

;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('af');

    test('parse', function (assert) {
        var tests = 'Januarie Jan_Februarie Feb_Maart Mrt_April Apr_Mei Mei_Junie Jun_Julie Jul_Augustus Aug_September Sep_Oktober Okt_November Nov_Desember Des'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Sondag, Februarie 14de 2010, 3:25:50 nm',
                ],
                ['ddd, hA', 'Son, 3NM'],
                ['M Mo MM MMMM MMM', '2 2de 02 Februarie Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14de 14'],
                ['d do dddd ddd dd', '0 0de Sondag Son So'],
                ['DDD DDDo DDDD', '45 45ste 045'],
                ['w wo ww', '6 6de 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'nm NM'],
                ['[the] DDDo [day of the year]', 'the 45ste day of the year'],
                ['LT', '15:25'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 Februarie 2010'],
                ['LLL', '14 Februarie 2010 15:25'],
                ['LLLL', 'Sondag, 14 Februarie 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 15:25'],
                ['llll', 'Son, 14 Feb 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');
    });

    test('format month', function (assert) {
        var expected = 'Januarie Jan_Februarie Feb_Maart Mrt_April Apr_Mei Mei_Junie Jun_Julie Jul_Augustus Aug_September Sep_Oktober Okt_November Nov_Desember Des'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Sondag Son So_Maandag Maa Ma_Dinsdag Din Di_Woensdag Woe Wo_Donderdag Don Do_Vrydag Vry Vr_Saterdag Sat Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            "'n paar sekondes",
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            "'n minuut",
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            "'n minuut",
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minute',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minute',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            "'n uur",
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            "'n uur",
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ure',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ure',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ure',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            "'n dag",
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            "'n dag",
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dae',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            "'n dag",
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dae',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dae',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            "'n maand",
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            "'n maand",
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            "'n maand",
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 maande',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 maande',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 maande',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            "'n maand",
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 maande',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            "'n jaar",
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 jaar',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            "'n jaar",
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 jaar',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), "oor 'n paar sekondes", 'prefix');
        assert.equal(moment(0).from(30000), "'n paar sekondes gelede", 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            "'n paar sekondes gelede",
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            "oor 'n paar sekondes",
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'oor 5 dae', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Vandag om 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Vandag om 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Vandag om 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Môre om 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Vandag om 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Gister om 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [om] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [om] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [om] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Laas] dddd [om] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Laas] dddd [om] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Laas] dddd [om] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52ste',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1ste',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1ste',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2de',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2de',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ar-dz');

    test('parse', function (assert) {
        var tests = 'جانفي:جانفي_فيفري:فيفري_مارس:مارس_أفريل:أفريل_ماي:ماي_جوان:جوان_جويلية:جويلية_أوت:أوت_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input +
                    ' should be month ' +
                    (i + 1) +
                    ' instead is month ' +
                    moment(input, mmm).month()
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(':');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'الأحد، فيفري 14 2010، 3:25:50 م',
                ],
                ['ddd, hA', 'أحد، 3م'],
                ['M Mo MM MMMM MMM', '2 2 02 فيفري فيفري'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 الأحد أحد ح'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '7 7 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'م م'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LT', '15:25'],
                ['LTS', '15:25:50'],
                ['L', '14/\u200f2/\u200f2010'],
                ['LL', '14 فيفري 2010'],
                ['LLL', '14 فيفري 2010 15:25'],
                ['LLLL', 'الأحد 14 فيفري 2010 15:25'],
                ['l', '14/\u200f2/\u200f2010'],
                ['ll', '14 فيفري 2010'],
                ['lll', '14 فيفري 2010 15:25'],
                ['llll', 'أحد 14 فيفري 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'جانفي جانفي_فيفري فيفري_مارس مارس_أفريل أفريل_ماي ماي_جوان جوان_جويلية جويلية_أوت أوت_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            '44 ثانية',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'دقيقة واحدة',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'دقيقة واحدة',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            'دقيقتان',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 دقيقة',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ساعة واحدة',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ساعة واحدة',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            'ساعتان',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ساعات',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ساعة',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'يوم واحد',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'يوم واحد',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            'يومان',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'يوم واحد',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 أيام',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 يومًا',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'شهر واحد',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'شهر واحد',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'شهر واحد',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            'شهران',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            'شهران',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 أشهر',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'شهر واحد',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 أشهر',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'عام واحد',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            'عامان',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'عام واحد',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 أعوام',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'بعد 30 ثانية', 'prefix');
        assert.equal(moment(0).from(30000), 'منذ 30 ثانية', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'منذ ثانية واحدة',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'بعد 30 ثانية',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'بعد 5 أيام', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'اليوم عند الساعة 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'اليوم عند الساعة 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'اليوم عند الساعة 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'غدًا عند الساعة 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'اليوم عند الساعة 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'أمس عند الساعة 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 1, 4]).format('w ww wo'),
            '5 05 5',
            'Feb 4 2011 should be week 5'
        );
        assert.equal(
            moment([2012, 0, 6]).format('w ww wo'),
            '1 01 1',
            'Jan  6 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 13]).format('w ww wo'),
            '2 02 2',
            'Jan 13 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2',
            'Jan 14 2012 should be week 2'
        );
    });

    test('no leading zeros in long date formats', function (assert) {
        var i, j, longDateStr, shortDateStr;
        for (i = 1; i <= 9; ++i) {
            for (j = 1; j <= 9; ++j) {
                longDateStr = moment([2014, i, j]).format('L');
                shortDateStr = moment([2014, i, j]).format('l');
                assert.equal(
                    longDateStr,
                    shortDateStr,
                    'should not have leading zeros in month or day'
                );
            }
        }
    });

    // locale-specific
    test('ar-dz strict mode parsing works', function (assert) {
        var m, formattedDate;
        m = moment().locale('ar-dz');
        formattedDate = m.format('l');
        assert.equal(
            moment.utc(formattedDate, 'l', 'ar-dz', false).isValid(),
            true,
            'Non-strict parsing works'
        );
        assert.equal(
            moment.utc(formattedDate, 'l', 'ar-dz', true).isValid(),
            true,
            'Strict parsing must work'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ar-kw');

    test('parse', function (assert) {
        var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_ماي:ماي_يونيو:يونيو_يوليوز:يوليوز_غشت:غشت_شتنبر:شتنبر_أكتوبر:أكتوبر_نونبر:نونبر_دجنبر:دجنبر'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(':');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'الأحد, فبراير 14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'احد, 3PM'],
                ['M Mo MM MMMM MMM', '2 2 02 فبراير فبراير'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 الأحد احد ح'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '9 9 09'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LT', '15:25'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 فبراير 2010'],
                ['LLL', '14 فبراير 2010 15:25'],
                ['LLLL', 'الأحد 14 فبراير 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 فبراير 2010'],
                ['lll', '14 فبراير 2010 15:25'],
                ['llll', 'احد 14 فبراير 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_ماي ماي_يونيو يونيو_يوليوز يوليوز_غشت غشت_شتنبر شتنبر_أكتوبر أكتوبر_نونبر نونبر_دجنبر دجنبر'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'الأحد احد ح_الإتنين اتنين ن_الثلاثاء ثلاثاء ث_الأربعاء اربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ثوان',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'دقيقة',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'دقيقة',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 دقائق',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 دقائق',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ساعة',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ساعة',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ساعات',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ساعات',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ساعات',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'يوم',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'يوم',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 أيام',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'يوم',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 أيام',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 أيام',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'شهر',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'شهر',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'شهر',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 أشهر',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 أشهر',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 أشهر',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'شهر',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 أشهر',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'سنة',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 سنوات',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'سنة',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 سنوات',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'في ثوان', 'prefix');
        assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'منذ ثوان',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'في ثوان',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'في 5 أيام', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'اليوم على الساعة 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'اليوم على الساعة 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'اليوم على الساعة 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'غدا على الساعة 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'اليوم على الساعة 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'أمس على الساعة 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 31]).format('w ww wo'),
            '1 01 1',
            'Dec 31 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '2 02 2',
            'Jan  1 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '3 03 3',
            'Jan  8 2012 should be week 3'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '3 03 3',
            'Jan 14 2012 should be week 3'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '4 04 4',
            'Jan 15 2012 should be week 4'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ar-ly');

    var months = [
        'يناير',
        'فبراير',
        'مارس',
        'أبريل',
        'مايو',
        'يونيو',
        'يوليو',
        'أغسطس',
        'سبتمبر',
        'أكتوبر',
        'نوفمبر',
        'ديسمبر',
    ];

    test('parse', function (assert) {
        var tests = months,
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input +
                    ' should be month ' +
                    (i + 1) +
                    ' instead is month ' +
                    moment(input, mmm).month()
            );
        }

        // function equalTestStrict(input, mmm, monthIndex) {
        //     assert.equal(
        //         moment(input, mmm, true).month(),
        //         monthIndex,
        //         input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
        //     );
        // }

        for (i = 0; i < 12; i++) {
            equalTest(tests[i], 'MMM', i);
            equalTest(tests[i], 'MMM', i);
            equalTest(tests[i], 'MMMM', i);
            equalTest(tests[i], 'MMMM', i);
            equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);

            // All strict parsing tests fail
            // equalTestStrict(tests[i][1], 'MMM', i);
            // equalTestStrict(tests[i][0], 'MMMM', i);
            // equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            // equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            // equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            // equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'الأحد، فبراير 14 2010، 3:25:50 م',
                ],
                ['ddd, hA', 'أحد، 3م'],
                ['M Mo MM MMMM MMM', '2 2 02 فبراير فبراير'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 الأحد أحد ح'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '8 8 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'م م'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LT', '15:25'],
                ['LTS', '15:25:50'],
                ['L', '14/\u200f2/\u200f2010'],
                ['LL', '14 فبراير 2010'],
                ['LLL', '14 فبراير 2010 15:25'],
                ['LLLL', 'الأحد 14 فبراير 2010 15:25'],
                ['l', '14/\u200f2/\u200f2010'],
                ['ll', '14 فبراير 2010'],
                ['lll', '14 فبراير 2010 15:25'],
                ['llll', 'أحد 14 فبراير 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = months,
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM'),
                expected[i],
                expected[i]
            );
            assert.equal(
                moment([2011, i, 1]).format('MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            '44 ثانية',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'دقيقة واحدة',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'دقيقة واحدة',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            'دقيقتان',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 دقيقة',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ساعة واحدة',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ساعة واحدة',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            'ساعتان',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ساعات',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ساعة',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'يوم واحد',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'يوم واحد',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            'يومان',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'يوم واحد',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 أيام',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 يومًا',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'شهر واحد',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'شهر واحد',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'شهر واحد',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            'شهران',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            'شهران',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 أشهر',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'شهر واحد',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 أشهر',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'عام واحد',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            'عامان',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'عام واحد',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 أعوام',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'بعد 30 ثانية', 'prefix');
        assert.equal(moment(0).from(30000), 'منذ 30 ثانية', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'منذ ثانية واحدة',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'بعد 30 ثانية',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'بعد 5 أيام', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'اليوم عند الساعة 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'اليوم عند الساعة 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'اليوم عند الساعة 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'غدًا عند الساعة 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'اليوم عند الساعة 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'أمس عند الساعة 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting wednesday custom', function (assert) {
        assert.equal(
            moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'),
            '2002-12-28',
            'Week 1 of 2003 should be Dec 28 2002'
        );
        assert.equal(
            moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'),
            '2002-12-28',
            'Week 1 of 2003 should be Dec 28 2002'
        );
        assert.equal(
            moment('2003 1 6', 'gggg w d').format('gggg w d'),
            '2003 1 6',
            'Saturday of week 1 of 2003 parsed should be formatted as 2003 1 6'
        );
        assert.equal(
            moment('2003 1 0', 'gggg w e').format('gggg w e'),
            '2003 1 0',
            '1st day of week 1 of 2003 parsed should be formatted as 2003 1 0'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 31]).format('w ww wo'),
            '1 01 1',
            'Dec 31 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 6]).format('w ww wo'),
            '1 01 1',
            'Jan  6 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '2 02 2',
            'Jan  7 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 13]).format('w ww wo'),
            '2 02 2',
            'Jan 13 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '3 03 3',
            'Jan 14 2012 should be week 3'
        );
    });

    test('no leading zeros in long date formats', function (assert) {
        var i, j, longDateStr, shortDateStr;
        for (i = 1; i <= 9; ++i) {
            for (j = 1; j <= 9; ++j) {
                longDateStr = moment([2014, i, j]).format('L');
                shortDateStr = moment([2014, i, j]).format('l');
                assert.equal(
                    longDateStr,
                    shortDateStr,
                    'should not have leading zeros in month or day'
                );
            }
        }
    });

    // locale-specific
    test('ar-ly strict mode parsing works', function (assert) {
        var m, formattedDate;
        m = moment().locale('ar-ly');
        formattedDate = m.format('l');
        assert.equal(
            moment.utc(formattedDate, 'l', 'ar-ly', false).isValid(),
            true,
            'Non-strict parsing works'
        );
        assert.equal(
            moment.utc(formattedDate, 'l', 'ar-ly', true).isValid(),
            true,
            'Strict parsing must work'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ar-ma');

    test('parse', function (assert) {
        var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_ماي:ماي_يونيو:يونيو_يوليوز:يوليوز_غشت:غشت_شتنبر:شتنبر_أكتوبر:أكتوبر_نونبر:نونبر_دجنبر:دجنبر'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(':');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'الأحد, فبراير 14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'احد, 3PM'],
                ['M Mo MM MMMM MMM', '2 2 02 فبراير فبراير'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 الأحد احد ح'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '6 6 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LT', '15:25'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 فبراير 2010'],
                ['LLL', '14 فبراير 2010 15:25'],
                ['LLLL', 'الأحد 14 فبراير 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 فبراير 2010'],
                ['lll', '14 فبراير 2010 15:25'],
                ['llll', 'احد 14 فبراير 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_ماي ماي_يونيو يونيو_يوليوز يوليوز_غشت غشت_شتنبر شتنبر_أكتوبر أكتوبر_نونبر نونبر_دجنبر دجنبر'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'الأحد احد ح_الإثنين اثنين ن_الثلاثاء ثلاثاء ث_الأربعاء اربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ثوان',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'دقيقة',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'دقيقة',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 دقائق',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 دقائق',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ساعة',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ساعة',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ساعات',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ساعات',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ساعات',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'يوم',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'يوم',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 أيام',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'يوم',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 أيام',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 أيام',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'شهر',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'شهر',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'شهر',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 أشهر',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 أشهر',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 أشهر',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'شهر',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 أشهر',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'سنة',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 سنوات',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'سنة',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 سنوات',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'في ثوان', 'prefix');
        assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'منذ ثوان',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'في ثوان',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'في 5 أيام', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'اليوم على الساعة 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'اليوم على الساعة 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'اليوم على الساعة 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'غدا على الساعة 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'اليوم على الساعة 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'أمس على الساعة 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting monday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 31]).format('w ww wo'),
            '52 52 52',
            'Dec 31 2011 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 6]).format('w ww wo'),
            '1 01 1',
            'Jan  6 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 13]).format('w ww wo'),
            '2 02 2',
            'Jan 13 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2',
            'Jan 14 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ar-sa');

    test('parse', function (assert) {
        var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_مايو:مايو_يونيو:يونيو_يوليو:يوليو_أغسطس:أغسطس_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input +
                    ' should be month ' +
                    (i + 1) +
                    ' instead is month ' +
                    moment(input, mmm).month()
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(':');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'الأحد، فبراير ١٤ ٢٠١٠، ٣:٢٥:٥٠ م',
                ],
                ['ddd, hA', 'أحد، ٣م'],
                ['M Mo MM MMMM MMM', '٢ ٢ ٠٢ فبراير فبراير'],
                ['YYYY YY', '٢٠١٠ ١٠'],
                ['D Do DD', '١٤ ١٤ ١٤'],
                ['d do dddd ddd dd', '٠ ٠ الأحد أحد ح'],
                ['DDD DDDo DDDD', '٤٥ ٤٥ ٠٤٥'],
                ['w wo ww', '٨ ٨ ٠٨'],
                ['h hh', '٣ ٠٣'],
                ['H HH', '١٥ ١٥'],
                ['m mm', '٢٥ ٢٥'],
                ['s ss', '٥٠ ٥٠'],
                ['a A', 'م م'],
                ['[the] DDDo [day of the year]', 'the ٤٥ day of the year'],
                ['LT', '١٥:٢٥'],
                ['LTS', '١٥:٢٥:٥٠'],
                ['L', '١٤/٠٢/٢٠١٠'],
                ['LL', '١٤ فبراير ٢٠١٠'],
                ['LLL', '١٤ فبراير ٢٠١٠ ١٥:٢٥'],
                ['LLLL', 'الأحد ١٤ فبراير ٢٠١٠ ١٥:٢٥'],
                ['l', '١٤/٢/٢٠١٠'],
                ['ll', '١٤ فبراير ٢٠١٠'],
                ['lll', '١٤ فبراير ٢٠١٠ ١٥:٢٥'],
                ['llll', 'أحد ١٤ فبراير ٢٠١٠ ١٥:٢٥'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');
    });

    test('format month', function (assert) {
        var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_مايو مايو_يونيو يونيو_يوليو يوليو_أغسطس أغسطس_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ثوان',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'دقيقة',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'دقيقة',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '٢ دقائق',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '٤٤ دقائق',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ساعة',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ساعة',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '٢ ساعات',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '٥ ساعات',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '٢١ ساعات',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'يوم',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'يوم',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '٢ أيام',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'يوم',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '٥ أيام',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '٢٥ أيام',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'شهر',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'شهر',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'شهر',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '٢ أشهر',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '٢ أشهر',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '٣ أشهر',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'شهر',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '٥ أشهر',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'سنة',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '٢ سنوات',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'سنة',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '٥ سنوات',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'في ثوان', 'prefix');
        assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'منذ ثوان',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'في ثوان',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'في ٥ أيام', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'اليوم على الساعة ١٢:٠٠',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'اليوم على الساعة ١٢:٢٥',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'اليوم على الساعة ١٣:٠٠',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'غدا على الساعة ١٢:٠٠',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'اليوم على الساعة ١١:٠٠',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'أمس على الساعة ١٢:٠٠',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting wednesday custom', function (assert) {
        assert.equal(
            moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'),
            '٢٠٠٣-٠١-٠٤',
            '2003 1 6 : gggg w d'
        );
        assert.equal(
            moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'),
            '٢٠٠٢-١٢-٢٩',
            '2003 1 0 : gggg w e'
        );
        assert.equal(
            moment('2003 1 6', 'gggg w d').format('gggg w d'),
            '٢٠٠٣ ١ ٦',
            '2003 1 6 : gggg w d'
        );
        assert.equal(
            moment('2003 1 0', 'gggg w e').format('gggg w e'),
            '٢٠٠٣ ١ ٠',
            '2003 1 0 : gggg w e'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 31]).format('w ww wo'),
            '٥٣ ٥٣ ٥٣',
            '2011 11 31'
        );
        assert.equal(moment([2012, 0, 6]).format('w ww wo'), '١ ٠١ ١', '2012 0 6');
        assert.equal(moment([2012, 0, 7]).format('w ww wo'), '١ ٠١ ١', '2012 0 7');
        assert.equal(
            moment([2012, 0, 13]).format('w ww wo'),
            '٢ ٠٢ ٢',
            '2012 0 13'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '٢ ٠٢ ٢',
            '2012 0 14'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ar-tn');

    test('parse', function (assert) {
        var tests = 'جانفي:جانفي_فيفري:فيفري_مارس:مارس_أفريل:أفريل_ماي:ماي_جوان:جوان_جويلية:جويلية_أوت:أوت_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(':');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'الأحد, فيفري 14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'أحد, 3PM'],
                ['M Mo MM MMMM MMM', '2 2 02 فيفري فيفري'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 الأحد أحد ح'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '6 6 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LT', '15:25'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 فيفري 2010'],
                ['LLL', '14 فيفري 2010 15:25'],
                ['LLLL', 'الأحد 14 فيفري 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 فيفري 2010'],
                ['lll', '14 فيفري 2010 15:25'],
                ['llll', 'أحد 14 فيفري 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'جانفي جانفي_فيفري فيفري_مارس مارس_أفريل أفريل_ماي ماي_جوان جوان_جويلية جويلية_أوت أوت_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    s: 44,
                }),
                true
            ),
            'ثوان',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    s: 45,
                }),
                true
            ),
            'دقيقة',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    s: 89,
                }),
                true
            ),
            'دقيقة',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    s: 90,
                }),
                true
            ),
            '2 دقائق',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    m: 44,
                }),
                true
            ),
            '44 دقائق',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    m: 45,
                }),
                true
            ),
            'ساعة',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    m: 89,
                }),
                true
            ),
            'ساعة',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    m: 90,
                }),
                true
            ),
            '2 ساعات',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    h: 5,
                }),
                true
            ),
            '5 ساعات',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    h: 21,
                }),
                true
            ),
            '21 ساعات',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    h: 22,
                }),
                true
            ),
            'يوم',
            '22 hours = a day'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    h: 35,
                }),
                true
            ),
            'يوم',
            '35 hours = a day'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    h: 36,
                }),
                true
            ),
            '2 أيام',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 1,
                }),
                true
            ),
            'يوم',
            '1 day = a day'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 5,
                }),
                true
            ),
            '5 أيام',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 25,
                }),
                true
            ),
            '25 أيام',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 26,
                }),
                true
            ),
            'شهر',
            '26 days = a month'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 30,
                }),
                true
            ),
            'شهر',
            '30 days = a month'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 43,
                }),
                true
            ),
            'شهر',
            '43 days = a month'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 46,
                }),
                true
            ),
            '2 أشهر',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 74,
                }),
                true
            ),
            '2 أشهر',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 76,
                }),
                true
            ),
            '3 أشهر',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    M: 1,
                }),
                true
            ),
            'شهر',
            '1 month = a month'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    M: 5,
                }),
                true
            ),
            '5 أشهر',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 345,
                }),
                true
            ),
            'سنة',
            '345 days = a year'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 548,
                }),
                true
            ),
            '2 سنوات',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    y: 1,
                }),
                true
            ),
            'سنة',
            '1 year = a year'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    y: 5,
                }),
                true
            ),
            '5 سنوات',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'في ثوان', 'prefix');
        assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'منذ ثوان',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment()
                .add({
                    s: 30,
                })
                .fromNow(),
            'في ثوان',
            'in a few seconds'
        );
        assert.equal(
            moment()
                .add({
                    d: 5,
                })
                .fromNow(),
            'في 5 أيام',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'اليوم على الساعة 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'اليوم على الساعة 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'اليوم على الساعة 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'غدا على الساعة 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'اليوم على الساعة 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'أمس على الساعة 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({
                d: i,
            });
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({
                d: i,
            });
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [على الساعة] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({
                w: 1,
            }),
            weeksFromNow = moment().add({
                w: 1,
            });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({
            w: 2,
        });
        weeksFromNow = moment().add({
            w: 2,
        });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ar');

    var months = [
        'يناير',
        'فبراير',
        'مارس',
        'أبريل',
        'مايو',
        'يونيو',
        'يوليو',
        'أغسطس',
        'سبتمبر',
        'أكتوبر',
        'نوفمبر',
        'ديسمبر',
    ];

    test('parse', function (assert) {
        var tests = months,
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input +
                    ' should be month ' +
                    (i + 1) +
                    ' instead is month ' +
                    moment(input, mmm).month()
            );
        }

        // function equalTestStrict(input, mmm, monthIndex) {
        //     assert.equal(
        //         moment(input, mmm, true).month(),
        //         monthIndex,
        //         input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
        //     );
        // }

        for (i = 0; i < 12; i++) {
            equalTest(tests[i], 'MMM', i);
            equalTest(tests[i], 'MMM', i);
            equalTest(tests[i], 'MMMM', i);
            equalTest(tests[i], 'MMMM', i);
            equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);

            // All strict parsing tests fail
            // equalTestStrict(tests[i][1], 'MMM', i);
            // equalTestStrict(tests[i][0], 'MMMM', i);
            // equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            // equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            // equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            // equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'الأحد، فبراير ١٤ ٢٠١٠، ٣:٢٥:٥٠ م',
                ],
                ['ddd, hA', 'أحد، ٣م'],
                ['M Mo MM MMMM MMM', '٢ ٢ ٠٢ فبراير فبراير'],
                ['YYYY YY', '٢٠١٠ ١٠'],
                ['D Do DD', '١٤ ١٤ ١٤'],
                ['d do dddd ddd dd', '٠ ٠ الأحد أحد ح'],
                ['DDD DDDo DDDD', '٤٥ ٤٥ ٠٤٥'],
                ['w wo ww', '٨ ٨ ٠٨'],
                ['h hh', '٣ ٠٣'],
                ['H HH', '١٥ ١٥'],
                ['m mm', '٢٥ ٢٥'],
                ['s ss', '٥٠ ٥٠'],
                ['a A', 'م م'],
                ['[the] DDDo [day of the year]', 'the ٤٥ day of the year'],
                ['LT', '١٥:٢٥'],
                ['LTS', '١٥:٢٥:٥٠'],
                ['L', '١٤/\u200f٢/\u200f٢٠١٠'],
                ['LL', '١٤ فبراير ٢٠١٠'],
                ['LLL', '١٤ فبراير ٢٠١٠ ١٥:٢٥'],
                ['LLLL', 'الأحد ١٤ فبراير ٢٠١٠ ١٥:٢٥'],
                ['l', '١٤/\u200f٢/\u200f٢٠١٠'],
                ['ll', '١٤ فبراير ٢٠١٠'],
                ['lll', '١٤ فبراير ٢٠١٠ ١٥:٢٥'],
                ['llll', 'أحد ١٤ فبراير ٢٠١٠ ١٥:٢٥'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');
    });

    test('format month', function (assert) {
        var expected = months,
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM'),
                expected[i],
                expected[i]
            );
            assert.equal(
                moment([2011, i, 1]).format('MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            '٤٤ ثانية',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'دقيقة واحدة',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'دقيقة واحدة',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            'دقيقتان',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '٤٤ دقيقة',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ساعة واحدة',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ساعة واحدة',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            'ساعتان',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '٥ ساعات',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '٢١ ساعة',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'يوم واحد',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'يوم واحد',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            'يومان',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'يوم واحد',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '٥ أيام',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '٢٥ يومًا',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'شهر واحد',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'شهر واحد',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'شهر واحد',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            'شهران',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            'شهران',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '٣ أشهر',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'شهر واحد',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '٥ أشهر',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'عام واحد',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            'عامان',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'عام واحد',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '٥ أعوام',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'بعد ٣٠ ثانية', 'prefix');
        assert.equal(moment(0).from(30000), 'منذ ٣٠ ثانية', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'منذ ثانية واحدة',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'بعد ٣٠ ثانية',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'بعد ٥ أيام', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'اليوم عند الساعة ١٢:٠٠',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'اليوم عند الساعة ١٢:٢٥',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'اليوم عند الساعة ١٣:٠٠',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'غدًا عند الساعة ١٢:٠٠',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'اليوم عند الساعة ١١:٠٠',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'أمس عند الساعة ١٢:٠٠',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [عند الساعة] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting wednesday custom', function (assert) {
        assert.equal(
            moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'),
            '٢٠٠٢-١٢-٢٨',
            'Week 1 of 2003 should be Dec 28 2002'
        );
        assert.equal(
            moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'),
            '٢٠٠٢-١٢-٢٨',
            'Week 1 of 2003 should be Dec 28 2002'
        );
        assert.equal(
            moment('2003 1 6', 'gggg w d').format('gggg w d'),
            '٢٠٠٣ ١ ٦',
            'Saturday of week 1 of 2003 parsed should be formatted as 2003 1 6'
        );
        assert.equal(
            moment('2003 1 0', 'gggg w e').format('gggg w e'),
            '٢٠٠٣ ١ ٠',
            '1st day of week 1 of 2003 parsed should be formatted as 2003 1 0'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 31]).format('w ww wo'),
            '١ ٠١ ١',
            'Dec 31 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 6]).format('w ww wo'),
            '١ ٠١ ١',
            'Jan  6 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '٢ ٠٢ ٢',
            'Jan  7 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 13]).format('w ww wo'),
            '٢ ٠٢ ٢',
            'Jan 13 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '٣ ٠٣ ٣',
            'Jan 14 2012 should be week 3'
        );
    });

    test('no leading zeros in long date formats', function (assert) {
        var i, j, longDateStr, shortDateStr;
        for (i = 1; i <= 9; ++i) {
            for (j = 1; j <= 9; ++j) {
                longDateStr = moment([2014, i, j]).format('L');
                shortDateStr = moment([2014, i, j]).format('l');
                assert.equal(
                    longDateStr,
                    shortDateStr,
                    'should not have leading zeros in month or day'
                );
            }
        }
    });

    // locale-specific
    test('ar strict mode parsing works', function (assert) {
        var m, formattedDate;
        m = moment().locale('ar');
        formattedDate = m.format('l');
        assert.equal(
            moment.utc(formattedDate, 'l', 'ar', false).isValid(),
            true,
            'Non-strict parsing works'
        );
        assert.equal(
            moment.utc(formattedDate, 'l', 'ar', true).isValid(),
            true,
            'Strict parsing must work'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('az');

    test('parse', function (assert) {
        var tests = 'yanvar yan_fevral fev_mart mar_Aprel apr_may may_iyun iyn_iyul iyl_Avqust avq_sentyabr sen_oktyabr okt_noyabr noy_dekabr dek'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                ['dddd, D MMMM YYYY, HH:mm:ss', 'Bazar, 14 fevral 2010, 15:25:50'],
                ['ddd, A h', 'Baz, gündüz 3'],
                ['M Mo MM MMMM MMM', '2 2-nci 02 fevral fev'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14-üncü 14'],
                ['d do dddd ddd dd', '0 0-ıncı Bazar Baz Bz'],
                ['DDD DDDo DDDD', '45 45-inci 045'],
                ['w wo ww', '7 7-nci 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'gündüz gündüz'],
                ['[ilin] DDDo [günü]', 'ilin 45-inci günü'],
                ['LT', '15:25'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 fevral 2010'],
                ['LLL', '14 fevral 2010 15:25'],
                ['LLLL', 'Bazar, 14 fevral 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 fev 2010'],
                ['lll', '14 fev 2010 15:25'],
                ['llll', 'Baz, 14 fev 2010 15:25'],
            ],
            DDDo = [
                [359, '360-ıncı'],
                [199, '200-üncü'],
                [149, '150-nci'],
            ],
            dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            DDDoDt,
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
        for (i = 0; i < DDDo.length; i++) {
            DDDoDt = moment([2010]);
            assert.equal(
                DDDoDt.add(DDDo[i][0], 'days').format('DDDo'),
                DDDo[i][1],
                DDDo[i][0] + ' ---> ' + DDDo[i][1]
            );
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-inci', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-nci', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-üncü', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-üncü', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-inci', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ncı', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-nci', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-inci', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-uncu', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-uncu', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-inci', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-nci', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-üncü', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-üncü', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-inci', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ncı', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-nci', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-inci', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-uncu', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-nci', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-inci', '21th');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-nci', '22th');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-üncü', '23th');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-üncü', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-inci', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ncı', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-nci', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-inci', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-uncu', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-uncu', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-inci', '31st');
    });

    test('format month', function (assert) {
        var expected = 'yanvar yan_fevral fev_mart mar_aprel apr_may may_iyun iyn_iyul iyl_avqust avq_sentyabr sen_oktyabr okt_noyabr noy_dekabr dek'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Bazar Baz Bz_Bazar ertəsi BzE BE_Çərşənbə axşamı ÇAx ÇA_Çərşənbə Çər Çə_Cümə axşamı CAx CA_Cümə Cüm Cü_Şənbə Şən Şə'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'bir neçə saniyə',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'bir dəqiqə',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'bir dəqiqə',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 dəqiqə',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 dəqiqə',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'bir saat',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'bir saat',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 saat',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 saat',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 saat',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'bir gün',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'bir gün',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 gün',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'bir gün',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 gün',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 gün',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'bir ay',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'bir ay',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 ay',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 ay',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 ay',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'bir ay',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 ay',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'bir il',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 il',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'bir il',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 il',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'bir neçə saniyə sonra', 'prefix');
        assert.equal(moment(0).from(30000), 'bir neçə saniyə əvvəl', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'bir neçə saniyə əvvəl',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'bir neçə saniyə sonra',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 gün sonra', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'bugün saat 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'bugün saat 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'bugün saat 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'sabah saat 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'bugün saat 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'dünən 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[gələn həftə] dddd [saat] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[gələn həftə] dddd [saat] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[gələn həftə] dddd [saat] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[keçən həftə] dddd [saat] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[keçən həftə] dddd [saat] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[keçən həftə] dddd [saat] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1-inci',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1-inci',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2-nci',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2-nci',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3-üncü',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('be');

    test('parse', function (assert) {
        var tests = 'студзень студ_люты лют_сакавік сак_красавік крас_травень трав_чэрвень чэрв_ліпень ліп_жнівень жнів_верасень вер_кастрычнік каст_лістапад ліст_снежань снеж'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, HH:mm:ss',
                    'нядзеля, 14-га лютага 2010, 15:25:50',
                ],
                ['ddd, h A', 'нд, 3 дня'],
                ['M Mo MM MMMM MMM', '2 2-і 02 люты лют'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14-га 14'],
                ['d do dddd ddd dd', '0 0-ы нядзеля нд нд'],
                ['DDD DDDo DDDD', '45 45-ы 045'],
                ['w wo ww', '7 7-ы 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'дня дня'],
                ['DDDo [дзень года]', '45-ы дзень года'],
                ['LT', '15:25'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 лютага 2010 г.'],
                ['LLL', '14 лютага 2010 г., 15:25'],
                ['LLLL', 'нядзеля, 14 лютага 2010 г., 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 лют 2010 г.'],
                ['lll', '14 лют 2010 г., 15:25'],
                ['llll', 'нд, 14 лют 2010 г., 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format meridiem', function (assert) {
        assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночы', 'night');
        assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночы', 'night');
        assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'раніцы', 'morning');
        assert.equal(
            moment([2012, 11, 28, 11, 59]).format('A'),
            'раніцы',
            'morning'
        );
        assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');
        assert.equal(
            moment([2012, 11, 28, 16, 59]).format('A'),
            'дня',
            'afternoon'
        );
        assert.equal(
            moment([2012, 11, 28, 17, 0]).format('A'),
            'вечара',
            'evening'
        );
        assert.equal(
            moment([2012, 11, 28, 23, 59]).format('A'),
            'вечара',
            'evening'
        );
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ы', '1-ы');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-і', '2-і');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-і', '3-і');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ы', '4-ы');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ы', '5-ы');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ы', '6-ы');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ы', '7-ы');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ы', '8-ы');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ы', '9-ы');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ы', '10-ы');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ы', '11-ы');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ы', '12-ы');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ы', '13-ы');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ы', '14-ы');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ы', '15-ы');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ы', '16-ы');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ы', '17-ы');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ы', '18-ы');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ы', '19-ы');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ы', '20-ы');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ы', '21-ы');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-і', '22-і');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-і', '23-і');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ы', '24-ы');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ы', '25-ы');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ы', '26-ы');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ы', '27-ы');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ы', '28-ы');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ы', '29-ы');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ы', '30-ы');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ы', '31-ы');
    });

    test('format month', function (assert) {
        var expected = 'студзень студ_люты лют_сакавік сак_красавік крас_травень трав_чэрвень чэрв_ліпень ліп_жнівень жнів_верасень вер_кастрычнік каст_лістапад ліст_снежань снеж'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format month case', function (assert) {
        var months = {
                nominative: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split(
                    '_'
                ),
                accusative: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split(
                    '_'
                ),
            },
            i;
        for (i = 0; i < 12; i++) {
            assert.equal(
                moment([2011, i, 1]).format('D MMMM'),
                '1 ' + months.accusative[i],
                '1 ' + months.accusative[i]
            );
            assert.equal(
                moment([2011, i, 1]).format('MMMM'),
                months.nominative[i],
                '1 ' + months.nominative[i]
            );
        }
    });

    test('format month case with escaped symbols', function (assert) {
        var months = {
                nominative: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split(
                    '_'
                ),
                accusative: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split(
                    '_'
                ),
            },
            i;
        for (i = 0; i < 12; i++) {
            assert.equal(
                moment([2013, i, 1]).format('D[] MMMM'),
                '1 ' + months.accusative[i],
                '1 ' + months.accusative[i]
            );
            assert.equal(
                moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'),
                '<i>1</i> <b>' + months.accusative[i] + '</b>',
                '1 <b>' + months.accusative[i] + '</b>'
            );
            assert.equal(
                moment([2013, i, 1]).format('D[-ы дзень] MMMM'),
                '1-ы дзень ' + months.accusative[i],
                '1-ы дзень ' + months.accusative[i]
            );
            assert.equal(
                moment([2013, i, 1]).format('D, MMMM'),
                '1, ' + months.nominative[i],
                '1, ' + months.nominative[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'нядзеля нд нд_панядзелак пн пн_аўторак ат ат_серада ср ср_чацвер чц чц_пятніца пт пт_субота сб сб'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'некалькі секунд',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'хвіліна',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'хвіліна',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 хвіліны',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 31 }), true),
            '31 хвіліна',
            '31 minutes = 31 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 хвіліны',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'гадзіна',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'гадзіна',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 гадзіны',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 гадзін',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 гадзіна',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'дзень',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'дзень',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 дні',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'дзень',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 дзён',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 11 }), true),
            '11 дзён',
            '11 days = 11 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 21 }), true),
            '21 дзень',
            '21 days = 21 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 дзён',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'месяц',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'месяц',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'месяц',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 месяцы',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 месяцы',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 месяцы',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'месяц',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 месяцаў',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'год',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 гады',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'год',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 гадоў',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'праз некалькі секунд', 'prefix');
        assert.equal(moment(0).from(30000), 'некалькі секунд таму', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'праз некалькі секунд',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'праз 5 дзён', 'in 5 days');
        assert.equal(
            moment().add({ m: 31 }).fromNow(),
            'праз 31 хвіліну',
            'in 31 minutes = in 31 minutes'
        );
        assert.equal(
            moment().subtract({ m: 31 }).fromNow(),
            '31 хвіліну таму',
            '31 minutes ago = 31 minutes ago'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Сёння ў 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Сёння ў 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Сёння ў 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Заўтра ў 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Сёння ў 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Учора ў 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        function makeFormat(d) {
            return '[У] dddd [ў] LT';
        }

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat()),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat()),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat()),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                case 3:
                case 5:
                case 6:
                    return '[У мінулую] dddd [ў] LT';
                case 1:
                case 2:
                case 4:
                    return '[У мінулы] dddd [ў] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1-ы',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1-ы',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2-і',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2-і',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3-і',
            'Jan  9 2012 should be week 3'
        );
    });

    test('calendar should format', function (assert) {
        assert.equal(
            moment('2018-04-13').calendar(moment('2018-04-16')),
            'У мінулую пятніцу ў 00:00',
            'calendar should handle day of week'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('bg');

    test('parse', function (assert) {
        var tests = 'януари яну_февруари фев_март мар_април апр_май май_юни юни_юли юли_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }
        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, H:mm:ss',
                    'неделя, февруари 14-ти 2010, 15:25:50',
                ],
                ['ddd, hA', 'нед, 3PM'],
                ['M Mo MM MMMM MMM', '2 2-ри 02 февруари фев'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14-ти 14'],
                ['d do dddd ddd dd', '0 0-ев неделя нед нд'],
                ['DDD DDDo DDDD', '45 45-ти 045'],
                ['w wo ww', '7 7-ми 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45-ти day of the year'],
                ['LT', '15:25'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 февруари 2010'],
                ['LLL', '14 февруари 2010 15:25'],
                ['LLLL', 'неделя, 14 февруари 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 фев 2010'],
                ['lll', '14 фев 2010 15:25'],
                ['llll', 'нед, 14 фев 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ви', '1-ви');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ри', '2-ри');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ти', '3-ти');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ти', '4-ти');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ти', '5-ти');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ти', '6-ти');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ми', '7-ми');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ми', '8-ми');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ти', '9-ти');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ти', '10-ти');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ти', '11-ти');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ти', '12-ти');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ти', '13-ти');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ти', '14-ти');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ти', '15-ти');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ти', '16-ти');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ти', '17-ти');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ти', '18-ти');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ти', '19-ти');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ти', '20-ти');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ви', '21-ви');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ри', '22-ри');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ти', '23-ти');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ти', '24-ти');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ти', '25-ти');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ти', '26-ти');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ми', '27-ми');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ми', '28-ми');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ти', '29-ти');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ти', '30-ти');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ви', '31-ви');
    });

    test('format month', function (assert) {
        var expected = 'януари яну_февруари фев_март мар_април апр_май май_юни юни_юли юли_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'неделя нед нд_понеделник пон пн_вторник вто вт_сряда сря ср_четвъртък чет чт_петък пет пт_събота съб сб'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'няколко секунди',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'минута',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'минута',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 минути',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 минути',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'час',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'час',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 часа',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 часа',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 часа',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ден',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ден',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 дена',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ден',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 дена',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 дена',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'месец',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'месец',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'месец',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 месеца',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 месеца',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 месеца',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'месец',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 месеца',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'година',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 години',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'година',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 години',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'след няколко секунди', 'prefix');
        assert.equal(moment(0).from(30000), 'преди няколко секунди', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'преди няколко секунди',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'след няколко секунди',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'след 5 дена', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Днес в 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Днес в 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Днес в 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Утре в 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Днес в 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Вчера в 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [в] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [в] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [в] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                case 3:
                case 6:
                    return '[Миналата] dddd [в] LT';
                case 1:
                case 2:
                case 4:
                case 5:
                    return '[Миналия] dddd [в] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1-ви',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1-ви',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2-ри',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2-ри',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3-ти',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('bm');

    test('parse', function (assert) {
        var i,
            tests = 'Zanwuyekalo Zan_Fewuruyekalo Few_Marisikalo Mar_Awirilikalo Awi_Mɛkalo Mɛ_Zuwɛnkalo Zuw_Zuluyekalo Zul_Utikalo Uti_Sɛtanburukalo Sɛt_ɔkutɔburukalo ɔku_Nowanburukalo Now_Desanburukalo Des'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Kari, Fewuruyekalo 14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Kar, 3PM'],
                ['M Mo MM MMMM MMM', '2 2 02 Fewuruyekalo Few'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Kari Kar Ka'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '6 6 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[le] Do [jour du mois]', 'le 14 jour du mois'],
                ['[le] DDDo [jour de l’année]', 'le 45 jour de l’année'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', 'Fewuruyekalo tile 14 san 2010'],
                ['LLL', 'Fewuruyekalo tile 14 san 2010 lɛrɛ 15:25'],
                ['LLLL', 'Kari Fewuruyekalo tile 14 san 2010 lɛrɛ 15:25'],
                ['l', '14/2/2010'],
                ['ll', 'Few tile 14 san 2010'],
                ['lll', 'Few tile 14 san 2010 lɛrɛ 15:25'],
                ['llll', 'Kar Few tile 14 san 2010 lɛrɛ 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format month', function (assert) {
        var i,
            expected = 'Zanwuyekalo Zan_Fewuruyekalo Few_Marisikalo Mar_Awirilikalo Awi_Mɛkalo Mɛ_Zuwɛnkalo Zuw_Zuluyekalo Zul_Utikalo Uti_Sɛtanburukalo Sɛt_ɔkutɔburukalo ɔku_Nowanburukalo Now_Desanburukalo Des'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'Kari Kar Ka_Ntɛnɛn Ntɛ Nt_Tarata Tar Ta_Araba Ara Ar_Alamisa Ala Al_Juma Jum Ju_Sibiri Sib Si'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'sanga dama dama',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'miniti kelen',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'miniti kelen',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            'miniti 2',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            'miniti 44',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'lɛrɛ kelen',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'lɛrɛ kelen',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            'lɛrɛ 2',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            'lɛrɛ 5',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            'lɛrɛ 21',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'tile kelen',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'tile kelen',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            'tile 2',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'tile kelen',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            'tile 5',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            'tile 25',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'kalo kelen',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'kalo kelen',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'kalo kelen',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            'kalo 2',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            'kalo 2',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            'kalo 3',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'kalo kelen',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            'kalo 5',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'san kelen',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            'san 2',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'san kelen',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            'san 5',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'sanga dama dama kɔnɔ', 'prefix');
        assert.equal(moment(0).from(30000), 'a bɛ sanga dama dama bɔ', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'sanga dama dama kɔnɔ',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'tile 5 kɔnɔ', 'in 5 days');
    });

    test('same day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Bi lɛrɛ 12:00',
            'Today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Bi lɛrɛ 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Bi lɛrɛ 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Sini lɛrɛ 12:00',
            'Tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Bi lɛrɛ 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Kunu lɛrɛ 12:00',
            'Yesterday at the same time'
        );
    });

    test('same next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [don lɛrɛ] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [don lɛrɛ] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [don lɛrɛ] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('same last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [tɛmɛnen lɛrɛ] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [tɛmɛnen lɛrɛ] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [tɛmɛnen lɛrɛ] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('same all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('bn-bd');

    test('parse', function (assert) {
        var tests = 'জানুয়ারি জানু_ফেব্রুয়ারি ফেব্রু_মার্চ মার্চ_এপ্রিল এপ্রিল_মে মে_জুন জুন_জুলাই জুলাই_আগস্ট আগস্ট_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভে_ডিসেম্বর ডিসে'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, a h:mm:ss সময়',
                    'রবিবার, ১৪ ফেব্রুয়ারি ২০১০, বিকাল ৩:২৫:৫০ সময়',
                ],
                ['ddd, a h সময়', 'রবি, বিকাল ৩ সময়'],
                ['M Mo MM MMMM MMM', '২ ২ ০২ ফেব্রুয়ারি ফেব্রু'],
                ['YYYY YY', '২০১০ ১০'],
                ['D Do DD', '১৪ ১৪ ১৪'],
                ['d do dddd ddd dd', '০ ০ রবিবার রবি রবি'],
                ['DDD DDDo DDDD', '৪৫ ৪৫ ০৪৫'],
                ['w wo ww', '৮ ৮ ০৮'],
                ['h hh', '৩ ০৩'],
                ['H HH', '১৫ ১৫'],
                ['m mm', '২৫ ২৫'],
                ['s ss', '৫০ ৫০'],
                ['a A', 'বিকাল বিকাল'],
                ['LT', 'বিকাল ৩:২৫ সময়'],
                ['LTS', 'বিকাল ৩:২৫:৫০ সময়'],
                ['L', '১৪/০২/২০১০'],
                ['LL', '১৪ ফেব্রুয়ারি ২০১০'],
                ['LLL', '১৪ ফেব্রুয়ারি ২০১০, বিকাল ৩:২৫ সময়'],
                ['LLLL', 'রবিবার, ১৪ ফেব্রুয়ারি ২০১০, বিকাল ৩:২৫ সময়'],
                ['l', '১৪/২/২০১০'],
                ['ll', '১৪ ফেব্রু ২০১০'],
                ['lll', '১৪ ফেব্রু ২০১০, বিকাল ৩:২৫ সময়'],
                ['llll', 'রবি, ১৪ ফেব্রু ২০১০, বিকাল ৩:২৫ সময়'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '১', '১');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '২', '২');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '৩', '৩');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '৪', '৪');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '৫', '৫');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '৬', '৬');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '৭', '৭');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '৮', '৮');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '৯', '৯');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '১০', '১০');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '১১', '১১');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '১২', '১২');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '১৩', '১৩');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '১৪', '১৪');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '১৫', '১৫');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '১৬', '১৬');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '১৭', '১৭');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '১৮', '১৮');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '১৯', '১৯');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '২০', '২০');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '২১', '২১');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '২২', '২২');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '২৩', '২৩');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '২৪', '২৪');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '২৫', '২৫');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '২৬', '২৬');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '২৭', '২৭');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '২৮', '२৮');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '২৯', '২৯');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '৩০', '৩০');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '৩১', '৩১');
    });

    test('format month', function (assert) {
        var expected = 'জানুয়ারি জানু_ফেব্রুয়ারি ফেব্রু_মার্চ মার্চ_এপ্রিল এপ্রিল_মে মে_জুন জুন_জুলাই জুলাই_আগস্ট আগস্ট_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভে_ডিসেম্বর ডিসে'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'রবিবার রবি রবি_সোমবার সোম সোম_মঙ্গলবার মঙ্গল মঙ্গল_বুধবার বুধ বুধ_বৃহস্পতিবার বৃহস্পতি বৃহ_শুক্রবার শুক্র শুক্র_শনিবার শনি শনি'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'কয়েক সেকেন্ড',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'এক মিনিট',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'এক মিনিট',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '২ মিনিট',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '৪৪ মিনিট',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'এক ঘন্টা',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'এক ঘন্টা',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '২ ঘন্টা',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '৫ ঘন্টা',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '২১ ঘন্টা',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'এক দিন',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'এক দিন',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '২ দিন',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'এক দিন',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '৫ দিন',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '২৫ দিন',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'এক মাস',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'এক মাস',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '২ মাস',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '২ মাস',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '৩ মাস',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'এক মাস',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '৫ মাস',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'এক বছর',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '২ বছর',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'এক বছর',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '৫ বছর',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'কয়েক সেকেন্ড পরে', 'prefix');
        assert.equal(moment(0).from(30000), 'কয়েক সেকেন্ড আগে', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'কয়েক সেকেন্ড আগে',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'কয়েক সেকেন্ড পরে',
            'কয়েক সেকেন্ড পরে'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '৫ দিন পরে', '৫ দিন পরে');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'আজ দুপুর ১২:০০ সময়',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'আজ দুপুর ১২:২৫ সময়',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 3 }).calendar(),
            'আজ বিকাল ৩:০০ সময়',
            'Now plus 3 hours'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'আগামীকাল দুপুর ১২:০০ সময়',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'আজ সকাল ১১:০০ সময়',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'গতকাল দুপুর ১২:০০ সময়',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[গত] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[গত] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[গত] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(moment([2011, 2, 23, 2, 30]).format('a'), 'রাত', 'Night');
        assert.equal(moment([2011, 2, 23, 9, 30]).format('a'), 'সকাল', 'morning');
        assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'দুপুর', 'Noon');
        assert.equal(
            moment([2011, 2, 23, 17, 30]).format('a'),
            'বিকাল',
            'Afternoon'
        );
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('a'),
            'সন্ধ্যা',
            'evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'রাত', 'night');

        assert.equal(moment([2011, 2, 23, 2, 30]).format('A'), 'রাত', 'Night');
        assert.equal(moment([2011, 2, 23, 9, 30]).format('A'), 'সকাল', 'morning');
        assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'দুপুর', 'Noon');
        assert.equal(
            moment([2011, 2, 23, 17, 30]).format('A'),
            'বিকাল',
            'Afternoon'
        );
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('A'),
            'সন্ধ্যা',
            'evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'রাত', 'night');
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '১ ০১ ১',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '১ ০১ ১',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '২ ০২ ২',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '২ ০২ ২',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '৩ ০৩ ৩',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('bn');

    test('parse', function (assert) {
        var tests = 'জানুয়ারি জানু_ফেব্রুয়ারি ফেব্রু_মার্চ মার্চ_এপ্রিল এপ্রিল_মে মে_জুন জুন_জুলাই জুলাই_আগস্ট আগস্ট_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভে_ডিসেম্বর ডিসে'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, a h:mm:ss সময়',
                    'রবিবার, ১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫:৫০ সময়',
                ],
                ['ddd, a h সময়', 'রবি, দুপুর ৩ সময়'],
                ['M Mo MM MMMM MMM', '২ ২ ০২ ফেব্রুয়ারি ফেব্রু'],
                ['YYYY YY', '২০১০ ১০'],
                ['D Do DD', '১৪ ১৪ ১৪'],
                ['d do dddd ddd dd', '০ ০ রবিবার রবি রবি'],
                ['DDD DDDo DDDD', '৪৫ ৪৫ ০৪৫'],
                ['w wo ww', '৮ ৮ ০৮'],
                ['h hh', '৩ ০৩'],
                ['H HH', '১৫ ১৫'],
                ['m mm', '২৫ ২৫'],
                ['s ss', '৫০ ৫০'],
                ['a A', 'দুপুর দুপুর'],
                ['LT', 'দুপুর ৩:২৫ সময়'],
                ['LTS', 'দুপুর ৩:২৫:৫০ সময়'],
                ['L', '১৪/০২/২০১০'],
                ['LL', '১৪ ফেব্রুয়ারি ২০১০'],
                ['LLL', '১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫ সময়'],
                ['LLLL', 'রবিবার, ১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫ সময়'],
                ['l', '১৪/২/২০১০'],
                ['ll', '১৪ ফেব্রু ২০১০'],
                ['lll', '১৪ ফেব্রু ২০১০, দুপুর ৩:২৫ সময়'],
                ['llll', 'রবি, ১৪ ফেব্রু ২০১০, দুপুর ৩:২৫ সময়'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '১', '১');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '২', '২');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '৩', '৩');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '৪', '৪');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '৫', '৫');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '৬', '৬');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '৭', '৭');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '৮', '৮');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '৯', '৯');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '১০', '১০');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '১১', '১১');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '১২', '১২');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '১৩', '১৩');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '১৪', '১৪');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '১৫', '১৫');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '১৬', '১৬');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '১৭', '১৭');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '১৮', '১৮');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '১৯', '১৯');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '২০', '২০');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '২১', '২১');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '২২', '২২');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '২৩', '২৩');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '২৪', '২৪');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '২৫', '২৫');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '২৬', '২৬');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '২৭', '২৭');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '২৮', '२৮');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '২৯', '২৯');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '৩০', '৩০');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '৩১', '৩১');
    });

    test('format month', function (assert) {
        var expected = 'জানুয়ারি জানু_ফেব্রুয়ারি ফেব্রু_মার্চ মার্চ_এপ্রিল এপ্রিল_মে মে_জুন জুন_জুলাই জুলাই_আগস্ট আগস্ট_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভে_ডিসেম্বর ডিসে'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'রবিবার রবি রবি_সোমবার সোম সোম_মঙ্গলবার মঙ্গল মঙ্গল_বুধবার বুধ বুধ_বৃহস্পতিবার বৃহস্পতি বৃহ_শুক্রবার শুক্র শুক্র_শনিবার শনি শনি'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'কয়েক সেকেন্ড',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'এক মিনিট',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'এক মিনিট',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '২ মিনিট',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '৪৪ মিনিট',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'এক ঘন্টা',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'এক ঘন্টা',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '২ ঘন্টা',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '৫ ঘন্টা',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '২১ ঘন্টা',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'এক দিন',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'এক দিন',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '২ দিন',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'এক দিন',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '৫ দিন',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '২৫ দিন',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'এক মাস',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'এক মাস',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '২ মাস',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '২ মাস',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '৩ মাস',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'এক মাস',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '৫ মাস',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'এক বছর',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '২ বছর',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'এক বছর',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '৫ বছর',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'কয়েক সেকেন্ড পরে', 'prefix');
        assert.equal(moment(0).from(30000), 'কয়েক সেকেন্ড আগে', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'কয়েক সেকেন্ড আগে',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'কয়েক সেকেন্ড পরে',
            'কয়েক সেকেন্ড পরে'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '৫ দিন পরে', '৫ দিন পরে');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'আজ দুপুর ১২:০০ সময়',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'আজ দুপুর ১২:২৫ সময়',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 3 }).calendar(),
            'আজ দুপুর ৩:০০ সময়',
            'Now plus 3 hours'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'আগামীকাল দুপুর ১২:০০ সময়',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'আজ দুপুর ১১:০০ সময়',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'গতকাল দুপুর ১২:০০ সময়',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[গত] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[গত] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[গত] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('a'),
            'রাত',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('a'), 'সকাল', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('a'),
            'দুপুর',
            'during day'
        );
        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'বিকাল', 'evening');
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('a'),
            'বিকাল',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'রাত', 'night');

        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('A'),
            'রাত',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('A'), 'সকাল', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('A'),
            'দুপুর',
            ' during day'
        );
        assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'বিকাল', 'evening');
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('A'),
            'বিকাল',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'রাত', 'night');
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '১ ০১ ১',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '১ ০১ ১',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '২ ০২ ২',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '২ ০২ ২',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '৩ ০৩ ৩',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('bo');

    test('parse', function (assert) {
        var tests = 'ཟླ་བ་དང་པོ ཟླ་༡_ཟླ་བ་གཉིས་པ ཟླ་༢_ཟླ་བ་གསུམ་པ ཟླ་༣_ཟླ་བ་བཞི་པ ཟླ་༤_ཟླ་བ་ལྔ་པ ཟླ་༥_ཟླ་བ་དྲུག་པ ཟླ་༦_ཟླ་བ་བདུན་པ ཟླ་༧_ཟླ་བ་བརྒྱད་པ ཟླ་༨_ཟླ་བ་དགུ་པ ཟླ་༩_ཟླ་བ་བཅུ་པ ཟླ་༡༠_ཟླ་བ་བཅུ་གཅིག་པ ཟླ་༡༡_ཟླ་བ་བཅུ་གཉིས་པ ཟླ་༡༢'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            // Failing only for month 1 (index 0)
            // equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            // Failing only for month 1 (index 0)
            // equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            // Failing only for month 1 (index 0)
            // equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, a h:mm:ss ལ་',
                    'གཟའ་ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥:༥༠ ལ་',
                ],
                ['ddd, a h ལ་', 'ཉི་མ་, ཉིན་གུང ༣ ལ་'],
                ['M Mo MM MMMM MMM', '༢ ༢ ༠༢ ཟླ་བ་གཉིས་པ ཟླ་༢'],
                ['YYYY YY', '༢༠༡༠ ༡༠'],
                ['D Do DD', '༡༤ ༡༤ ༡༤'],
                ['d do dddd ddd dd', '༠ ༠ གཟའ་ཉི་མ་ ཉི་མ་ ཉི'],
                ['DDD DDDo DDDD', '༤༥ ༤༥ ༠༤༥'],
                ['w wo ww', '༨ ༨ ༠༨'],
                ['h hh', '༣ ༠༣'],
                ['H HH', '༡༥ ༡༥'],
                ['m mm', '༢༥ ༢༥'],
                ['s ss', '༥༠ ༥༠'],
                ['a A', 'ཉིན་གུང ཉིན་གུང'],
                ['LT', 'ཉིན་གུང ༣:༢༥'],
                ['LTS', 'ཉིན་གུང ༣:༢༥:༥༠'],
                ['L', '༡༤/༠༢/༢༠༡༠'],
                ['LL', '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠'],
                ['LLL', '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],
                ['LLLL', 'གཟའ་ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],
                ['l', '༡༤/༢/༢༠༡༠'],
                ['ll', '༡༤ ཟླ་༢ ༢༠༡༠'],
                ['lll', '༡༤ ཟླ་༢ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],
                ['llll', 'ཉི་མ་, ༡༤ ཟླ་༢ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '༡', '༡');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '༢', '༢');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '༣', '༣');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '༤', '༤');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '༥', '༥');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '༦', '༦');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '༧', '༧');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '༨', '༨');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '༩', '༩');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '༡༠', '༡༠');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '༡༡', '༡༡');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '༡༢', '༡༢');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '༡༣', '༡༣');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '༡༤', '༡༤');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '༡༥', '༡༥');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '༡༦', '༡༦');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '༡༧', '༡༧');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '༡༨', '༡༨');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '༡༩', '༡༩');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '༢༠', '༢༠');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '༢༡', '༢༡');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '༢༢', '༢༢');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '༢༣', '༢༣');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '༢༤', '༢༤');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '༢༥', '༢༥');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '༢༦', '༢༦');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '༢༧', '༢༧');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '༢༨', '༢༨');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '༢༩', '༢༩');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '༣༠', '༣༠');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '༣༡', '༣༡');
    });

    test('format month', function (assert) {
        var expected = 'ཟླ་བ་དང་པོ ཟླ་༡_ཟླ་བ་གཉིས་པ ཟླ་༢_ཟླ་བ་གསུམ་པ ཟླ་༣_ཟླ་བ་བཞི་པ ཟླ་༤_ཟླ་བ་ལྔ་པ ཟླ་༥_ཟླ་བ་དྲུག་པ ཟླ་༦_ཟླ་བ་བདུན་པ ཟླ་༧_ཟླ་བ་བརྒྱད་པ ཟླ་༨_ཟླ་བ་དགུ་པ ཟླ་༩_ཟླ་བ་བཅུ་པ ཟླ་༡༠_ཟླ་བ་བཅུ་གཅིག་པ ཟླ་༡༡_ཟླ་བ་བཅུ་གཉིས་པ ཟླ་༡༢'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'གཟའ་ཉི་མ་ ཉི་མ་ ཉི_གཟའ་ཟླ་བ་ ཟླ་བ་ ཟླ_གཟའ་མིག་དམར་ མིག་དམར་ མིག_གཟའ་ལྷག་པ་ ལྷག་པ་ ལྷག_གཟའ་ཕུར་བུ ཕུར་བུ ཕུར_གཟའ་པ་སངས་ པ་སངས་ སངས_གཟའ་སྤེན་པ་ སྤེན་པ་ སྤེན'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ལམ་སང',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'སྐར་མ་གཅིག',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'སྐར་མ་གཅིག',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '༢ སྐར་མ',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '༤༤ སྐར་མ',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ཆུ་ཚོད་གཅིག',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ཆུ་ཚོད་གཅིག',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '༢ ཆུ་ཚོད',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '༥ ཆུ་ཚོད',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '༢༡ ཆུ་ཚོད',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ཉིན་གཅིག',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ཉིན་གཅིག',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '༢ ཉིན་',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ཉིན་གཅིག',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '༥ ཉིན་',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '༢༥ ཉིན་',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ཟླ་བ་གཅིག',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ཟླ་བ་གཅིག',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ཟླ་བ་གཅིག',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '༢ ཟླ་བ',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '༢ ཟླ་བ',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '༣ ཟླ་བ',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ཟླ་བ་གཅིག',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '༥ ཟླ་བ',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ལོ་གཅིག',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '༢ ལོ',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ལོ་གཅིག',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '༥ ལོ',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'ལམ་སང ལ་', 'prefix');
        assert.equal(moment(0).from(30000), 'ལམ་སང སྔན་ལ', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'ལམ་སང སྔན་ལ',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(moment().add({ s: 30 }).fromNow(), 'ལམ་སང ལ་', 'ལམ་སང ལ་');
        assert.equal(moment().add({ d: 5 }).fromNow(), '༥ ཉིན་ ལ་', '༥ ཉིན་ ལ་');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'དི་རིང ཉིན་གུང ༡༢:༠༠',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'དི་རིང ཉིན་གུང ༡༢:༢༥',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 3 }).calendar(),
            'དི་རིང ཉིན་གུང ༣:༠༠',
            'Now plus 3 hours'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'སང་ཉིན ཉིན་གུང ༡༢:༠༠',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'དི་རིང ཉིན་གུང ༡༡:༠༠',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ཁ་སང ཉིན་གུང ༡༢:༠༠',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('a'),
            'མཚན་མོ',
            'before dawn'
        );
        assert.equal(
            moment([2011, 2, 23, 9, 30]).format('a'),
            'ཞོགས་ཀས',
            'morning'
        );
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('a'),
            'ཉིན་གུང',
            'during day'
        );
        assert.equal(
            moment([2011, 2, 23, 17, 30]).format('a'),
            'དགོང་དག',
            'evening'
        );
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('a'),
            'དགོང་དག',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'མཚན་མོ', 'night');

        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('A'),
            'མཚན་མོ',
            'before dawn'
        );
        assert.equal(
            moment([2011, 2, 23, 9, 30]).format('A'),
            'ཞོགས་ཀས',
            'morning'
        );
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('A'),
            'ཉིན་གུང',
            ' during day'
        );
        assert.equal(
            moment([2011, 2, 23, 17, 30]).format('A'),
            'དགོང་དག',
            'evening'
        );
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('A'),
            'དགོང་དག',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'མཚན་མོ', 'night');
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '༡ ༠༡ ༡',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '༡ ༠༡ ༡',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '༢ ༠༢ ༢',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '༢ ༠༢ ༢',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '༣ ༠༣ ༣',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('br');

    test('parse', function (assert) {
        var tests = 'Genver Gen_Cʼhwevrer Cʼhwe_Meurzh Meu_Ebrel Ebr_Mae Mae_Mezheven Eve_Gouere Gou_Eost Eos_Gwengolo Gwe_Here Her_Du Du_Kerzu Ker'.split(
                '_'
            ),
            i,
            monthsWithRegularQuoteMark = ["C'hwevrer", "C'hwe"];

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }

        // check with regular quote mark
        equalTest(monthsWithRegularQuoteMark[0], 'MMM', 1);
        equalTest(monthsWithRegularQuoteMark[1], 'MMM', 1);
        equalTest(monthsWithRegularQuoteMark[0], 'MMMM', 1);
        equalTest(monthsWithRegularQuoteMark[1], 'MMMM', 1);
        equalTest(monthsWithRegularQuoteMark[0].toLocaleLowerCase(), 'MMM', 1);
        equalTest(monthsWithRegularQuoteMark[1].toLocaleLowerCase(), 'MMM', 1);
        equalTest(monthsWithRegularQuoteMark[0].toLocaleUpperCase(), 'MMMM', 1);
        equalTest(monthsWithRegularQuoteMark[1].toLocaleUpperCase(), 'MMMM', 1);

        assert.notEqual(
            moment(monthsWithRegularQuoteMark[0], 'MMM', true).month(),
            1
        );
        equalTestStrict(monthsWithRegularQuoteMark[1], 'MMM', 1);
        equalTest(monthsWithRegularQuoteMark[0], 'MMMM', 1);
        assert.notEqual(
            moment(monthsWithRegularQuoteMark[1], 'MMMM', true).month(),
            1
        );
        equalTest(monthsWithRegularQuoteMark[1].toLocaleLowerCase(), 'MMM', 1);
        equalTest(monthsWithRegularQuoteMark[0].toLocaleUpperCase(), 'MMMM', 1);

        // check weekday with regular quote mark
        assert.equal(
            moment("merc'her", 'dddd', true).day(),
            3,
            "merc'her (regular quote)"
        );
        assert.equal(
            moment('mercʼher', 'dddd', true).day(),
            3,
            'mercʼher (special quote)'
        );
    });

    test('format', function (assert) {
        moment.locale('br');
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Sul, Cʼhwevrer 14vet 2010, 3:25:50 g.m.',
                ],
                ['ddd, h A', 'Sul, 3 g.m.'],
                ['M Mo MM MMMM MMM', '2 2vet 02 Cʼhwevrer Cʼhwe'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14vet 14'],
                ['d do dddd ddd dd', '0 0vet Sul Sul Su'],
                ['DDD DDDo DDDD', '45 45vet 045'],
                ['w wo ww', '6 6vet 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['DDDo [devezh] [ar] [vloaz]', '45vet devezh ar vloaz'],
                ['L', '14/02/2010'],
                ['LL', '14 a viz Cʼhwevrer 2010'],
                ['LLL', '14 a viz Cʼhwevrer 2010 15:25'],
                ['LLLL', 'Sul, 14 a viz Cʼhwevrer 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        moment.locale('br');
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1añ', '1añ');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2vet', '2vet');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3vet', '3vet');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4vet', '4vet');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5vet', '5vet');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6vet', '6vet');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7vet', '7vet');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8vet', '8vet');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9vet', '9vet');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10vet', '10vet');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11vet', '11vet');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12vet', '12vet');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13vet', '13vet');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14vet', '14vet');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15vet', '15vet');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16vet', '16vet');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17vet', '17vet');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18vet', '18vet');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19vet', '19vet');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20vet', '20vet');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21vet', '21vet');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22vet', '22vet');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23vet', '23vet');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24vet', '24vet');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25vet', '25vet');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26vet', '26vet');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27vet', '27vet');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28vet', '28vet');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29vet', '29vet');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30vet', '30vet');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31vet', '31vet');
    });

    test('format month', function (assert) {
        moment.locale('br');
        var expected = 'Genver Gen_Cʼhwevrer Cʼhwe_Meurzh Meu_Ebrel Ebr_Mae Mae_Mezheven Eve_Gouere Gou_Eost Eos_Gwengolo Gwe_Here Her_Du Du_Kerzu Ker'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        moment.locale('br');
        var expected = 'Sul Sul Su_Lun Lun Lu_Meurzh Meu Me_Mercʼher Mer Mer_Yaou Yao Ya_Gwener Gwe Gw_Sadorn Sad Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        moment.locale('br');
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'un nebeud segondennoù',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ur vunutenn',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ur vunutenn',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 vunutenn',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 munutenn',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'un eur',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'un eur',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 eur',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 eur',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 eur',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un devezh',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un devezh',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 zevezh',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un devezh',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 devezh',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 devezh',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ur miz',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ur miz',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ur miz',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 viz',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 viz',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 miz',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ur miz',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 miz',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ur bloaz',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 vloaz',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ur bloaz',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 bloaz',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        moment.locale('br');
        assert.equal(
            moment(30000).from(0),
            'a-benn un nebeud segondennoù',
            'prefix'
        );
        assert.equal(moment(0).from(30000), 'un nebeud segondennoù ʼzo', 'suffix');
    });

    test('now from now', function (assert) {
        moment.locale('br');
        assert.equal(
            moment().fromNow(),
            'un nebeud segondennoù ʼzo',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        moment.locale('br');
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'a-benn un nebeud segondennoù',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'a-benn 5 devezh',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        moment.locale('br');

        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Hiziv da 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Hiziv da 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Hiziv da 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ h: 3 }).calendar(),
            'Hiziv da 15:00',
            'Now plus 3 hour'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Hiziv da 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Warcʼhoazh da 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Decʼh da 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        moment.locale('br');

        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [da] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [da] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [da] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        moment.locale('br');

        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [paset da] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [paset da] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [paset da] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        moment.locale('br');
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('special mutations for years', function (assert) {
        moment.locale('br');
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ur bloaz',
            'mutation 1 year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 2 }), true),
            '2 vloaz',
            'mutation 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 3 }), true),
            '3 bloaz',
            'mutation 3 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 4 }), true),
            '4 bloaz',
            'mutation 4 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 bloaz',
            'mutation 5 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 9 }), true),
            '9 bloaz',
            'mutation 9 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 10 }), true),
            '10 vloaz',
            'mutation 10 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 21 }), true),
            '21 bloaz',
            'mutation 21 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 22 }), true),
            '22 vloaz',
            'mutation 22 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 133 }), true),
            '133 bloaz',
            'mutation 133 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 148 }), true),
            '148 vloaz',
            'mutation 148 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 261 }), true),
            '261 bloaz',
            'mutation 261 years'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('bs');

    test('parse', function (assert) {
        var tests = 'januar jan._februar feb._mart mar._april apr._maj maj._juni jun._juli jul._august aug._septembar sep._oktobar okt._novembar nov._decembar dec.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1) + ' inp ' + mmm
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'nedjelja, 14. februar 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'ned., 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 februar feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. nedjelja ned. ne'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '7 7. 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. februar 2010'],
                ['LLL', '14. februar 2010 15:25'],
                ['LLLL', 'nedjelja, 14. februar 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14. feb. 2010'],
                ['lll', '14. feb. 2010 15:25'],
                ['llll', 'ned., 14. feb. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'januar jan._februar feb._mart mar._april apr._maj maj._juni jun._juli jul._august aug._septembar sep._oktobar okt._novembar nov._decembar dec.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'par sekundi',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'jedna minuta',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'jedna minuta',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minute',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuta',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'jedan sat',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'jedan sat',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 sata',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 sati',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 sati',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'dan',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'dan',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dana',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'dan',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dana',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dana',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'mjesec',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'mjesec',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'mjesec',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mjeseca',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mjeseca',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mjeseca',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'mjesec',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mjeseci',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'godinu',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 godine',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'godinu',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 godina',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'za par sekundi', 'prefix');
        assert.equal(moment(0).from(30000), 'prije par sekundi', 'prefix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'prije par sekundi',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'za par sekundi',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'za 5 dana', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'danas u 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'danas u 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'danas u 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'sutra u 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'danas u 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'jučer u 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                    return '[u] [nedjelju] [u] LT';
                case 3:
                    return '[u] [srijedu] [u] LT';
                case 6:
                    return '[u] [subotu] [u] LT';
                case 1:
                case 2:
                case 4:
                case 5:
                    return '[u] dddd [u] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                case 3:
                    return '[prošlu] dddd [u] LT';
                case 6:
                    return '[prošle] [subote] [u] LT';
                case 1:
                case 2:
                case 4:
                case 5:
                    return '[prošli] dddd [u] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1.',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1.',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2.',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2.',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3.',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ca');

    test('parse', function (assert) {
        var tests = 'gener gen._febrer febr._març març_abril abr._maig maig_juny juny_juliol jul._agost ag._setembre set._octubre oct._novembre nov._desembre des.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'diumenge, 14è de febrer 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dg., 3PM'],
                ['M Mo MM MMMM MMM', '2 2n 02 febrer febr.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14è 14'],
                ['d do dddd ddd dd', '0 0è diumenge dg. dg'],
                ['DDD DDDo DDDD', '45 45è 045'],
                ['w wo ww', '6 6a 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45è day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 de febrer de 2010'],
                ['LLL', '14 de febrer de 2010 a les 15:25'],
                ['LLLL', 'diumenge 14 de febrer de 2010 a les 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 febr. 2010'],
                ['lll', '14 febr. 2010, 15:25'],
                ['llll', 'dg. 14 febr. 2010, 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1r', '1r');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2n', '2n');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3r', '3r');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4t', '4t');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5è', '5è');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6è', '6è');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7è', '7è');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8è', '8è');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9è', '9è');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10è', '10è');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11è', '11è');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12è', '12è');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13è', '13è');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14è', '14è');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15è', '15è');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16è', '16è');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17è', '17è');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18è', '18è');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19è', '19è');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20è', '20è');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21è', '21è');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22è', '22è');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23è', '23è');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24è', '24è');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25è', '25è');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26è', '26è');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27è', '27è');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28è', '28è');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29è', '29è');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30è', '30è');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31è', '31è');
    });

    test('format month', function (assert) {
        var expected = 'gener gen._febrer febr._març març_abril abr._maig maig_juny juny_juliol jul._agost ag._setembre set._octubre oct._novembre nov._desembre des.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'diumenge dg. dg_dilluns dl. dl_dimarts dt. dt_dimecres dc. dc_dijous dj. dj_divendres dv. dv_dissabte ds. ds'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'uns segons',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'un minut',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'un minut',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuts',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuts',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'una hora',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'una hora',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 hores',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 hores',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 hores',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un dia',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un dia',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dies',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un dia',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dies',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dies',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'un mes',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'un mes',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'un mes',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mesos',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mesos',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mesos',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'un mes',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mesos',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un any',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 anys',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un any',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 anys',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), "d'aquí uns segons", 'prefix');
        assert.equal(moment(0).from(30000), 'fa uns segons', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'fa uns segons',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            "d'aquí uns segons",
            "d'aquí uns segons"
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            "d'aquí 5 dies",
            "d'aquí 5 dies"
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'avui a les 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'avui a les 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'avui a les 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'demà a les 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).add({ d: 1, h: -1 }).calendar(),
            'demà a les 11:00',
            'tomorrow minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'avui a les 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ahir a les 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [a ' + (m.hours() !== 1 ? 'les' : 'la') + '] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [a ' + (m.hours() !== 1 ? 'les' : 'la') + '] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [a ' + (m.hours() !== 1 ? 'les' : 'la') + '] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [passat a ' +
                        (m.hours() !== 1 ? 'les' : 'la') +
                        '] LT'
                ),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [passat a ' +
                        (m.hours() !== 1 ? 'les' : 'la') +
                        '] LT'
                ),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [passat a ' +
                        (m.hours() !== 1 ? 'les' : 'la') +
                        '] LT'
                ),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52a',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1a',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1a',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2a',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2a',
            'Jan 15 2012 should be week 2'
        );
    });

    test('day and month', function (assert) {
        assert.equal(moment([2012, 1, 15]).format('D MMMM'), '15 de febrer');
        assert.equal(moment([2012, 9, 15]).format('D MMMM'), "15 d'octubre");
        assert.equal(moment([2012, 9, 15]).format('MMMM, D'), 'octubre, 15');
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('cs');

    test('parse', function (assert) {
        var tests = 'leden led ledna_únor úno února_březen bře března_duben dub dubna_květen kvě května_červen čvn června_červenec čvc července_srpen srp srpna_září zář září_říjen říj října_listopad lis listopadu_prosinec pro prosince'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm).month(),
                monthIndex,
                input + ' ' + mmm + ' should be month ' + (monthIndex + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }
        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][2], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][2], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][2].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][2].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][2], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTestStrict(tests[i][2].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][2].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                ['dddd, MMMM Do YYYY, h:mm:ss', 'neděle, únor 14. 2010, 3:25:50'],
                ['ddd, h', 'ne, 3'],
                ['M Mo MM MMMM MMM', '2 2. 02 únor úno'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. neděle ne ne'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['DDDo [den v roce]', '45. den v roce'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. únor 2010'],
                ['LLL', '14. únor 2010 15:25'],
                ['LLLL', 'neděle 14. únor 2010 15:25'],
                ['l', '14. 2. 2010'],
                ['ll', '14. úno 2010'],
                ['lll', '14. úno 2010 15:25'],
                ['llll', 'ne 14. úno 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'leden led_únor úno_březen bře_duben dub_květen kvě_červen čvn_červenec čvc_srpen srp_září zář_říjen říj_listopad lis_prosinec pro'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'neděle ne ne_pondělí po po_úterý út út_středa st st_čtvrtek čt čt_pátek pá pá_sobota so so'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'pár sekund',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'minuta',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'minuta',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuty',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minut',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'hodina',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'hodina',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 hodiny',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 hodin',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 hodin',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'den',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'den',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dny',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'den',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dní',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dní',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'měsíc',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'měsíc',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'měsíc',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 měsíce',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 měsíce',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 měsíce',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'měsíc',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 měsíců',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'rok',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 roky',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'rok',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 let',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'za pár sekund', 'prefix');
        assert.equal(moment(0).from(30000), 'před pár sekundami', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'před pár sekundami',
            'now from now should display as in the past'
        );
    });

    test('fromNow (future)', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'za pár sekund',
            'in a few seconds'
        );
        assert.equal(moment().add({ m: 1 }).fromNow(), 'za minutu', 'in a minute');
        assert.equal(
            moment().add({ m: 3 }).fromNow(),
            'za 3 minuty',
            'in 3 minutes'
        );
        assert.equal(
            moment().add({ m: 10 }).fromNow(),
            'za 10 minut',
            'in 10 minutes'
        );
        assert.equal(moment().add({ h: 1 }).fromNow(), 'za hodinu', 'in an hour');
        assert.equal(moment().add({ h: 3 }).fromNow(), 'za 3 hodiny', 'in 3 hours');
        assert.equal(
            moment().add({ h: 10 }).fromNow(),
            'za 10 hodin',
            'in 10 hours'
        );
        assert.equal(moment().add({ d: 1 }).fromNow(), 'za den', 'in a day');
        assert.equal(moment().add({ d: 3 }).fromNow(), 'za 3 dny', 'in 3 days');
        assert.equal(moment().add({ d: 10 }).fromNow(), 'za 10 dní', 'in 10 days');
        assert.equal(moment().add({ M: 1 }).fromNow(), 'za měsíc', 'in a month');
        assert.equal(
            moment().add({ M: 3 }).fromNow(),
            'za 3 měsíce',
            'in 3 months'
        );
        assert.equal(
            moment().add({ M: 10 }).fromNow(),
            'za 10 měsíců',
            'in 10 months'
        );
        assert.equal(moment().add({ y: 1 }).fromNow(), 'za rok', 'in a year');
        assert.equal(moment().add({ y: 3 }).fromNow(), 'za 3 roky', 'in 3 years');
        assert.equal(moment().add({ y: 10 }).fromNow(), 'za 10 let', 'in 10 years');
    });

    test('fromNow (past)', function (assert) {
        assert.equal(
            moment().subtract({ s: 30 }).fromNow(),
            'před pár sekundami',
            'a few seconds ago'
        );
        assert.equal(
            moment().subtract({ m: 1 }).fromNow(),
            'před minutou',
            'a minute ago'
        );
        assert.equal(
            moment().subtract({ m: 3 }).fromNow(),
            'před 3 minutami',
            '3 minutes ago'
        );
        assert.equal(
            moment().subtract({ m: 10 }).fromNow(),
            'před 10 minutami',
            '10 minutes ago'
        );
        assert.equal(
            moment().subtract({ h: 1 }).fromNow(),
            'před hodinou',
            'an hour ago'
        );
        assert.equal(
            moment().subtract({ h: 3 }).fromNow(),
            'před 3 hodinami',
            '3 hours ago'
        );
        assert.equal(
            moment().subtract({ h: 10 }).fromNow(),
            'před 10 hodinami',
            '10 hours ago'
        );
        assert.equal(
            moment().subtract({ d: 1 }).fromNow(),
            'před dnem',
            'a day ago'
        );
        assert.equal(
            moment().subtract({ d: 3 }).fromNow(),
            'před 3 dny',
            '3 days ago'
        );
        assert.equal(
            moment().subtract({ d: 10 }).fromNow(),
            'před 10 dny',
            '10 days ago'
        );
        assert.equal(
            moment().subtract({ M: 1 }).fromNow(),
            'před měsícem',
            'a month ago'
        );
        assert.equal(
            moment().subtract({ M: 3 }).fromNow(),
            'před 3 měsíci',
            '3 months ago'
        );
        assert.equal(
            moment().subtract({ M: 10 }).fromNow(),
            'před 10 měsíci',
            '10 months ago'
        );
        assert.equal(
            moment().subtract({ y: 1 }).fromNow(),
            'před rokem',
            'a year ago'
        );
        assert.equal(
            moment().subtract({ y: 3 }).fromNow(),
            'před 3 lety',
            '3 years ago'
        );
        assert.equal(
            moment().subtract({ y: 10 }).fromNow(),
            'před 10 lety',
            '10 years ago'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'dnes v 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'dnes v 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'dnes v 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'zítra v 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'dnes v 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'včera v 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m, nextDay;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            nextDay = '';
            switch (m.day()) {
                case 0:
                    nextDay = 'v neděli';
                    break;
                case 1:
                    nextDay = 'v pondělí';
                    break;
                case 2:
                    nextDay = 'v úterý';
                    break;
                case 3:
                    nextDay = 've středu';
                    break;
                case 4:
                    nextDay = 've čtvrtek';
                    break;
                case 5:
                    nextDay = 'v pátek';
                    break;
                case 6:
                    nextDay = 'v sobotu';
                    break;
            }
            assert.equal(
                m.calendar(),
                m.format('[' + nextDay + '] [v] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[' + nextDay + '] [v] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[' + nextDay + '] [v] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m, lastDay;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            lastDay = '';
            switch (m.day()) {
                case 0:
                    lastDay = 'minulou neděli';
                    break;
                case 1:
                    lastDay = 'minulé pondělí';
                    break;
                case 2:
                    lastDay = 'minulé úterý';
                    break;
                case 3:
                    lastDay = 'minulou středu';
                    break;
                case 4:
                    lastDay = 'minulý čtvrtek';
                    break;
                case 5:
                    lastDay = 'minulý pátek';
                    break;
                case 6:
                    lastDay = 'minulou sobotu';
                    break;
            }
            assert.equal(
                m.calendar(),
                m.format('[' + lastDay + '] [v] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[' + lastDay + '] [v] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[' + lastDay + '] [v] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('humanize duration', function (assert) {
        assert.equal(
            moment.duration(1, 'minutes').humanize(),
            'minuta',
            'a minute (future)'
        );
        assert.equal(
            moment.duration(1, 'minutes').humanize(true),
            'za minutu',
            'in a minute'
        );
        assert.equal(
            moment.duration(-1, 'minutes').humanize(),
            'minuta',
            'a minute (past)'
        );
        assert.equal(
            moment.duration(-1, 'minutes').humanize(true),
            'před minutou',
            'a minute ago'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('cv');

    test('parse', function (assert) {
        var tests = 'кӑрлач кӑр_нарӑс нар_пуш пуш_ака ака_май май_ҫӗртме ҫӗр_утӑ утӑ_ҫурла ҫур_авӑн авн_юпа юпа_чӳк чӳк_раштав раш'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'вырсарникун, нарӑс 14-мӗш 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'выр, 3PM'],
                ['M Mo MM MMMM MMM', '2 2-мӗш 02 нарӑс нар'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14-мӗш 14'],
                ['d do dddd ddd dd', '0 0-мӗш вырсарникун выр вр'],
                ['DDD DDDo DDDD', '45 45-мӗш 045'],
                ['w wo ww', '7 7-мӗш 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['Ҫулӑн DDDo кунӗ', 'Ҫулӑн 45-мӗш кунӗ'],
                ['LTS', '15:25:50'],
                ['L', '14-02-2010'],
                ['LL', '2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ'],
                ['LLL', '2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ, 15:25'],
                ['LLLL', 'вырсарникун, 2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ, 15:25'],
                ['l', '14-2-2010'],
                ['ll', '2010 ҫулхи нар уйӑхӗн 14-мӗшӗ'],
                ['lll', '2010 ҫулхи нар уйӑхӗн 14-мӗшӗ, 15:25'],
                ['llll', 'выр, 2010 ҫулхи нар уйӑхӗн 14-мӗшӗ, 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-мӗш', '1-мӗш');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-мӗш', '2-мӗш');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-мӗш', '3-мӗш');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-мӗш', '4-мӗш');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-мӗш', '5-мӗш');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-мӗш', '6-мӗш');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-мӗш', '7-мӗш');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-мӗш', '8-мӗш');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-мӗш', '9-мӗш');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-мӗш', '10-мӗш');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-мӗш', '11-мӗш');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-мӗш', '12-мӗш');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-мӗш', '13-мӗш');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-мӗш', '14-мӗш');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-мӗш', '15-мӗш');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-мӗш', '16-мӗш');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-мӗш', '17-мӗш');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-мӗш', '18-мӗш');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-мӗш', '19-мӗш');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-мӗш', '20-мӗш');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-мӗш', '21-мӗш');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-мӗш', '22-мӗш');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-мӗш', '23-мӗш');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-мӗш', '24-мӗш');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-мӗш', '25-мӗш');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-мӗш', '26-мӗш');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-мӗш', '27-мӗш');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-мӗш', '28-мӗш');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-мӗш', '29-мӗш');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-мӗш', '30-мӗш');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-мӗш', '31-мӗш');
    });

    test('format month', function (assert) {
        var expected = 'кӑрлач кӑр_нарӑс нар_пуш пуш_ака ака_май май_ҫӗртме ҫӗр_утӑ утӑ_ҫурла ҫур_авӑн авн_юпа юпа_чӳк чӳк_раштав раш'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'вырсарникун выр вр_тунтикун тун тн_ытларикун ытл ыт_юнкун юн юн_кӗҫнерникун кӗҫ кҫ_эрнекун эрн эр_шӑматкун шӑм шм'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'пӗр-ик ҫеккунт',
            '44 sekunder = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'пӗр минут',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'пӗр минут',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 минут',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 минут',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'пӗр сехет',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'пӗр сехет',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 сехет',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 сехет',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 сехет',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'пӗр кун',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'пӗр кун',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 кун',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'пӗр кун',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 кун',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 кун',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'пӗр уйӑх',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'пӗр уйӑх',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'пӗр уйӑх',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 уйӑх',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 уйӑх',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 уйӑх',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'пӗр уйӑх',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 уйӑх',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'пӗр ҫул',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ҫул',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'пӗр ҫул',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ҫул',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'пӗр-ик ҫеккунтран', 'prefix');
        assert.equal(moment(0).from(30000), 'пӗр-ик ҫеккунт каялла', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'пӗр-ик ҫеккунт каялла',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'пӗр-ик ҫеккунтран',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 кунран', 'in 5 days');
        assert.equal(
            moment().add({ h: 2 }).fromNow(),
            '2 сехетрен',
            'in 2 hours, the right suffix!'
        );
        assert.equal(
            moment().add({ y: 3 }).fromNow(),
            '3 ҫултан',
            'in 3 years, the right suffix!'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);
        assert.equal(
            moment(a).calendar(),
            'Паян 12:00 сехетре',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Паян 12:25 сехетре',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Паян 13:00 сехетре',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Ыран 12:00 сехетре',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Паян 11:00 сехетре',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Ӗнер 12:00 сехетре',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Ҫитес] dddd LT [сехетре]'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Ҫитес] dddd LT [сехетре]'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Ҫитес] dddd LT [сехетре]'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Иртнӗ] dddd LT [сехетре]'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Иртнӗ] dddd LT [сехетре]'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Иртнӗ] dddd LT [сехетре]'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    // Monday is the first day of the week.
    // The week that contains Jan 1st is the first week of the year.

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1-мӗш',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1-мӗш',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2-мӗш',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2-мӗш',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3-мӗш',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('cy');

    test('parse', function (assert) {
        var tests = 'Ionawr Ion_Chwefror Chwe_Mawrth Maw_Ebrill Ebr_Mai Mai_Mehefin Meh_Gorffennaf Gor_Awst Aws_Medi Med_Hydref Hyd_Tachwedd Tach_Rhagfyr Rhag'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Dydd Sul, Chwefror 14eg 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Sul, 3PM'],
                ['M Mo MM MMMM MMM', '2 2il 02 Chwefror Chwe'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14eg 14'],
                ['d do dddd ddd dd', '0 0 Dydd Sul Sul Su'],
                ['DDD DDDo DDDD', '45 45ain 045'],
                ['w wo ww', '6 6ed 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45ain day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 Chwefror 2010'],
                ['LLL', '14 Chwefror 2010 15:25'],
                ['LLLL', 'Dydd Sul, 14 Chwefror 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Chwe 2010'],
                ['lll', '14 Chwe 2010 15:25'],
                ['llll', 'Sul, 14 Chwe 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1af', '1af');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2il', '2il');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3ydd', '3ydd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4ydd', '4ydd');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5ed', '5ed');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6ed', '6ed');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7ed', '7ed');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8fed', '8fed');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9fed', '9fed');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10fed', '10fed');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11eg', '11eg');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12fed', '12fed');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13eg', '13eg');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14eg', '14eg');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15fed', '15fed');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16eg', '16eg');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17eg', '17eg');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18fed', '18fed');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19eg', '19eg');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20fed', '20fed');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ain', '21ain');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ain', '22ain');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ain', '23ain');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ain', '24ain');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ain', '25ain');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ain', '26ain');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ain', '27ain');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ain', '28ain');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ain', '29ain');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ain', '30ain');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ain', '31ain');
    });

    test('format month', function (assert) {
        var expected = 'Ionawr Ion_Chwefror Chwe_Mawrth Maw_Ebrill Ebr_Mai Mai_Mehefin Meh_Gorffennaf Gor_Awst Aws_Medi Med_Hydref Hyd_Tachwedd Tach_Rhagfyr Rhag'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Dydd Sul Sul Su_Dydd Llun Llun Ll_Dydd Mawrth Maw Ma_Dydd Mercher Mer Me_Dydd Iau Iau Ia_Dydd Gwener Gwe Gw_Dydd Sadwrn Sad Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ychydig eiliadau',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'munud',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'munud',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 munud',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 munud',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'awr',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'awr',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 awr',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 awr',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 awr',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'diwrnod',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'diwrnod',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 diwrnod',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'diwrnod',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 diwrnod',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 diwrnod',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'mis',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'mis',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'mis',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mis',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mis',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mis',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'mis',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mis',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'blwyddyn',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 flynedd',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'blwyddyn',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 flynedd',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'mewn ychydig eiliadau', 'prefix');
        assert.equal(moment(0).from(30000), 'ychydig eiliadau yn ôl', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'mewn ychydig eiliadau',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'mewn 5 diwrnod',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Heddiw am 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Heddiw am 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Heddiw am 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Yfory am 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Heddiw am 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Ddoe am 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [am] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [am] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [am] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [diwethaf am] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [diwethaf am] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [diwethaf am] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52ain',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1af',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1af',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2il',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2il',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('da');

    test('parse', function (assert) {
        var tests = 'januar jan_februar feb_marts mar_april apr_maj maj_juni jun_juli jul_august aug_september sep_oktober okt_november nov_december dec'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd [den] Do MMMM YYYY, h:mm:ss a',
                    'søndag den 14. februar 2010, 3:25:50 pm',
                ],
                ['ddd hA', 'søn 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 februar feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. søndag søn sø'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[den] DDDo [dag på året]', 'den 45. dag på året'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. februar 2010'],
                ['LLL', '14. februar 2010 15:25'],
                ['LLLL', 'søndag d. 14. februar 2010 kl. 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14. feb 2010'],
                ['lll', '14. feb 2010 15:25'],
                ['llll', 'søn d. 14. feb 2010 kl. 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'januar jan_februar feb_marts mar_april apr_maj maj_juni jun_juli jul_august aug_september sep_oktober okt_november nov_december dec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'søndag søn sø_mandag man ma_tirsdag tir ti_onsdag ons on_torsdag tor to_fredag fre fr_lørdag lør lø'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'få sekunder',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'et minut',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'et minut',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutter',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutter',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'en time',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'en time',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 timer',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 timer',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 timer',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'en dag',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'en dag',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dage',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'en dag',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dage',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dage',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'en måned',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'en måned',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'en måned',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 måneder',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 måneder',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 måneder',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'en måned',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 måneder',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'et år',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 år',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'et år',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 år',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'om få sekunder', 'prefix');
        assert.equal(moment(0).from(30000), 'få sekunder siden', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'få sekunder siden',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'om få sekunder',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'om 5 dage', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'i dag kl. 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'i dag kl. 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'i dag kl. 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'i morgen kl. 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'i dag kl. 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'i går kl. 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('på dddd [kl.] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('på dddd [kl.] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('på dddd [kl.] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[i] dddd[s kl.] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[i] dddd[s kl.] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[i] dddd[s kl.] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('de-at');

    test('parse', function (assert) {
        var tests = 'Jänner Jän._Februar Feb._März März_April Apr._Mai Mai_Juni Juni_Juli Juli_August Aug._September Sep._Oktober Okt._November Nov._Dezember Dez.'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'Sonntag, 14. Februar 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'So., 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 Februar Feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. Sonntag So. So'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. Februar 2010'],
                ['LLL', '14. Februar 2010 15:25'],
                ['LLLL', 'Sonntag, 14. Februar 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14. Feb. 2010'],
                ['lll', '14. Feb. 2010 15:25'],
                ['llll', 'So., 14. Feb. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'Jänner Jän._Februar Feb._März März_April Apr._Mai Mai_Juni Juni_Juli Juli_August Aug._September Sep._Oktober Okt._November Nov._Dezember Dez.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ein paar Sekunden',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'eine Minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'eine Minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 Minuten',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 Minuten',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'eine Stunde',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'eine Stunde',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 Stunden',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 Stunden',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 Stunden',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ein Tag',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ein Tag',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 Tage',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ein Tag',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 Tage',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 Tage',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ein Monat',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ein Monat',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 Monate',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 Monate',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 Monate',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ein Monat',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 Monate',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ein Jahr',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 Jahre',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ein Jahr',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 Jahre',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');
        assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in ein paar Sekunden',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'in 5 Tagen', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'heute um 12:00 Uhr',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'heute um 12:25 Uhr',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'heute um 13:00 Uhr',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'morgen um 12:00 Uhr',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'heute um 11:00 Uhr',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'gestern um 12:00 Uhr',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[letzten] dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[letzten] dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[letzten] dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

    test('duration humanize week threshold', function (assert) {
        assert.equal(
            moment.duration(1, 'week').humanize({ d: 7, w: 4 }),
            'eine Woche',
            'a week'
        );
        assert.equal(
            moment.duration(-1, 'week').humanize({ d: 7, w: 4 }),
            'eine Woche',
            'a week'
        );
        assert.equal(
            moment.duration(-1, 'week').humanize(true, { d: 7, w: 4 }),
            'vor einer Woche',
            'a week ago'
        );
        assert.equal(
            moment.duration(1, 'week').humanize(true, { d: 7, w: 4 }),
            'in einer Woche',
            'in a week'
        );
        assert.equal(
            moment.duration(2, 'week').humanize({ d: 7, w: 4 }),
            '2 Wochen',
            '2 weeks'
        );
        assert.equal(
            moment.duration(-2, 'week').humanize({ d: 7, w: 4 }),
            '2 Wochen',
            '2 weeks'
        );
        assert.equal(
            moment.duration(2, 'week').humanize(true, { d: 7, w: 4 }),
            'in 2 Wochen',
            'in 2 week'
        );
        assert.equal(
            moment.duration(-2, 'week').humanize(true, { d: 7, w: 4 }),
            'vor 2 Wochen',
            '2 weeks ago'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('de-ch');

    test('parse', function (assert) {
        var tests = 'Januar Jan._Februar Feb._März März_April Apr._Mai Mai_Juni Juni_Juli Juli_August Aug._September Sep._Oktober Okt._November Nov._Dezember Dez.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'Sonntag, 14. Februar 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'So, 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 Februar Feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. Sonntag So So'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LT', '15:25'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. Februar 2010'],
                ['LLL', '14. Februar 2010 15:25'],
                ['LLLL', 'Sonntag, 14. Februar 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14. Feb. 2010'],
                ['lll', '14. Feb. 2010 15:25'],
                ['llll', 'So, 14. Feb. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'Januar Jan._Februar Feb._März März_April Apr._Mai Mai_Juni Juni_Juli Juli_August Aug._September Sep._Oktober Okt._November Nov._Dezember Dez.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Sonntag So So_Montag Mo Mo_Dienstag Di Di_Mittwoch Mi Mi_Donnerstag Do Do_Freitag Fr Fr_Samstag Sa Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ein paar Sekunden',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'eine Minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'eine Minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 Minuten',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 Minuten',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'eine Stunde',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'eine Stunde',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 Stunden',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 Stunden',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 Stunden',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ein Tag',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ein Tag',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 Tage',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ein Tag',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 Tage',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 Tage',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ein Monat',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ein Monat',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ein Monat',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 Monate',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 Monate',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 Monate',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ein Monat',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 Monate',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ein Jahr',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 Jahre',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ein Jahr',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 Jahre',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');
        assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in ein paar Sekunden',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'in 5 Tagen', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'heute um 12:00 Uhr',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'heute um 12:25 Uhr',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'heute um 13:00 Uhr',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'morgen um 12:00 Uhr',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'heute um 11:00 Uhr',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'gestern um 12:00 Uhr',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[letzten] dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[letzten] dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[letzten] dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

    test('duration humanize week threshold', function (assert) {
        assert.equal(
            moment.duration(1, 'week').humanize({ d: 7, w: 4 }),
            'eine Woche',
            'a week'
        );
        assert.equal(
            moment.duration(-1, 'week').humanize({ d: 7, w: 4 }),
            'eine Woche',
            'a week'
        );
        assert.equal(
            moment.duration(-1, 'week').humanize(true, { d: 7, w: 4 }),
            'vor einer Woche',
            'a week ago'
        );
        assert.equal(
            moment.duration(1, 'week').humanize(true, { d: 7, w: 4 }),
            'in einer Woche',
            'in a week'
        );
        assert.equal(
            moment.duration(2, 'week').humanize({ d: 7, w: 4 }),
            '2 Wochen',
            '2 weeks'
        );
        assert.equal(
            moment.duration(-2, 'week').humanize({ d: 7, w: 4 }),
            '2 Wochen',
            '2 weeks'
        );
        assert.equal(
            moment.duration(2, 'week').humanize(true, { d: 7, w: 4 }),
            'in 2 Wochen',
            'in 2 week'
        );
        assert.equal(
            moment.duration(-2, 'week').humanize(true, { d: 7, w: 4 }),
            'vor 2 Wochen',
            '2 weeks ago'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('de');

    test('parse', function (assert) {
        var tests = 'Januar Jan._Februar Feb._März März_April Apr._Mai Mai_Juni Juni_Juli Juli_August Aug._September Sep._Oktober Okt._November Nov._Dezember Dez.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'Sonntag, 14. Februar 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'So., 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 Februar Feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. Sonntag So. So'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. Februar 2010'],
                ['LLL', '14. Februar 2010 15:25'],
                ['LLLL', 'Sonntag, 14. Februar 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14. Feb. 2010'],
                ['lll', '14. Feb. 2010 15:25'],
                ['llll', 'So., 14. Feb. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'Januar Jan._Februar Feb._März März_April Apr._Mai Mai_Juni Juni_Juli Juli_August Aug._September Sep._Oktober Okt._November Nov._Dezember Dez.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ein paar Sekunden',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'eine Minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'eine Minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 Minuten',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 Minuten',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'eine Stunde',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'eine Stunde',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 Stunden',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 Stunden',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 Stunden',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ein Tag',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ein Tag',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 Tage',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ein Tag',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 Tage',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 Tage',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ein Monat',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ein Monat',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ein Monat',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 Monate',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 Monate',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 Monate',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ein Monat',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 Monate',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ein Jahr',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 Jahre',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ein Jahr',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 Jahre',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');
        assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in ein paar Sekunden',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'in 5 Tagen', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'heute um 12:00 Uhr',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'heute um 12:25 Uhr',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'heute um 13:00 Uhr',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'morgen um 12:00 Uhr',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'heute um 11:00 Uhr',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'gestern um 12:00 Uhr',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[letzten] dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[letzten] dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[letzten] dddd [um] LT [Uhr]'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

    test('duration humanize week threshold', function (assert) {
        assert.equal(
            moment.duration(1, 'week').humanize({ d: 7, w: 4 }),
            'eine Woche',
            'a week'
        );
        assert.equal(
            moment.duration(-1, 'week').humanize({ d: 7, w: 4 }),
            'eine Woche',
            'a week'
        );
        assert.equal(
            moment.duration(-1, 'week').humanize(true, { d: 7, w: 4 }),
            'vor einer Woche',
            'a week ago'
        );
        assert.equal(
            moment.duration(1, 'week').humanize(true, { d: 7, w: 4 }),
            'in einer Woche',
            'in a week'
        );
        assert.equal(
            moment.duration(2, 'week').humanize({ d: 7, w: 4 }),
            '2 Wochen',
            '2 weeks'
        );
        assert.equal(
            moment.duration(-2, 'week').humanize({ d: 7, w: 4 }),
            '2 Wochen',
            '2 weeks'
        );
        assert.equal(
            moment.duration(2, 'week').humanize(true, { d: 7, w: 4 }),
            'in 2 Wochen',
            'in 2 week'
        );
        assert.equal(
            moment.duration(-2, 'week').humanize(true, { d: 7, w: 4 }),
            'vor 2 Wochen',
            '2 weeks ago'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('dv');

    test('parse', function (assert) {
        var i,
            tests = [
                'ޖެނުއަރީ',
                'ފެބްރުއަރީ',
                'މާރިޗު',
                'އޭޕްރީލު',
                'މޭ',
                'ޖޫން',
                'ޖުލައި',
                'އޯގަސްޓު',
                'ސެޕްޓެމްބަރު',
                'އޮކްޓޯބަރު',
                'ނޮވެމްބަރު',
                'ޑިސެމްބަރު',
            ];

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            equalTest(tests[i], 'MMM', i);
            equalTest(tests[i], 'MMMM', i);
            equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i], 'MMM', i);
            equalTestStrict(tests[i].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i].toLocaleLowerCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'އާދިއްތަ، ފެބްރުއަރީ 14 2010، 3:25:50 މފ',
                ],
                ['ddd, hA', 'އާދިއްތަ، 3މފ'],
                ['M Mo MM MMMM MMM', '2 2 02 ފެބްރުއަރީ ފެބްރުއަރީ'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 އާދިއްތަ އާދިއްތަ އާދި'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '8 8 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'މފ މފ'],
                ['LTS', '15:25:50'],
                ['L', '14/2/2010'],
                ['LL', '14 ފެބްރުއަރީ 2010'],
                ['LLL', '14 ފެބްރުއަރީ 2010 15:25'],
                ['LLLL', 'އާދިއްތަ 14 ފެބްރުއަރީ 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 ފެބްރުއަރީ 2010'],
                ['lll', '14 ފެބްރުއަރީ 2010 15:25'],
                ['llll', 'އާދިއްތަ 14 ފެބްރުއަރީ 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format month', function (assert) {
        var i,
            expected = [
                'ޖެނުއަރީ',
                'ފެބްރުއަރީ',
                'މާރިޗު',
                'އޭޕްރީލު',
                'މޭ',
                'ޖޫން',
                'ޖުލައި',
                'އޯގަސްޓު',
                'ސެޕްޓެމްބަރު',
                'އޮކްޓޯބަރު',
                'ނޮވެމްބަރު',
                'ޑިސެމްބަރު',
            ];

        for (i = 0; i < expected.length; i++) {
            assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i]);
        }
    });

    test('format week', function (assert) {
        var i,
            expected = [
                'އާދިއްތަ',
                'ހޯމަ',
                'އަންގާރަ',
                'ބުދަ',
                'ބުރާސްފަތި',
                'ހުކުރު',
                'ހޮނިހިރު',
            ];

        for (i = 0; i < expected.length; i++) {
            assert.equal(moment([2011, 0, 2 + i]).format('dddd'), expected[i]);
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ސިކުންތުކޮޅެއް',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'މިނިޓެއް',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'މިނިޓެއް',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            'މިނިޓު 2',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            'މިނިޓު 44',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ގަޑިއިރެއް',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ގަޑިއިރެއް',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            'ގަޑިއިރު 2',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            'ގަޑިއިރު 5',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            'ގަޑިއިރު 21',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ދުވަހެއް',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ދުވަހެއް',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            'ދުވަސް 2',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ދުވަހެއް',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            'ދުވަސް 5',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            'ދުވަސް 25',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'މަހެއް',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'މަހެއް',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'މަހެއް',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            'މަސް 2',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            'މަސް 2',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            'މަސް 3',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'މަހެއް',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            'މަސް 5',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'އަހަރެއް',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            'އަހަރު 2',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'އަހަރެއް',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            'އަހަރު 5',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'ތެރޭގައި ސިކުންތުކޮޅެއް', 'prefix');
        assert.equal(moment(0).from(30000), 'ކުރިން ސިކުންތުކޮޅެއް', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'ތެރޭގައި ސިކުންތުކޮޅެއް',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'ތެރޭގައި ދުވަސް 5',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'މިއަދު 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'މިއަދު 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'މިއަދު 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'މާދަމާ 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'މިއަދު 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'އިއްޔެ 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[ފާއިތުވި] dddd LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[ފާއިތުވި] dddd LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[ފާއިތުވި] dddd LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('el');

    test('parse', function (assert) {
        var i,
            tests = 'Ιανουάριος Ιαν_Φεβρουάριος Φεβ_Μάρτιος Μαρ_Απρίλιος Απρ_Μάιος Μαϊ_Ιούνιος Ιουν_Ιούλιος Ιουλ_Αύγουστος Αυγ_Σεπτέμβριος Σεπ_Οκτώβριος Οκτ_Νοέμβριος Νοε_Δεκέμβριος Δεκ'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('parse meridiem', function (assert) {
        var i,
            b = moment(),
            meridiemTests = [
                // h a patterns, expected hours, isValid
                ['10 πμ', 10, true],
                ['10 μμ', 22, true],
                ['10 π.μ.', 10, true],
                ['10 μ.μ.', 22, true],
                ['10 π', 10, true],
                ['10 μ', 22, true],
                ['10 ΠΜ', 10, true],
                ['10 ΜΜ', 22, true],
                ['10 Π.Μ.', 10, true],
                ['10 Μ.Μ.', 22, true],
                ['10 Π', 10, true],
                ['10 Μ', 22, true],
                ['10 am', 10, false],
                ['10 pm', 10, false],
            ],
            parsed;

        // test that a formatted moment including meridiem string can be parsed back to the same moment
        assert.ok(
            b.isSame(
                moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true),
                'seconds'
            ),
            b.format('h:mm:ss a') +
                ' should be equal to ' +
                moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true).format(
                    'h:mm:ss a'
                )
        );

        // test that a formatted moment having a meridiem string can be parsed with strict flag
        assert.ok(
            moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true).isValid(),
            b.format('h:mm:ss a') + ' should be parsed as valid'
        );

        for (i = 0; i < meridiemTests.length; i++) {
            parsed = moment(meridiemTests[i][0], 'h a', 'el', true);
            assert.equal(
                parsed.isValid(),
                meridiemTests[i][2],
                'validity for ' + meridiemTests[i][0]
            );
            if (parsed.isValid()) {
                assert.equal(
                    parsed.hours(),
                    meridiemTests[i][1],
                    'hours for ' + meridiemTests[i][0]
                );
            }
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Κυριακή, Φεβρουάριος 14η 2010, 3:25:50 μμ',
                ],
                [
                    'dddd, D MMMM YYYY, h:mm:ss a',
                    'Κυριακή, 14 Φεβρουαρίου 2010, 3:25:50 μμ',
                ],
                ['ddd, hA', 'Κυρ, 3ΜΜ'],
                ['dddd, MMMM YYYY', 'Κυριακή, Φεβρουάριος 2010'],
                ['M Mo MM MMMM MMM', '2 2η 02 Φεβρουάριος Φεβ'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14η 14'],
                ['d do dddd ddd dd', '0 0η Κυριακή Κυρ Κυ'],
                ['DDD DDDo DDDD', '45 45η 045'],
                ['w wo ww', '6 6η 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'μμ ΜΜ'],
                ['[the] DDDo [day of the year]', 'the 45η day of the year'],
                ['LTS', '3:25:50 ΜΜ'],
                ['L', '14/02/2010'],
                ['LL', '14 Φεβρουαρίου 2010'],
                ['LLL', '14 Φεβρουαρίου 2010 3:25 ΜΜ'],
                ['LLLL', 'Κυριακή, 14 Φεβρουαρίου 2010 3:25 ΜΜ'],
                ['l', '14/2/2010'],
                ['ll', '14 Φεβ 2010'],
                ['lll', '14 Φεβ 2010 3:25 ΜΜ'],
                ['llll', 'Κυρ, 14 Φεβ 2010 3:25 ΜΜ'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1η', '1η');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2η', '2η');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3η', '3η');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4η', '4η');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5η', '5η');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6η', '6η');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7η', '7η');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8η', '8η');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9η', '9η');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10η', '10η');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11η', '11η');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12η', '12η');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13η', '13η');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14η', '14η');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15η', '15η');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16η', '16η');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17η', '17η');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18η', '18η');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19η', '19η');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20η', '20η');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21η', '21η');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22η', '22η');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23η', '23η');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24η', '24η');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25η', '25η');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26η', '26η');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27η', '27η');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28η', '28η');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29η', '29η');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30η', '30η');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31η', '31η');
    });

    test('format month', function (assert) {
        var i,
            expected = 'Ιανουάριος Ιαν_Φεβρουάριος Φεβ_Μάρτιος Μαρ_Απρίλιος Απρ_Μάιος Μαϊ_Ιούνιος Ιουν_Ιούλιος Ιουλ_Αύγουστος Αυγ_Σεπτέμβριος Σεπ_Οκτώβριος Οκτ_Νοέμβριος Νοε_Δεκέμβριος Δεκ'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'Κυριακή Κυρ Κυ_Δευτέρα Δευ Δε_Τρίτη Τρι Τρ_Τετάρτη Τετ Τε_Πέμπτη Πεμ Πε_Παρασκευή Παρ Πα_Σάββατο Σαβ Σα'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'λίγα δευτερόλεπτα',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ένα λεπτό',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ένα λεπτό',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 λεπτά',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 λεπτά',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'μία ώρα',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'μία ώρα',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ώρες',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ώρες',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ώρες',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'μία μέρα',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'μία μέρα',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 μέρες',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'μία μέρα',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 μέρες',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 μέρες',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ένας μήνας',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ένας μήνας',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ένας μήνας',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 μήνες',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 μήνες',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 μήνες',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ένας μήνας',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 μήνες',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ένας χρόνος',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 χρόνια',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ένας χρόνος',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 χρόνια',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'σε λίγα δευτερόλεπτα', 'prefix');
        assert.equal(moment(0).from(30000), 'λίγα δευτερόλεπτα πριν', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'λίγα δευτερόλεπτα πριν',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'σε λίγα δευτερόλεπτα',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'σε 5 μέρες', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Σήμερα στις 12:00 ΜΜ',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Σήμερα στις 12:25 ΜΜ',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Σήμερα στη 1:00 ΜΜ',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Αύριο στις 12:00 ΜΜ',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Σήμερα στις 11:00 ΠΜ',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Χθες στις 12:00 ΜΜ',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format(
                    'dddd [' + (m.hours() % 12 === 1 ? 'στη' : 'στις') + '] LT'
                ),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [στις] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [στις] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m, dayString;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            dayString =
                m.day() === 6
                    ? '[το προηγούμενο Σάββατο]'
                    : '[την προηγούμενη] dddd';
            assert.equal(
                m.calendar(),
                m.format(
                    dayString +
                        ' [' +
                        (m.hours() % 12 === 1 ? 'στη' : 'στις') +
                        '] LT'
                ),
                'Today - ' + i + ' days current time'
            );
            m.hours(1).minutes(30).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(dayString + ' [στη] LT'),
                'Today - ' + i + ' days one o clock'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(dayString + ' [στις] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(dayString + ' [στις] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52η',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1η',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1η',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2η',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2η',
            'Jan 15 2012 should be week 2'
        );
    });

    test('localeData months calls', function (assert) {
        var jan = moment('2012-01-01');
        assert.equal(
            moment.localeData().months(jan),
            'Ιανουάριος',
            'should return the nominative month name'
        );
        assert.equal(
            moment.localeData().months(jan, 'D MMMM'),
            'Ιανουαρίου',
            'should return the genitive month name'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('en-au');

    test('parse', function (assert) {
        var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Sunday, February 14th 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Sun, 3PM'],
                ['M Mo MM MMMM MMM', '2 2nd 02 February Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14th 14'],
                ['d do dddd ddd dd', '0 0th Sunday Sun Su'],
                ['DDD DDDo DDDD', '45 45th 045'],
                ['w wo ww', '7 7th 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45th day of the year'],
                ['LTS', '3:25:50 PM'],
                ['L', '14/02/2010'],
                ['LL', '14 February 2010'],
                ['LLL', '14 February 2010 3:25 PM'],
                ['LLLL', 'Sunday, 14 February 2010 3:25 PM'],
                ['l', '14/2/2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 3:25 PM'],
                ['llll', 'Sun, 14 Feb 2010 3:25 PM'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');
    });

    test('format month', function (assert) {
        var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'a few seconds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'a minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'a minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'an hour',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'an hour',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 hours',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 hours',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 hours',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'a day',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'a day',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 days',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'a day',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 days',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 days',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'a month',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'a month',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'a month',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 months',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 months',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 months',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'a month',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 months',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'a year',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 years',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'a year',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 years',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in a few seconds', 'prefix');
        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'a few seconds ago',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in a few seconds',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'in 5 days', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Today at 12:00 PM',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Today at 12:25 PM',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Today at 1:00 PM',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Tomorrow at 12:00 PM',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Today at 11:00 AM',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Yesterday at 12:00 PM',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1st',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1st',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2nd',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2nd',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3rd',
            'Jan 15 2012 should be week 3'
        );
    });

    // Concrete test for Locale#weekdaysMin
    test('Weekdays sort by locale', function (assert) {
        assert.deepEqual(
            moment().localeData('en-au').weekdays(),
            'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
            'weekdays start on Sunday'
        );
        assert.deepEqual(
            moment().localeData('en-au').weekdays(true),
            'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
            'locale-sorted weekdays start on Sunday'
        );
        assert.deepEqual(
            moment().localeData('en-au').weekdaysShort(),
            'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
            'weekdaysShort start on Sunday'
        );
        assert.deepEqual(
            moment().localeData('en-au').weekdaysShort(true),
            'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
            'locale-sorted weekdaysShort start on Sunday'
        );
        assert.deepEqual(
            moment().localeData('en-au').weekdaysMin(),
            'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
            'weekdaysMin start on Sunday'
        );
        assert.deepEqual(
            moment().localeData('en-au').weekdaysMin(true),
            'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
            'locale-sorted weekdaysMin start on Sunday'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('en-ca');

    test('parse', function (assert) {
        var i,
            tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Sunday, February 14th 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Sun, 3PM'],
                ['M Mo MM MMMM MMM', '2 2nd 02 February Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14th 14'],
                ['d do dddd ddd dd', '0 0th Sunday Sun Su'],
                ['DDD DDDo DDDD', '45 45th 045'],
                ['w wo ww', '8 8th 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45th day of the year'],
                ['L', '2010-02-14'],
                ['LTS', '3:25:50 PM'],
                ['LL', 'February 14, 2010'],
                ['LLL', 'February 14, 2010 3:25 PM'],
                ['LLLL', 'Sunday, February 14, 2010 3:25 PM'],
                ['l', '2010-2-14'],
                ['ll', 'Feb 14, 2010'],
                ['lll', 'Feb 14, 2010 3:25 PM'],
                ['llll', 'Sun, Feb 14, 2010 3:25 PM'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');
    });

    test('format month', function (assert) {
        var i,
            expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'a few seconds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'a minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'a minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'an hour',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'an hour',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 hours',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 hours',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 hours',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'a day',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'a day',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 days',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'a day',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 days',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 days',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'a month',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'a month',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'a month',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 months',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 months',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 months',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'a month',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 months',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'a year',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 years',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'a year',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 years',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in a few seconds', 'prefix');
        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'a few seconds ago',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in a few seconds',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'in 5 days', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Today at 12:00 PM',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Today at 12:25 PM',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Today at 1:00 PM',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Tomorrow at 12:00 PM',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Today at 11:00 AM',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Yesterday at 12:00 PM',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1st',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1st',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2nd',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2nd',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3rd',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('en-gb');

    test('parse', function (assert) {
        var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Sunday, February 14th 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Sun, 3PM'],
                ['M Mo MM MMMM MMM', '2 2nd 02 February Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14th 14'],
                ['d do dddd ddd dd', '0 0th Sunday Sun Su'],
                ['DDD DDDo DDDD', '45 45th 045'],
                ['w wo ww', '6 6th 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45th day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 February 2010'],
                ['LLL', '14 February 2010 15:25'],
                ['LLLL', 'Sunday, 14 February 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 15:25'],
                ['llll', 'Sun, 14 Feb 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');
    });

    test('format month', function (assert) {
        var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'a few seconds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'a minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'a minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'an hour',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'an hour',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 hours',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 hours',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 hours',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'a day',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'a day',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 days',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'a day',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 days',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 days',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'a month',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'a month',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'a month',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 months',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 months',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 months',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'a month',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 months',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'a year',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 years',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'a year',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 years',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in a few seconds', 'prefix');
        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'a few seconds ago',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in a few seconds',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'in 5 days', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Today at 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Today at 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Today at 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Tomorrow at 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Today at 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Yesterday at 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52nd',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1st',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1st',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2nd',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2nd',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('en-ie');

    test('parse', function (assert) {
        var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Sunday, February 14th 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Sun, 3PM'],
                ['M Mo MM MMMM MMM', '2 2nd 02 February Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14th 14'],
                ['d do dddd ddd dd', '0 0th Sunday Sun Su'],
                ['DDD DDDo DDDD', '45 45th 045'],
                ['w wo ww', '6 6th 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45th day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 February 2010'],
                ['LLL', '14 February 2010 15:25'],
                ['LLLL', 'Sunday 14 February 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 15:25'],
                ['llll', 'Sun 14 Feb 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');
    });

    test('format month', function (assert) {
        var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'a few seconds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'a minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'a minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'an hour',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'an hour',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 hours',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 hours',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 hours',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'a day',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'a day',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 days',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'a day',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 days',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 days',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'a month',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'a month',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'a month',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 months',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 months',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 months',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'a month',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 months',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'a year',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 years',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'a year',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 years',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in a few seconds', 'prefix');
        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'a few seconds ago',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in a few seconds',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'in 5 days', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Today at 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Today at 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Today at 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Tomorrow at 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Today at 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Yesterday at 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52nd',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1st',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1st',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2nd',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2nd',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('en-il');

    test('parse', function (assert) {
        var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Sunday, February 14th 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Sun, 3PM'],
                ['M Mo MM MMMM MMM', '2 2nd 02 February Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14th 14'],
                ['d do dddd ddd dd', '0 0th Sunday Sun Su'],
                ['DDD DDDo DDDD', '45 45th 045'],
                ['w wo ww', '8 8th 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45th day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 February 2010'],
                ['LLL', '14 February 2010 15:25'],
                ['LLLL', 'Sunday, 14 February 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 15:25'],
                ['llll', 'Sun, 14 Feb 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');
    });

    test('format month', function (assert) {
        var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'a few seconds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'a minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'a minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'an hour',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'an hour',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 hours',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 hours',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 hours',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'a day',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'a day',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 days',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'a day',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 days',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 days',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'a month',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'a month',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'a month',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 months',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 months',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 months',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'a month',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 months',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'a year',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 years',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'a year',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 years',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in a few seconds', 'prefix');
        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'a few seconds ago',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in a few seconds',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'in 5 days', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Today at 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Today at 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Today at 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Tomorrow at 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Today at 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Yesterday at 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1st',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1st',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2nd',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2nd',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3rd',
            'Jan 15 2012 should be week 3'
        );
    });

    test('days start on sunday', function (assert) {
        assert.equal(
            moment().startOf('week').format('dddd'),
            'Sunday',
            'First day of the week should be Sunday'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('en-in');

    test('parse', function (assert) {
        var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Sunday, February 14th 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Sun, 3PM'],
                ['M Mo MM MMMM MMM', '2 2nd 02 February Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14th 14'],
                ['d do dddd ddd dd', '0 0th Sunday Sun Su'],
                ['DDD DDDo DDDD', '45 45th 045'],
                ['w wo ww', '8 8th 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45th day of the year'],
                ['LTS', '3:25:50 PM'],
                ['L', '14/02/2010'],
                ['LL', '14 February 2010'],
                ['LLL', '14 February 2010 3:25 PM'],
                ['LLLL', 'Sunday, 14 February 2010 3:25 PM'],
                ['l', '14/2/2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 3:25 PM'],
                ['llll', 'Sun, 14 Feb 2010 3:25 PM'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');
    });

    test('format month', function (assert) {
        var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'a few seconds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'a minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'a minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'an hour',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'an hour',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 hours',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 hours',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 hours',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'a day',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'a day',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 days',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'a day',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 days',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 days',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'a month',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'a month',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'a month',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 months',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 months',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 months',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'a month',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 months',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'a year',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 years',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'a year',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 years',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in a few seconds', 'prefix');
        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'a few seconds ago',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in a few seconds',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'in 5 days', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Today at 12:00 PM',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Today at 12:25 PM',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Today at 1:00 PM',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Tomorrow at 12:00 PM',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Today at 11:00 AM',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Yesterday at 12:00 PM',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1st',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1st',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2nd',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2nd',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3rd',
            'Jan 15 2012 should be week 3'
        );
    });

    // Concrete test for Locale#weekdaysMin
    test('Weekdays sort by locale', function (assert) {
        assert.deepEqual(
            moment().localeData('en-in').weekdays(),
            'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
            'weekdays start on Sunday'
        );
        assert.deepEqual(
            moment().localeData('en-in').weekdays(true),
            'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
            'locale-sorted weekdays start on Sunday'
        );
        assert.deepEqual(
            moment().localeData('en-in').weekdaysShort(),
            'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
            'weekdaysShort start on Sunday'
        );
        assert.deepEqual(
            moment().localeData('en-in').weekdaysShort(true),
            'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
            'locale-sorted weekdaysShort start on Sunday'
        );
        assert.deepEqual(
            moment().localeData('en-in').weekdaysMin(),
            'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
            'weekdaysMin start on Sunday'
        );
        assert.deepEqual(
            moment().localeData('en-in').weekdaysMin(true),
            'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
            'locale-sorted weekdaysMin start on Sunday'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('en-nz');

    test('parse', function (assert) {
        var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Sunday, February 14th 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Sun, 3PM'],
                ['M Mo MM MMMM MMM', '2 2nd 02 February Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14th 14'],
                ['d do dddd ddd dd', '0 0th Sunday Sun Su'],
                ['DDD DDDo DDDD', '45 45th 045'],
                ['w wo ww', '6 6th 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45th day of the year'],
                ['LTS', '3:25:50 PM'],
                ['L', '14/02/2010'],
                ['LL', '14 February 2010'],
                ['LLL', '14 February 2010 3:25 PM'],
                ['LLLL', 'Sunday, 14 February 2010 3:25 PM'],
                ['l', '14/2/2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 3:25 PM'],
                ['llll', 'Sun, 14 Feb 2010 3:25 PM'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');
    });

    test('format month', function (assert) {
        var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'a few seconds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'a minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'a minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'an hour',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'an hour',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 hours',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 hours',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 hours',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'a day',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'a day',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 days',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'a day',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 days',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 days',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'a month',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'a month',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'a month',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 months',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 months',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 months',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'a month',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 months',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'a year',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 years',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'a year',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 years',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in a few seconds', 'prefix');
        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'a few seconds ago',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in a few seconds',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'in 5 days', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Today at 12:00 PM',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Today at 12:25 PM',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Today at 1:00 PM',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Tomorrow at 12:00 PM',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Today at 11:00 AM',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Yesterday at 12:00 PM',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52nd',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1st',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1st',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2nd',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2nd',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('en-sg');

    test('parse', function (assert) {
        var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Sunday, February 14th 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Sun, 3PM'],
                ['M Mo MM MMMM MMM', '2 2nd 02 February Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14th 14'],
                ['d do dddd ddd dd', '0 0th Sunday Sun Su'],
                ['DDD DDDo DDDD', '45 45th 045'],
                ['w wo ww', '6 6th 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45th day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 February 2010'],
                ['LLL', '14 February 2010 15:25'],
                ['LLLL', 'Sunday, 14 February 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 15:25'],
                ['llll', 'Sun, 14 Feb 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');
    });

    test('format month', function (assert) {
        var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'a few seconds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'a minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'a minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'an hour',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'an hour',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 hours',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 hours',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 hours',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'a day',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'a day',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 days',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'a day',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 days',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 days',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'a month',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'a month',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'a month',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 months',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 months',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 months',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'a month',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 months',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'a year',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 years',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'a year',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 years',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in a few seconds', 'prefix');
        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'a few seconds ago',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in a few seconds',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'in 5 days', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Today at 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Today at 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Today at 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Tomorrow at 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Today at 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Yesterday at 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52nd',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1st',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1st',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2nd',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2nd',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('en');

    test('parse', function (assert) {
        var i,
            tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Sunday, February 14th 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Sun, 3PM'],
                ['M Mo MM MMMM MMM', '2 2nd 02 February Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14th 14'],
                ['d do dddd ddd dd', '0 0th Sunday Sun Su'],
                ['DDD DDDo DDDD', '45 45th 045'],
                ['w wo ww', '8 8th 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45th day of the year'],
                ['LTS', '3:25:50 PM'],
                ['L', '02/14/2010'],
                ['LL', 'February 14, 2010'],
                ['LLL', 'February 14, 2010 3:25 PM'],
                ['LLLL', 'Sunday, February 14, 2010 3:25 PM'],
                ['l', '2/14/2010'],
                ['ll', 'Feb 14, 2010'],
                ['lll', 'Feb 14, 2010 3:25 PM'],
                ['llll', 'Sun, Feb 14, 2010 3:25 PM'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('parse era', function (assert) {
        assert.equal(moment('2010 AD', 'y N', true).isValid(), true, '2010 AD');
        assert.equal(moment('2010 AD', 'y N', true).year(), 2010, '2010 AD');

        assert.equal(
            moment('2010 Anno Domini', 'y N', true).isValid(),
            false,
            '2010 Anno Domini'
        );
        assert.equal(
            moment('2010 Anno Domini', 'y N', false).isValid(),
            true,
            '2010 Anno Domini'
        );
        assert.equal(
            moment('2010 Anno Domini', 'y NNNN', true).isValid(),
            true,
            '2010 Anno Domini'
        );
        assert.equal(
            moment('2010 Anno Domini', 'y NNNN', true).year(),
            2010,
            '2010 Anno Domini'
        );
        assert.equal(
            moment('2010 Anno Domini', 'y N', false).year(),
            2010,
            '2010 Anno Domini'
        );

        assert.equal(moment('469 BC', 'y N', true).isValid(), true, '469 BC');
        assert.equal(moment('469 BC', 'y N', true).year(), -468, '469 BC');

        assert.equal(
            moment('469 Before Christ', 'y NNNN', true).isValid(),
            true,
            '469 Before Christ'
        );
        assert.equal(
            moment('469 Before Christ', 'y NNNN', true).year(),
            -468,
            '469 Before Christ'
        );
    });

    test('format era', function (assert) {
        var a = [
                ['+000001-01-01', 'N, NN, NNN', 'AD, AD, AD'],
                ['+000001-01-01', 'NNNN', 'Anno Domini'],
                ['+000001-01-01', 'NNNNN', 'AD'],
                ['+000001-01-01', 'y', '1'],

                ['+000000-12-31', 'N, NN, NNN', 'BC, BC, BC'],
                ['+000000-12-31', 'NNNN', 'Before Christ'],
                ['+000000-12-31', 'NNNNN', 'BC'],
                ['+000000-12-31', 'y', '1'],

                ['-000001-12-31', 'N, NN, NNN', 'BC, BC, BC'],
                ['-000001-12-31', 'NNNN', 'Before Christ'],
                ['-000001-12-31', 'NNNNN', 'BC'],
                ['-000001-12-31', 'y', '2'],
            ],
            i,
            l;

        for (i = 0, l = a.length; i < l; ++i) {
            assert.equal(
                moment(a[i][0]).format(a[i][1]),
                a[i][2],
                a[i][0] + '; ' + a[i][1] + ' ---> ' + a[i][2]
            );
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');
    });

    test('format month', function (assert) {
        var i,
            expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'a few seconds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'a minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'a minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'an hour',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'an hour',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 hours',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 hours',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 hours',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'a day',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'a day',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 days',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'a day',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 days',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 days',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'a month',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'a month',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'a month',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 months',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 months',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 months',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'a month',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 months',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'a year',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 years',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'a year',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 years',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in a few seconds', 'prefix');
        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'a few seconds ago',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in a few seconds',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'in 5 days', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Today at 12:00 PM',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Today at 12:25 PM',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Today at 1:00 PM',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Tomorrow at 12:00 PM',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Today at 11:00 AM',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Yesterday at 12:00 PM',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [at] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Last] dddd [at] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1st',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1st',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2nd',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2nd',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3rd',
            'Jan 15 2012 should be week 3'
        );
    });

    test('weekdays strict parsing', function (assert) {
        var m = moment('2015-01-01T12', moment.ISO_8601, true),
            enLocale = moment.localeData('en'),
            i;

        for (i = 0; i < 7; ++i) {
            assert.equal(
                moment(enLocale.weekdays(m.day(i), ''), 'dddd', true).isValid(),
                true,
                'parse weekday ' + i
            );
            assert.equal(
                moment(enLocale.weekdaysShort(m.day(i), ''), 'ddd', true).isValid(),
                true,
                'parse short weekday ' + i
            );
            assert.equal(
                moment(enLocale.weekdaysMin(m.day(i), ''), 'dd', true).isValid(),
                true,
                'parse min weekday ' + i
            );

            // negative tests
            assert.equal(
                moment(enLocale.weekdaysMin(m.day(i), ''), 'ddd', true).isValid(),
                false,
                'parse short weekday ' + i
            );
            assert.equal(
                moment(enLocale.weekdaysShort(m.day(i), ''), 'dd', true).isValid(),
                false,
                'parse min weekday ' + i
            );
        }
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('eo');

    test('parse', function (assert) {
        var tests = 'januaro jan_februaro feb_marto mart_aprilo apr_majo maj_junio jun_julio jul_aŭgusto aŭg_septembro sept_oktobro okt_novembro nov_decembro dec'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'dimanĉo, februaro 14a 2010, 3:25:50 p.t.m.',
                ],
                ['ddd, hA', 'dim, 3P.T.M.'],
                ['M Mo MM MMMM MMM', '2 2a 02 februaro feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14a 14'],
                ['d do dddd ddd dd', '0 0a dimanĉo dim di'],
                ['DDD DDDo DDDD', '45 45a 045'],
                ['w wo ww', '7 7a 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'p.t.m. P.T.M.'],
                ['[la] DDDo [tago] [de] [la] [jaro]', 'la 45a tago de la jaro'],
                ['LTS', '15:25:50'],
                ['L', '2010-02-14'],
                ['LL', 'la 14-an de februaro, 2010'],
                ['LLL', 'la 14-an de februaro, 2010 15:25'],
                ['LLLL', 'dimanĉon, la 14-an de februaro, 2010 15:25'],
                ['l', '2010-2-14'],
                ['ll', 'la 14-an de feb, 2010'],
                ['lll', 'la 14-an de feb, 2010 15:25'],
                ['llll', 'dim, la 14-an de feb, 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1a', '1a');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2a', '2a');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3a', '3a');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4a', '4a');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5a', '5a');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6a', '6a');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7a', '7a');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8a', '8a');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9a', '9a');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10a', '10a');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11a', '11a');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12a', '12a');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13a', '13a');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14a', '14a');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15a', '15a');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16a', '16a');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17a', '17a');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18a', '18a');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19a', '19a');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20a', '20a');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21a', '21a');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22a', '22a');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23a', '23a');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24a', '24a');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25a', '25a');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26a', '26a');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27a', '27a');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28a', '28a');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29a', '29a');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30a', '30a');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31a', '31a');
    });

    test('format month', function (assert) {
        var expected = 'januaro jan_februaro feb_marto mart_aprilo apr_majo maj_junio jun_julio jul_aŭgusto aŭg_septembro sept_oktobro okt_novembro nov_decembro dec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'dimanĉo dim di_lundo lun lu_mardo mard ma_merkredo merk me_ĵaŭdo ĵaŭ ĵa_vendredo ven ve_sabato sab sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'kelkaj sekundoj',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'unu minuto',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'unu minuto',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutoj',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutoj',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'unu horo',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'unu horo',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 horoj',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 horoj',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 horoj',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'unu tago',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'unu tago',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 tagoj',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'unu tago',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 tagoj',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 tagoj',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'unu monato',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'unu monato',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'unu monato',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 monatoj',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 monatoj',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 monatoj',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'unu monato',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 monatoj',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'unu jaro',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 jaroj',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'unu jaro',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 jaroj',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'post kelkaj sekundoj', 'post prefix');
        assert.equal(
            moment(0).from(30000),
            'antaŭ kelkaj sekundoj',
            'antaŭ prefix'
        );
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'antaŭ kelkaj sekundoj',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'post kelkaj sekundoj',
            'post kelkaj sekundoj'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'post 5 tagoj',
            'post 5 tagoj'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Hodiaŭ je 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Hodiaŭ je 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Hodiaŭ je 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Morgaŭ je 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Hodiaŭ je 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Hieraŭ je 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd[n] [je] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd[n] [je] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd[n] [je] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[pasintan] dddd[n je] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[pasintan] dddd[n je] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[pasintan] dddd[n je] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1a',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1a',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2a',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2a',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3a',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('es-do');

    test('parse', function (assert) {
        var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'domingo, febrero 14º 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dom., 3PM'],
                ['M Mo MM MMMM MMM', '2 2º 02 febrero feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14º 14'],
                ['d do dddd ddd dd', '0 0º domingo dom. do'],
                ['DDD DDDo DDDD', '45 45º 045'],
                ['w wo ww', '6 6º 06'],
                ['YYYY-MMM-DD', '2010-feb-14'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45º day of the year'],
                ['LTS', '3:25:50 PM'],
                ['L', '14/02/2010'],
                ['LL', '14 de febrero de 2010'],
                ['LLL', '14 de febrero de 2010 3:25 PM'],
                ['LLLL', 'domingo, 14 de febrero de 2010 3:25 PM'],
                ['l', '14/2/2010'],
                ['ll', '14 de feb. de 2010'],
                ['lll', '14 de feb. de 2010 3:25 PM'],
                ['llll', 'dom., 14 de feb. de 2010 3:25 PM'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');
    });

    test('format month', function (assert) {
        var expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'domingo dom. do_lunes lun. lu_martes mar. ma_miércoles mié. mi_jueves jue. ju_viernes vie. vi_sábado sáb. sá'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'unos segundos',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'un minuto',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'un minuto',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutos',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutos',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'una hora',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'una hora',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 horas',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 horas',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 horas',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un día',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un día',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 días',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un día',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 días',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 días',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'un mes',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'un mes',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'un mes',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 meses',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 meses',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 meses',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'un mes',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 meses',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un año',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 años',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un año',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 años',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'en unos segundos', 'prefix');
        assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'hace unos segundos',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'en unos segundos',
            'en unos segundos'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'en 5 días', 'en 5 días');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'hoy a las 12:00 PM',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'hoy a las 12:25 PM',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'hoy a las 1:00 PM',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'mañana a las 12:00 PM',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).add({ d: 1, h: -1 }).calendar(),
            'mañana a las 11:00 AM',
            'tomorrow minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'hoy a las 11:00 AM',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ayer a las 12:00 PM',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [a la' + (m.hours() !== 1 ? 's' : '') + '] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [a la' + (m.hours() !== 1 ? 's' : '') + '] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [a la' + (m.hours() !== 1 ? 's' : '') + '] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [pasado a la' + (m.hours() !== 1 ? 's' : '') + '] LT'
                ),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [pasado a la' + (m.hours() !== 1 ? 's' : '') + '] LT'
                ),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [pasado a la' + (m.hours() !== 1 ? 's' : '') + '] LT'
                ),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52º',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1º',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1º',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2º',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2º',
            'Jan 15 2012 should be week 2'
        );
    });

    test('test short months proper', function (assert) {
        var str = '02-ago-2016'; // "02-ago-2016"
        assert.equal(
            moment(str, 'DD-MMM-YYYY').month(),
            7,
            '02-ago-2016 month should be 7'
        );
        assert.equal(
            moment(str, 'DD-MMM-YYYY', true).month(),
            7,
            '02-ago-2016 strict parse month should be 7'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('es-mx');

    test('parse', function (assert) {
        var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'domingo, febrero 14º 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dom., 3PM'],
                ['M Mo MM MMMM MMM', '2 2º 02 febrero feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14º 14'],
                ['d do dddd ddd dd', '0 0º domingo dom. do'],
                ['DDD DDDo DDDD', '45 45º 045'],
                ['w wo ww', '7 7º 07'],
                ['YYYY-MMM-DD', '2010-feb-14'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45º day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 de febrero de 2010'],
                ['LLL', '14 de febrero de 2010 15:25'],
                ['LLLL', 'domingo, 14 de febrero de 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 de feb. de 2010'],
                ['lll', '14 de feb. de 2010 15:25'],
                ['llll', 'dom., 14 de feb. de 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');
    });

    test('format month', function (assert) {
        var expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'domingo dom. do_lunes lun. lu_martes mar. ma_miércoles mié. mi_jueves jue. ju_viernes vie. vi_sábado sáb. sá'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'unos segundos',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'un minuto',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'un minuto',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutos',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutos',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'una hora',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'una hora',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 horas',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 horas',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 horas',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un día',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un día',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 días',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un día',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 días',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 días',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'un mes',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'un mes',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'un mes',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 meses',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 meses',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 meses',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'un mes',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 meses',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un año',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 años',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un año',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 años',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'en unos segundos', 'prefix');
        assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'hace unos segundos',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'en unos segundos',
            'en unos segundos'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'en 5 días', 'en 5 días');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'hoy a las 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'hoy a las 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'hoy a las 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'mañana a las 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).add({ d: 1, h: -1 }).calendar(),
            'mañana a las 11:00',
            'tomorrow minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'hoy a las 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ayer a las 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [a la' + (m.hours() !== 1 ? 's' : '') + '] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [a la' + (m.hours() !== 1 ? 's' : '') + '] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [a la' + (m.hours() !== 1 ? 's' : '') + '] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [pasado a la' + (m.hours() !== 1 ? 's' : '') + '] LT'
                ),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [pasado a la' + (m.hours() !== 1 ? 's' : '') + '] LT'
                ),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [pasado a la' + (m.hours() !== 1 ? 's' : '') + '] LT'
                ),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1º',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1º',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2º',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2º',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3º',
            'Jan 15 2012 should be week 3'
        );
    });

    // Concrete test for Locale#weekdaysMin
    test('Weekdays sort by locale', function (assert) {
        const weekdays = 'domingo_lunes_martes_miércoles_jueves_viernes_sábado',
            weekdaysShort = 'dom._lun._mar._mié._jue._vie._sáb.',
            weekdaysMin = 'do_lu_ma_mi_ju_vi_sá';

        assert.deepEqual(
            moment().localeData().weekdays(),
            weekdays.split('_'),
            'weekdays start on Sunday'
        );
        assert.deepEqual(
            moment().localeData().weekdays(true),
            weekdays.split('_'),
            'locale-sorted weekdays start on Sunday'
        );
        assert.deepEqual(
            moment().localeData().weekdaysShort(),
            weekdaysShort.split('_'),
            'weekdaysShort start on Sunday'
        );
        assert.deepEqual(
            moment().localeData().weekdaysShort(true),
            weekdaysShort.split('_'),
            'locale-sorted weekdaysShort start on Sunday'
        );
        assert.deepEqual(
            moment().localeData().weekdaysMin(),
            weekdaysMin.split('_'),
            'weekdaysMin start on Sunday'
        );
        assert.deepEqual(
            moment().localeData().weekdaysMin(true),
            weekdaysMin.split('_'),
            'locale-sorted weekdaysMin start on Sunday'
        );
    });

    test('test short months proper', function (assert) {
        var str = '02-ago-2016';
        assert.equal(
            moment(str, 'DD-MMM-YYYY').month(),
            '7',
            '02-ago-2016 month should be 7'
        );
    });

    test('translated invalid date', function (assert) {
        assert.equal(
            moment('nonsense', 'DD-MMM-YYYY').format(),
            'Fecha inválida',
            'Invalid date should translate'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('es-us');

    test('parse', function (assert) {
        var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'domingo, febrero 14º 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dom., 3PM'],
                ['M Mo MM MMMM MMM', '2 2º 02 febrero feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14º 14'],
                ['d do dddd ddd dd', '0 0º domingo dom. do'],
                ['DDD DDDo DDDD', '45 45º 045'],
                ['w wo ww', '8 8º 08'],
                ['YYYY-MMM-DD', '2010-feb-14'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45º day of the year'],
                ['LT', '3:25 PM'],
                ['LTS', '3:25:50 PM'],
                ['L', '02/14/2010'],
                ['LL', '14 de febrero de 2010'],
                ['LLL', '14 de febrero de 2010 3:25 PM'],
                ['LLLL', 'domingo, 14 de febrero de 2010 3:25 PM'],
                ['l', '2/14/2010'],
                ['ll', '14 de feb. de 2010'],
                ['lll', '14 de feb. de 2010 3:25 PM'],
                ['llll', 'dom., 14 de feb. de 2010 3:25 PM'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');
    });

    test('format month', function (assert) {
        var i,
            expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'domingo dom. do_lunes lun. lu_martes mar. ma_miércoles mié. mi_jueves jue. ju_viernes vie. vi_sábado sáb. sá'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'unos segundos',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'un minuto',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'un minuto',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutos',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutos',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'una hora',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'una hora',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 horas',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 horas',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 horas',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un día',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un día',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 días',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un día',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 días',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 días',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'un mes',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'un mes',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'un mes',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 meses',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 meses',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 meses',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'un mes',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 meses',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un año',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 años',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un año',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 años',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'en unos segundos', 'prefix');
        assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'hace unos segundos',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'en unos segundos',
            'en unos segundos'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'en 5 días', 'en 5 días');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'hoy a las 12:00 PM',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'hoy a las 12:25 PM',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'hoy a las 1:00 PM',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'mañana a las 12:00 PM',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).add({ d: 1, h: -1 }).calendar(),
            'mañana a las 11:00 AM',
            'tomorrow minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'hoy a las 11:00 AM',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ayer a las 12:00 PM',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [a la' + (m.hours() !== 1 ? 's' : '') + '] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [a la' + (m.hours() !== 1 ? 's' : '') + '] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [a la' + (m.hours() !== 1 ? 's' : '') + '] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [pasado a la' + (m.hours() !== 1 ? 's' : '') + '] LT'
                ),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [pasado a la' + (m.hours() !== 1 ? 's' : '') + '] LT'
                ),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [pasado a la' + (m.hours() !== 1 ? 's' : '') + '] LT'
                ),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1º',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1º',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1º',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2º',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2º',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3º',
            'Jan 15 2012 should be week 3'
        );
    });

    test('test short months proper', function (assert) {
        var str = '02-ago-2016'; // "02-ago-2016"
        assert.equal(
            moment(str, 'DD-MMM-YYYY').month(),
            7,
            '02-ago-2016 month should be 7'
        );
        assert.equal(
            moment(str, 'DD-MMM-YYYY', true).month(),
            7,
            '02-ago-2016 strict parse month should be 7'
        );
    });

    test('test lenient month parsing', function (assert) {
        assert.ok(
            moment('nov 01, 2015', 'MMM D, YYYY', true).isValid(),
            'nov 01, 2015 should parse correctly'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('es');

    test('parse', function (assert) {
        var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'domingo, febrero 14º 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dom., 3PM'],
                ['M Mo MM MMMM MMM', '2 2º 02 febrero feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14º 14'],
                ['d do dddd ddd dd', '0 0º domingo dom. do'],
                ['DDD DDDo DDDD', '45 45º 045'],
                ['w wo ww', '6 6º 06'],
                ['YYYY-MMM-DD', '2010-feb-14'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45º day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 de febrero de 2010'],
                ['LLL', '14 de febrero de 2010 15:25'],
                ['LLLL', 'domingo, 14 de febrero de 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 de feb. de 2010'],
                ['lll', '14 de feb. de 2010 15:25'],
                ['llll', 'dom., 14 de feb. de 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');
    });

    test('format month', function (assert) {
        var expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'domingo dom. do_lunes lun. lu_martes mar. ma_miércoles mié. mi_jueves jue. ju_viernes vie. vi_sábado sáb. sá'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'unos segundos',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'un minuto',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'un minuto',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutos',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutos',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'una hora',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'una hora',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 horas',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 horas',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 horas',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un día',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un día',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 días',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un día',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 días',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 días',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'un mes',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'un mes',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'un mes',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 meses',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 meses',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 meses',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'un mes',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 meses',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un año',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 años',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un año',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 años',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'en unos segundos', 'prefix');
        assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'hace unos segundos',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'en unos segundos',
            'en unos segundos'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'en 5 días', 'en 5 días');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'hoy a las 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'hoy a las 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'hoy a las 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'mañana a las 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).add({ d: 1, h: -1 }).calendar(),
            'mañana a las 11:00',
            'tomorrow minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'hoy a las 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ayer a las 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [a la' + (m.hours() !== 1 ? 's' : '') + '] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [a la' + (m.hours() !== 1 ? 's' : '') + '] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [a la' + (m.hours() !== 1 ? 's' : '') + '] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [pasado a la' + (m.hours() !== 1 ? 's' : '') + '] LT'
                ),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [pasado a la' + (m.hours() !== 1 ? 's' : '') + '] LT'
                ),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(
                    '[el] dddd [pasado a la' + (m.hours() !== 1 ? 's' : '') + '] LT'
                ),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52º',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1º',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1º',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2º',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2º',
            'Jan 15 2012 should be week 2'
        );
    });

    test('test short months proper', function (assert) {
        var str = '02-ago-2016';
        assert.equal(
            moment(str, 'DD-MMM-YYYY').month(),
            '7',
            '02-ago-2016 month should be 7'
        );
    });

    test('translated invalid date', function (assert) {
        assert.equal(
            moment('nonsense', 'DD-MMM-YYYY').format(),
            'Fecha inválida',
            'Invalid date should translate'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('et');

    test('parse', function (assert) {
        var tests = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' peaks olema kuu ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, H:mm:ss',
                    'pühapäev, 14. veebruar 2010, 15:25:50',
                ],
                ['ddd, h', 'P, 3'],
                ['M Mo MM MMMM MMM', '2 2. 02 veebruar veebr'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. pühapäev P P'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[aasta] DDDo [päev]', 'aasta 45. päev'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. veebruar 2010'],
                ['LLL', '14. veebruar 2010 15:25'],
                ['LLLL', 'pühapäev, 14. veebruar 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14. veebr 2010'],
                ['lll', '14. veebr 2010 15:25'],
                ['llll', 'P, 14. veebr 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'pühapäev P P_esmaspäev E E_teisipäev T T_kolmapäev K K_neljapäev N N_reede R R_laupäev L L'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'paar sekundit',
            '44 seconds = paar sekundit'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'üks minut',
            '45 seconds = üks minut'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'üks minut',
            '89 seconds = üks minut'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutit',
            '90 seconds = 2 minutit'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutit',
            '44 minutes = 44 minutit'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'üks tund',
            '45 minutes = tund aega'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'üks tund',
            '89 minutes = üks tund'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 tundi',
            '90 minutes = 2 tundi'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 tundi',
            '5 hours = 5 tundi'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 tundi',
            '21 hours = 21 tundi'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'üks päev',
            '22 hours = üks päev'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'üks päev',
            '35 hours = üks päev'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 päeva',
            '36 hours = 2 päeva'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'üks päev',
            '1 day = üks päev'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 päeva',
            '5 days = 5 päeva'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 päeva',
            '25 days = 25 päeva'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'üks kuu',
            '26 days = üks kuu'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'üks kuu',
            '30 days = üks kuu'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'üks kuu',
            '43 days = üks kuu'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 kuud',
            '46 days = 2 kuud'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 kuud',
            '75 days = 2 kuud'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 kuud',
            '76 days = 3 kuud'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'üks kuu',
            '1 month = üks kuu'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 kuud',
            '5 months = 5 kuud'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'üks aasta',
            '345 days = üks aasta'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 aastat',
            '548 days = 2 aastat'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'üks aasta',
            '1 year = üks aasta'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 aastat',
            '5 years = 5 aastat'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'mõne sekundi pärast', 'prefix');
        assert.equal(moment(0).from(30000), 'mõni sekund tagasi', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'mõni sekund tagasi',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'mõne sekundi pärast',
            'in a few seconds'
        );
        assert.equal(
            moment().subtract({ s: 30 }).fromNow(),
            'mõni sekund tagasi',
            'a few seconds ago'
        );

        assert.equal(
            moment().add({ m: 1 }).fromNow(),
            'ühe minuti pärast',
            'in a minute'
        );
        assert.equal(
            moment().subtract({ m: 1 }).fromNow(),
            'üks minut tagasi',
            'a minute ago'
        );

        assert.equal(
            moment().add({ m: 5 }).fromNow(),
            '5 minuti pärast',
            'in 5 minutes'
        );
        assert.equal(
            moment().subtract({ m: 5 }).fromNow(),
            '5 minutit tagasi',
            '5 minutes ago'
        );

        assert.equal(
            moment().add({ d: 1 }).fromNow(),
            'ühe päeva pärast',
            'in one day'
        );
        assert.equal(
            moment().subtract({ d: 1 }).fromNow(),
            'üks päev tagasi',
            'one day ago'
        );

        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            '5 päeva pärast',
            'in 5 days'
        );
        assert.equal(
            moment().subtract({ d: 5 }).fromNow(),
            '5 päeva tagasi',
            '5 days ago'
        );

        assert.equal(
            moment().add({ M: 1 }).fromNow(),
            'kuu aja pärast',
            'in a month'
        );
        assert.equal(
            moment().subtract({ M: 1 }).fromNow(),
            'kuu aega tagasi',
            'a month ago'
        );

        assert.equal(
            moment().add({ M: 5 }).fromNow(),
            '5 kuu pärast',
            'in 5 months'
        );
        assert.equal(
            moment().subtract({ M: 5 }).fromNow(),
            '5 kuud tagasi',
            '5 months ago'
        );

        assert.equal(
            moment().add({ y: 1 }).fromNow(),
            'ühe aasta pärast',
            'in a year'
        );
        assert.equal(
            moment().subtract({ y: 1 }).fromNow(),
            'aasta tagasi',
            'a year ago'
        );

        assert.equal(
            moment().add({ y: 5 }).fromNow(),
            '5 aasta pärast',
            'in 5 years'
        );
        assert.equal(
            moment().subtract({ y: 5 }).fromNow(),
            '5 aastat tagasi',
            '5 years ago'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), 'Täna, 12:00', 'today at the same time');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Täna, 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Täna, 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Homme, 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Täna, 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Eile, 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Järgmine] dddd LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Järgmine] dddd LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Järgmine] dddd LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Eelmine] dddd LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Eelmine] dddd LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Eelmine] dddd LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 nädal tagasi');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            '1 nädala pärast'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 nädalat tagasi');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            '2 nädala pärast'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('eu');

    test('parse', function (assert) {
        var tests = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'igandea, otsaila 14. 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'ig., 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 otsaila ots.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. igandea ig. ig'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '7 7. 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '2010-02-14'],
                ['LL', '2010ko otsailaren 14a'],
                ['LLL', '2010ko otsailaren 14a 15:25'],
                ['LLLL', 'igandea, 2010ko otsailaren 14a 15:25'],
                ['l', '2010-2-14'],
                ['ll', '2010ko ots. 14a'],
                ['lll', '2010ko ots. 14a 15:25'],
                ['llll', 'ig., 2010ko ots. 14a 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'igandea ig. ig_astelehena al. al_asteartea ar. ar_asteazkena az. az_osteguna og. og_ostirala ol. ol_larunbata lr. lr'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'segundo batzuk',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'minutu bat',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'minutu bat',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutu',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutu',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ordu bat',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ordu bat',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ordu',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ordu',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ordu',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'egun bat',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'egun bat',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 egun',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'egun bat',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 egun',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 egun',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'hilabete bat',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'hilabete bat',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'hilabete bat',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 hilabete',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 hilabete',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 hilabete',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'hilabete bat',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 hilabete',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'urte bat',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 urte',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'urte bat',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 urte',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'segundo batzuk barru', 'prefix');
        assert.equal(moment(0).from(30000), 'duela segundo batzuk', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'duela segundo batzuk',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'segundo batzuk barru',
            'in seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 egun barru', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'gaur 12:00etan',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'gaur 12:25etan',
            'now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'gaur 13:00etan',
            'now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'bihar 12:00etan',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'gaur 11:00etan',
            'now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'atzo 12:00etan',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd LT[etan]'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd LT[etan]'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd LT[etan]'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[aurreko] dddd LT[etan]'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[aurreko] dddd LT[etan]'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[aurreko] dddd LT[etan]'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1.',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1.',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2.',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2.',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3.',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('fa');

    test('parse', function (assert) {
        var tests = 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input +
                    ' should be month ' +
                    (i + 1) +
                    ' instead is month ' +
                    moment(input, mmm).month()
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            equalTest(tests[i], 'MMM', i);
            equalTest(tests[i], 'MMMM', i);
            equalTest(tests[i].toLocaleLowerCase(), 'MMM', i);
            equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i].toLocaleUpperCase(), 'MMM', i);
            equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i], 'MMM', i);
            equalTestStrict(tests[i], 'MMMM', i);
            equalTestStrict(tests[i].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'یک\u200cشنبه، فوریه ۱۴م ۲۰۱۰، ۳:۲۵:۵۰ بعد از ظهر',
                ],
                ['ddd, hA', 'یک\u200cشنبه، ۳بعد از ظهر'],
                ['M Mo MM MMMM MMM', '۲ ۲م ۰۲ فوریه فوریه'],
                ['YYYY YY', '۲۰۱۰ ۱۰'],
                ['D Do DD', '۱۴ ۱۴م ۱۴'],
                ['d do dddd ddd dd', '۰ ۰م یک\u200cشنبه یک\u200cشنبه ی'],
                ['DDD DDDo DDDD', '۴۵ ۴۵م ۰۴۵'],
                ['w wo ww', '۸ ۸م ۰۸'],
                ['h hh', '۳ ۰۳'],
                ['H HH', '۱۵ ۱۵'],
                ['m mm', '۲۵ ۲۵'],
                ['s ss', '۵۰ ۵۰'],
                ['a A', 'بعد از ظهر بعد از ظهر'],
                ['DDDo [روز سال]', '۴۵م روز سال'],
                ['LTS', '۱۵:۲۵:۵۰'],
                ['L', '۱۴/۰۲/۲۰۱۰'],
                ['LL', '۱۴ فوریه ۲۰۱۰'],
                ['LLL', '۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],
                ['LLLL', 'یک\u200cشنبه، ۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],
                ['l', '۱۴/۲/۲۰۱۰'],
                ['ll', '۱۴ فوریه ۲۰۱۰'],
                ['lll', '۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],
                ['llll', 'یک\u200cشنبه، ۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '۱م', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '۲م', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '۳م', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '۴م', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '۵م', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '۶م', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '۷م', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '۸م', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '۹م', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '۱۰م', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '۱۱م', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '۱۲م', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '۱۳م', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '۱۴م', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '۱۵م', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '۱۶م', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '۱۷م', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '۱۸م', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '۱۹م', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '۲۰م', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '۲۱م', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '۲۲م', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '۲۳م', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '۲۴م', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '۲۵م', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '۲۶م', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '۲۷م', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '۲۸م', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '۲۹م', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '۳۰م', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '۳۱م', '31');
    });

    test('format month', function (assert) {
        var expected = 'ژانویه ژانویه_فوریه فوریه_مارس مارس_آوریل آوریل_مه مه_ژوئن ژوئن_ژوئیه ژوئیه_اوت اوت_سپتامبر سپتامبر_اکتبر اکتبر_نوامبر نوامبر_دسامبر دسامبر'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'یک\u200cشنبه یک\u200cشنبه ی_دوشنبه دوشنبه د_سه\u200cشنبه سه\u200cشنبه س_چهارشنبه چهارشنبه چ_پنج\u200cشنبه پنج\u200cشنبه پ_جمعه جمعه ج_شنبه شنبه ش'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]),
            s,
            ss;
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'چند ثانیه',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'یک دقیقه',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'یک دقیقه',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '۲ دقیقه',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '۴۴ دقیقه',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'یک ساعت',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'یک ساعت',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '۲ ساعت',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '۵ ساعت',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '۲۱ ساعت',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'یک روز',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'یک روز',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '۲ روز',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'یک روز',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '۵ روز',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '۲۵ روز',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'یک ماه',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'یک ماه',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'یک ماه',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '۲ ماه',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '۲ ماه',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '۳ ماه',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'یک ماه',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '۵ ماه',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'یک سال',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '۲ سال',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'یک سال',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '۵ سال',
            '5 years = 5 years'
        );

        s = moment.relativeTimeThreshold('s');
        ss = moment.relativeTimeThreshold('ss');

        moment.relativeTimeThreshold('s', 60);
        moment.relativeTimeThreshold('ss', 0);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            '۴۴ ثانیه',
            '44 seconds = 44 seconds'
        );
        moment.relativeTimeThreshold('s', s);
        moment.relativeTimeThreshold('ss', ss);
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'در چند ثانیه', 'prefix');
        assert.equal(moment(0).from(30000), 'چند ثانیه پیش', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'چند ثانیه پیش',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'در چند ثانیه',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'در ۵ روز', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'امروز ساعت ۱۲:۰۰',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'امروز ساعت ۱۲:۲۵',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'امروز ساعت ۱۳:۰۰',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'فردا ساعت ۱۲:۰۰',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'امروز ساعت ۱۱:۰۰',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'دیروز ساعت ۱۲:۰۰',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [ساعت] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [ساعت] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [ساعت] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [پیش ساعت] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [پیش ساعت] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [پیش ساعت] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 31]).format('w ww wo'),
            '۱ ۰۱ ۱م',
            'Dec 31 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 6]).format('w ww wo'),
            '۱ ۰۱ ۱م',
            'Jan  6 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '۲ ۰۲ ۲م',
            'Jan  7 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 13]).format('w ww wo'),
            '۲ ۰۲ ۲م',
            'Jan 13 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '۳ ۰۳ ۳م',
            'Jan 14 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('fi');

    test('parse', function (assert) {
        var tests = 'tammikuu tammi_helmikuu helmi_maaliskuu maalis_huhtikuu huhti_toukokuu touko_kesäkuu kesä_heinäkuu heinä_elokuu elo_syyskuu syys_lokakuu loka_marraskuu marras_joulukuu joulu'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'sunnuntai, helmikuu 14. 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'su, 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 helmikuu helmi'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. sunnuntai su su'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[vuoden] DDDo [päivä]', 'vuoden 45. päivä'],
                ['LTS', '15.25.50'],
                ['L', '14.02.2010'],
                ['LL', '14. helmikuuta 2010'],
                ['LLL', '14. helmikuuta 2010, klo 15.25'],
                ['LLLL', 'sunnuntai, 14. helmikuuta 2010, klo 15.25'],
                ['l', '14.2.2010'],
                ['ll', '14. helmi 2010'],
                ['lll', '14. helmi 2010, klo 15.25'],
                ['llll', 'su, 14. helmi 2010, klo 15.25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31st');
    });

    test('format month', function (assert) {
        var expected = 'tammikuu tammi_helmikuu helmi_maaliskuu maalis_huhtikuu huhti_toukokuu touko_kesäkuu kesä_heinäkuu heinä_elokuu elo_syyskuu syys_lokakuu loka_marraskuu marras_joulukuu joulu'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'sunnuntai su su_maanantai ma ma_tiistai ti ti_keskiviikko ke ke_torstai to to_perjantai pe pe_lauantai la la'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'muutama sekunti',
            '44 seconds = few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'minuutti',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'minuutti',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            'kaksi minuuttia',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuuttia',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'tunti',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'tunti',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            'kaksi tuntia',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            'viisi tuntia',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 tuntia',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'päivä',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'päivä',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            'kaksi päivää',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'päivä',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            'viisi päivää',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 päivää',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'kuukausi',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'kuukausi',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'kuukausi',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            'kaksi kuukautta',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            'kaksi kuukautta',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            'kolme kuukautta',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'kuukausi',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            'viisi kuukautta',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'vuosi',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            'kaksi vuotta',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'vuosi',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            'viisi vuotta',
            '5 years = 5 years'
        );
    });

    test('from ss threshold set', function (assert) {
        var start = moment([2007, 1, 28]),
            s = moment.relativeTimeThreshold('s'),
            ss = moment.relativeTimeThreshold('ss');
        moment.relativeTimeThreshold('s', 45);
        moment.relativeTimeThreshold('ss', 10);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 10 }), true),
            'muutama sekunti',
            '10 seconds = few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 11 }), true),
            '11 sekuntia',
            '11 seconds = 11 seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            '44 sekuntia',
            '44 seconds = 44 seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'minuutti',
            '45 seconds = a minute'
        );
        moment.relativeTimeThreshold('s', s);
        moment.relativeTimeThreshold('ss', ss);
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'muutaman sekunnin päästä', 'prefix');
        assert.equal(moment(0).from(30000), 'muutama sekunti sitten', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'muutama sekunti sitten',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'muutaman sekunnin päästä',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'viiden päivän päästä',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'tänään klo 12.00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'tänään klo 12.25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'tänään klo 13.00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'huomenna klo 12.00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'tänään klo 11.00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'eilen klo 12.00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [klo] LT'),
                'today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [klo] LT'),
                'today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [klo] LT'),
                'today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[viime] dddd[na] [klo] LT'),
                'today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[viime] dddd[na] [klo] LT'),
                'today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[viime] dddd[na] [klo] LT'),
                'today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(
            weeksAgo.calendar(),
            weeksAgo.format('L'),
            'yksi viikko sitten'
        );
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'yhden viikon päästä'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(
            weeksAgo.calendar(),
            weeksAgo.format('L'),
            'kaksi viikkoa sitten'
        );
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'kaden viikon päästä'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('fil');

    test('parse', function (assert) {
        var tests = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Linggo, Pebrero 14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Lin, 3PM'],
                ['M Mo MM MMMM MMM', '2 2 02 Pebrero Peb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Linggo Lin Li'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '6 6 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LTS', '15:25:50'],
                ['L', '02/14/2010'],
                ['LL', 'Pebrero 14, 2010'],
                ['LLL', 'Pebrero 14, 2010 15:25'],
                ['LLLL', 'Linggo, Pebrero 14, 2010 15:25'],
                ['l', '2/14/2010'],
                ['ll', 'Peb 14, 2010'],
                ['lll', 'Peb 14, 2010 15:25'],
                ['llll', 'Lin, Peb 14, 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Linggo Lin Li_Lunes Lun Lu_Martes Mar Ma_Miyerkules Miy Mi_Huwebes Huw Hu_Biyernes Biy Bi_Sabado Sab Sab'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ilang segundo',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'isang minuto',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'isang minuto',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuto',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuto',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'isang oras',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'isang oras',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 oras',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 oras',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 oras',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'isang araw',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'isang araw',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 araw',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'isang araw',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 araw',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 araw',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'isang buwan',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'isang buwan',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'isang buwan',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 buwan',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 buwan',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 buwan',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'isang buwan',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 buwan',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'isang taon',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 taon',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'isang taon',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 taon',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'sa loob ng ilang segundo', 'prefix');
        assert.equal(
            moment(0).from(30000),
            'ilang segundo ang nakalipas',
            'suffix'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'sa loob ng ilang segundo',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'sa loob ng 5 araw',
            'in 5 days'
        );
    });

    test('same day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            '12:00 ngayong araw',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            '12:25 ngayong araw',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            '13:00 ngayong araw',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Bukas ng 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            '11:00 ngayong araw',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            '12:00 kahapon',
            'yesterday at the same time'
        );
    });

    test('same next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('LT [sa susunod na] dddd'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('LT [sa susunod na] dddd'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('LT [sa susunod na] dddd'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('same last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('LT [noong nakaraang] dddd'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('LT [noong nakaraang] dddd'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('LT [noong nakaraang] dddd'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('same all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('fo');

    test('parse', function (assert) {
        var tests = 'januar jan_februar feb_mars mar_apríl apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd [tann] Do MMMM YYYY, h:mm:ss a',
                    'sunnudagur tann 14. februar 2010, 3:25:50 pm',
                ],
                ['ddd hA', 'sun 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 februar feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. sunnudagur sun su'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[tann] DDDo [dagin á árinum]', 'tann 45. dagin á árinum'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 februar 2010'],
                ['LLL', '14 februar 2010 15:25'],
                ['LLLL', 'sunnudagur 14. februar, 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 feb 2010'],
                ['lll', '14 feb 2010 15:25'],
                ['llll', 'sun 14. feb, 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'januar jan_februar feb_mars mar_apríl apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'sunnudagur sun su_mánadagur mán má_týsdagur týs tý_mikudagur mik mi_hósdagur hós hó_fríggjadagur frí fr_leygardagur ley le'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'fá sekund',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ein minuttur',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ein minuttur',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuttir',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuttir',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ein tími',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ein tími',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 tímar',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 tímar',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 tímar',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ein dagur',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ein dagur',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dagar',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ein dagur',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dagar',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dagar',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ein mánaður',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ein mánaður',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ein mánaður',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mánaðir',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mánaðir',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mánaðir',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ein mánaður',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mánaðir',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'eitt ár',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ár',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'eitt ár',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ár',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'um fá sekund', 'prefix');
        assert.equal(moment(0).from(30000), 'fá sekund síðani', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'fá sekund síðani',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'um fá sekund',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'um 5 dagar', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Í dag kl. 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Í dag kl. 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Í dag kl. 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Í morgin kl. 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Í dag kl. 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Í gjár kl. 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [kl.] LT'),
                'today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [kl.] LT'),
                'today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [kl.] LT'),
                'today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[síðstu] dddd [kl] LT'),
                'today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[síðstu] dddd [kl] LT'),
                'today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[síðstu] dddd [kl] LT'),
                'today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(
            weeksAgo.calendar(),
            weeksAgo.format('L'),
            'yksi viikko sitten'
        );
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'yhden viikon päästä'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(
            weeksAgo.calendar(),
            weeksAgo.format('L'),
            'kaksi viikkoa sitten'
        );
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'kaden viikon päästä'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('fr-ca');

    test('parse', function (assert) {
        var i,
            tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'dimanche, février 14e 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dim., 3PM'],
                ['M Mo MM MMMM MMM', '2 2e 02 février févr.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14e 14'],
                ['d do dddd ddd dd', '0 0e dimanche dim. di'],
                ['DDD DDDo DDDD', '45 45e 045'],
                ['w wo ww', '8 8e 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[le] Do [jour du mois]', 'le 14e jour du mois'],
                ['[le] DDDo [jour de l’année]', 'le 45e jour de l’année'],
                ['LTS', '15:25:50'],
                ['L', '2010-02-14'],
                ['LL', '14 février 2010'],
                ['LLL', '14 février 2010 15:25'],
                ['LLLL', 'dimanche 14 février 2010 15:25'],
                ['l', '2010-2-14'],
                ['ll', '14 févr. 2010'],
                ['lll', '14 févr. 2010 15:25'],
                ['llll', 'dim. 14 févr. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2017, 0, 1]).format('Mo'), '1er', '1er');
        assert.equal(moment([2017, 1, 1]).format('Mo'), '2e', '2e');

        assert.equal(moment([2017, 0, 1]).format('Qo'), '1er', '1er');
        assert.equal(moment([2017, 3, 1]).format('Qo'), '2e', '2e');

        assert.equal(moment([2017, 0, 1]).format('Do'), '1er', '1er');
        assert.equal(moment([2017, 0, 2]).format('Do'), '2e', '2e');

        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1er', '1er');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2e', '2e');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3e', '3e');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4e', '4e');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5e', '5e');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6e', '6e');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7e', '7e');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8e', '8e');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9e', '9e');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10e', '10e');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11e', '11e');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12e', '12e');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13e', '13e');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14e', '14e');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15e', '15e');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16e', '16e');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17e', '17e');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18e', '18e');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19e', '19e');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20e', '20e');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21e', '21e');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22e', '22e');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23e', '23e');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24e', '24e');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25e', '25e');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26e', '26e');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27e', '27e');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28e', '28e');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29e', '29e');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30e', '30e');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31e', '31e');

        assert.equal(moment([2017, 0, 1]).format('do'), '0e', '0e');
        assert.equal(moment([2017, 0, 2]).format('do'), '1er', '1er');

        assert.equal(moment([2017, 0, 4]).format('wo Wo'), '1re 1re', '1re 1re');
        assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e', '2e 2e');
    });

    test('format month', function (assert) {
        var i,
            expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'dimanche dim. di_lundi lun. lu_mardi mar. ma_mercredi mer. me_jeudi jeu. je_vendredi ven. ve_samedi sam. sa'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'quelques secondes',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'une minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'une minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'une heure',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'une heure',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 heures',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 heures',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 heures',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un jour',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un jour',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 jours',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un jour',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 jours',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 jours',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'un mois',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'un mois',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'un mois',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mois',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mois',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mois',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'un mois',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mois',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un an',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ans',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un an',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ans',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'dans quelques secondes', 'prefix');
        assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'dans quelques secondes',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'dans 5 jours', 'in 5 days');
    });

    test('same day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Aujourd’hui à 12:00',
            'Today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Aujourd’hui à 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Aujourd’hui à 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Demain à 12:00',
            'Tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Aujourd’hui à 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Hier à 12:00',
            'Yesterday at the same time'
        );
    });

    test('same next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [à] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [à] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [à] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('same last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [dernier à] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [dernier à] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [dernier à] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('same all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1re',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1re',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2e',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2e',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3e',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('fr-ch');

    test('parse', function (assert) {
        var i,
            tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'dimanche, février 14e 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dim., 3PM'],
                ['M Mo MM MMMM MMM', '2 2e 02 février févr.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14e 14'],
                ['d do dddd ddd dd', '0 0e dimanche dim. di'],
                ['DDD DDDo DDDD', '45 45e 045'],
                ['w wo ww', '6 6e 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[le] Do [jour du mois]', 'le 14e jour du mois'],
                ['[le] DDDo [jour de l’année]', 'le 45e jour de l’année'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 février 2010'],
                ['LLL', '14 février 2010 15:25'],
                ['LLLL', 'dimanche 14 février 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 févr. 2010'],
                ['lll', '14 févr. 2010 15:25'],
                ['llll', 'dim. 14 févr. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2017, 0, 1]).format('Mo'), '1er', '1er');
        assert.equal(moment([2017, 1, 1]).format('Mo'), '2e', '2e');

        assert.equal(moment([2017, 0, 1]).format('Qo'), '1er', '1er');
        assert.equal(moment([2017, 3, 1]).format('Qo'), '2e', '2e');

        assert.equal(moment([2017, 0, 1]).format('Do'), '1er', '1er');
        assert.equal(moment([2017, 0, 2]).format('Do'), '2e', '2e');

        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1er', '1er');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2e', '2e');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3e', '3e');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4e', '4e');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5e', '5e');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6e', '6e');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7e', '7e');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8e', '8e');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9e', '9e');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10e', '10e');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11e', '11e');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12e', '12e');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13e', '13e');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14e', '14e');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15e', '15e');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16e', '16e');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17e', '17e');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18e', '18e');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19e', '19e');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20e', '20e');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21e', '21e');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22e', '22e');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23e', '23e');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24e', '24e');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25e', '25e');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26e', '26e');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27e', '27e');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28e', '28e');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29e', '29e');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30e', '30e');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31e', '31e');

        assert.equal(moment([2017, 0, 1]).format('do'), '0e', '0e');
        assert.equal(moment([2017, 0, 2]).format('do'), '1er', '1er');

        assert.equal(moment([2017, 0, 4]).format('wo Wo'), '1re 1re', '1re 1re');
        assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e', '2e 2e');
    });

    test('format month', function (assert) {
        var i,
            expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'dimanche dim. di_lundi lun. lu_mardi mar. ma_mercredi mer. me_jeudi jeu. je_vendredi ven. ve_samedi sam. sa'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'quelques secondes',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'une minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'une minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'une heure',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'une heure',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 heures',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 heures',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 heures',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un jour',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un jour',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 jours',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un jour',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 jours',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 jours',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'un mois',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'un mois',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'un mois',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mois',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mois',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mois',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'un mois',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mois',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un an',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ans',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un an',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ans',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'dans quelques secondes', 'prefix');
        assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'dans quelques secondes',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'dans 5 jours', 'in 5 days');
    });

    test('same day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Aujourd’hui à 12:00',
            'Today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Aujourd’hui à 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Aujourd’hui à 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Demain à 12:00',
            'Tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Aujourd’hui à 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Hier à 12:00',
            'Yesterday at the same time'
        );
    });

    test('same next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [à] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [à] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [à] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('same last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [dernier à] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [dernier à] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [dernier à] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('same all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52e',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1re',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1re',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2e',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2e',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('fr');

    test('parse', function (assert) {
        var i,
            tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split(
                '_'
            ),
            testsNoDot = 'janvier janv_février févr_mars mars_avril avr_mai mai_juin juin_juillet juil_août août_septembre sept_octobre oct_novembre nov_décembre déc'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }

        for (i = 0; i < 12; i++) {
            testsNoDot[i] = testsNoDot[i].split(' ');
            equalTest(testsNoDot[i][0], 'MMM', i);
            equalTest(testsNoDot[i][1], 'MMM', i);
            equalTest(testsNoDot[i][0], 'MMMM', i);
            equalTest(testsNoDot[i][1], 'MMMM', i);
            equalTest(testsNoDot[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(testsNoDot[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(testsNoDot[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(testsNoDot[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(testsNoDot[i][1], 'MMM', i);
            equalTestStrict(testsNoDot[i][0], 'MMMM', i);
            equalTestStrict(testsNoDot[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(testsNoDot[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(testsNoDot[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(testsNoDot[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'dimanche, février 14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dim., 3PM'],
                ['M Mo MM MMMM MMM', '2 2e 02 février févr.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0e dimanche dim. di'],
                ['DDD DDDo DDDD', '45 45e 045'],
                ['w wo ww', '6 6e 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[le] Do [jour du mois]', 'le 14 jour du mois'],
                ['[le] DDDo [jour de l’année]', 'le 45e jour de l’année'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 février 2010'],
                ['LLL', '14 février 2010 15:25'],
                ['LLLL', 'dimanche 14 février 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 févr. 2010'],
                ['lll', '14 févr. 2010 15:25'],
                ['llll', 'dim. 14 févr. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2017, 0, 1]).format('Mo'), '1er', '1er');
        assert.equal(moment([2017, 1, 1]).format('Mo'), '2e', '2e');

        assert.equal(moment([2017, 0, 1]).format('Qo'), '1er', '1er');
        assert.equal(moment([2017, 3, 1]).format('Qo'), '2e', '2e');

        assert.equal(moment([2017, 0, 1]).format('Do'), '1er', '1er');
        assert.equal(moment([2017, 0, 2]).format('Do'), '2', '2');

        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1er', '1er');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2e', '2e');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3e', '3e');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4e', '4e');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5e', '5e');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6e', '6e');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7e', '7e');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8e', '8e');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9e', '9e');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10e', '10e');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11e', '11e');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12e', '12e');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13e', '13e');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14e', '14e');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15e', '15e');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16e', '16e');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17e', '17e');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18e', '18e');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19e', '19e');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20e', '20e');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21e', '21e');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22e', '22e');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23e', '23e');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24e', '24e');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25e', '25e');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26e', '26e');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27e', '27e');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28e', '28e');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29e', '29e');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30e', '30e');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31e', '31e');

        assert.equal(moment([2017, 0, 1]).format('do'), '0e', '0e');
        assert.equal(moment([2017, 0, 2]).format('do'), '1er', '1er');

        assert.equal(moment([2017, 0, 4]).format('wo Wo'), '1re 1re', '1re 1re');
        assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e', '2e 2e');
    });

    test('format month', function (assert) {
        var i,
            expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'dimanche dim. di_lundi lun. lu_mardi mar. ma_mercredi mer. me_jeudi jeu. je_vendredi ven. ve_samedi sam. sa'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'quelques secondes',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'une minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'une minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'une heure',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'une heure',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 heures',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 heures',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 heures',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un jour',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un jour',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 jours',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un jour',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 jours',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 jours',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'un mois',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'un mois',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'un mois',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mois',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mois',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mois',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'un mois',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mois',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un an',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ans',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un an',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ans',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'dans quelques secondes', 'prefix');
        assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'dans quelques secondes',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'dans 5 jours', 'in 5 days');
    });

    test('same day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Aujourd’hui à 12:00',
            'Today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Aujourd’hui à 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Aujourd’hui à 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Demain à 12:00',
            'Tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Aujourd’hui à 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Hier à 12:00',
            'Yesterday at the same time'
        );
    });

    test('same next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [à] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [à] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [à] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('same last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [dernier à] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [dernier à] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [dernier à] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('same all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52e',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1re',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1re',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2e',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2e',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('fy');

    test('parse', function (assert) {
        var tests = 'jannewaris jan._febrewaris feb._maart mrt._april apr._maaie mai._juny jun._july jul._augustus aug._septimber sep._oktober okt._novimber nov._desimber des.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            // Fails only for month 5 (index 4)
            // equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            // Fails only for month 5 (index 4)
            // equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            // Fails only for month 5 (index 4)
            // equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, HH:mm:ss',
                    'snein, febrewaris 14de 2010, 15:25:50',
                ],
                ['ddd, HH', 'si., 15'],
                ['M Mo MM MMMM MMM', '2 2de 02 febrewaris feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14de 14'],
                ['d do dddd ddd dd', '0 0de snein si. Si'],
                ['DDD DDDo DDDD', '45 45ste 045'],
                ['w wo ww', '6 6de 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45ste day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14-02-2010'],
                ['LL', '14 febrewaris 2010'],
                ['LLL', '14 febrewaris 2010 15:25'],
                ['LLLL', 'snein 14 febrewaris 2010 15:25'],
                ['l', '14-2-2010'],
                ['ll', '14 feb. 2010'],
                ['lll', '14 feb. 2010 15:25'],
                ['llll', 'si. 14 feb. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');
    });

    test('format month', function (assert) {
        var expected = 'jannewaris jan._febrewaris feb._maart mrt._april apr._maaie mai_juny jun._july jul._augustus aug._septimber sep._oktober okt._novimber nov._desimber des.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'snein si. Si_moandei mo. Mo_tiisdei ti. Ti_woansdei wo. Wo_tongersdei to. To_freed fr. Fr_sneon so. So'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'in pear sekonden',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ien minút',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ien minút',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuten',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuten',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ien oere',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ien oere',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 oeren',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 oeren',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 oeren',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ien dei',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ien dei',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dagen',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ien dei',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dagen',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dagen',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ien moanne',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ien moanne',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ien moanne',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 moannen',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 moannen',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 moannen',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ien moanne',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 moannen',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ien jier',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 jierren',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ien jier',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 jierren',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'oer in pear sekonden', 'prefix');
        assert.equal(moment(0).from(30000), 'in pear sekonden lyn', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'in pear sekonden lyn',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'oer in pear sekonden',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'oer 5 dagen', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'hjoed om 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'hjoed om 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'hjoed om 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'moarn om 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'hjoed om 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'juster om 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [om] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [om] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [om] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[ôfrûne] dddd [om] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[ôfrûne] dddd [om] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[ôfrûne] dddd [om] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('month abbreviation', function (assert) {
        assert.equal(
            moment([2012, 5, 23]).format('D-MMM-YYYY'),
            '23-jun-2012',
            'format month abbreviation surrounded by dashes should not include a dot'
        );
        assert.equal(
            moment([2012, 5, 23]).format('D MMM YYYY'),
            '23 jun. 2012',
            'format month abbreviation not surrounded by dashes should include a dot'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52ste',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1ste',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1ste',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2de',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2de',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ga');

    var months = [
        'Eanáir,Ean',
        'Feabhra,Feabh',
        'Márta,Márt',
        'Aibreán,Aib',
        'Bealtaine,Beal',
        'Meitheamh,Meith',
        'Iúil,Iúil',
        'Lúnasa,Lún',
        'Meán Fómhair,M.F.',
        'Deireadh Fómhair,D.F.',
        'Samhain,Samh',
        'Nollaig,Noll',
    ];

    test('parse', function (assert) {
        function equalTest(monthName, monthFormat, monthNum) {
            assert.equal(
                moment(monthName, monthFormat).month(),
                monthNum,
                monthName + ' should be month ' + (monthNum + 1)
            );
        }

        var i, testMonth;
        for (i = 0; i < 12; i++) {
            testMonth = months[i].split(',');

            equalTest(testMonth[0], 'MMM', i);
            equalTest(testMonth[1], 'MMM', i);
            equalTest(testMonth[0], 'MMMM', i);
            equalTest(testMonth[1], 'MMMM', i);
            equalTest(testMonth[0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(testMonth[1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(testMonth[0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(testMonth[1].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Dé Domhnaigh, Feabhra 14mh 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Domh, 3PM'],
                ['M Mo MM MMMM MMM', '2 2na 02 Feabhra Feabh'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14mh 14'],
                ['d do dddd ddd dd', '0 0mh Dé Domhnaigh Domh Do'],
                ['DDD DDDo DDDD', '45 45mh 045'],
                ['w wo ww', '6 6mh 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[an] DDDo [latha den bhliadhna]', 'an 45mh latha den bhliadhna'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 Feabhra 2010'],
                ['LLL', '14 Feabhra 2010 15:25'],
                ['LLLL', 'Dé Domhnaigh, 14 Feabhra 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Feabh 2010'],
                ['lll', '14 Feabh 2010 15:25'],
                ['llll', 'Domh, 14 Feabh 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1d', '1d');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2na', '2na');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3mh', '3mh');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4mh', '4mh');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5mh', '5mh');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6mh', '6mh');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7mh', '7mh');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8mh', '8mh');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9mh', '9mh');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10mh', '10mh');
        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11mh', '11mh');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12na', '12na');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13mh', '13mh');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14mh', '14mh');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15mh', '15mh');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16mh', '16mh');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17mh', '17mh');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18mh', '18mh');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19mh', '19mh');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20mh', '20mh');
        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21mh', '21mh');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22na', '22na');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23mh', '23mh');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24mh', '24mh');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25mh', '25mh');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26mh', '26mh');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27mh', '27mh');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28mh', '28mh');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29mh', '29mh');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30mh', '30mh');
        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31mh', '31mh');
    });

    test('format month', function (assert) {
        var expected = months,
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM,MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = [
                'Dé Domhnaigh Domh Do',
                'Dé Luain Luan Lu',
                'Dé Máirt Máirt Má',
                'Dé Céadaoin Céad Cé',
                'Déardaoin Déar Dé',
                'Dé hAoine Aoine A',
                'Dé Sathairn Sath Sa',
            ],
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'cúpla soicind',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'nóiméad',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'nóiméad',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 nóiméad',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 nóiméad',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'uair an chloig',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'uair an chloig',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 uair an chloig',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 uair an chloig',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 uair an chloig',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'lá',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'lá',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 lá',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'lá',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 lá',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 lá',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'mí',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'mí',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'mí',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 míonna',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 míonna',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 míonna',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'mí',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 míonna',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'bliain',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 bliain',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'bliain',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 bliain',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'i cúpla soicind', 'prefix');
        assert.equal(moment(0).from(30000), 'cúpla soicind ó shin', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'cúpla soicind ó shin',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'i cúpla soicind',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'i 5 lá', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Inniu ag 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Inniu ag 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Inniu ag 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Amárach ag 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Inniu ag 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Inné ag 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [ag] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [ag] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [ag] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [seo caite] [ag] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [seo caite] [ag] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [seo caite] [ag] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52na',
            'Ean  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1d',
            'Ean  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1d',
            'Ean  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2na',
            'Ean  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2na',
            'Ean 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('gd');

    var months = [
        'Am Faoilleach,Faoi',
        'An Gearran,Gear',
        'Am Màrt,Màrt',
        'An Giblean,Gibl',
        'An Cèitean,Cèit',
        'An t-Ògmhios,Ògmh',
        'An t-Iuchar,Iuch',
        'An Lùnastal,Lùn',
        'An t-Sultain,Sult',
        'An Dàmhair,Dàmh',
        'An t-Samhain,Samh',
        'An Dùbhlachd,Dùbh',
    ];

    test('parse', function (assert) {
        function equalTest(monthName, monthFormat, monthNum) {
            assert.equal(
                moment(monthName, monthFormat).month(),
                monthNum,
                monthName + ' should be month ' + (monthNum + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        var i, testMonth;
        for (i = 0; i < 12; i++) {
            testMonth = months[i].split(',');

            equalTest(testMonth[0], 'MMM', i);
            equalTest(testMonth[1], 'MMM', i);
            equalTest(testMonth[0], 'MMMM', i);
            equalTest(testMonth[1], 'MMMM', i);
            equalTest(testMonth[0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(testMonth[1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(testMonth[0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(testMonth[1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(testMonth[1], 'MMM', i);
            equalTestStrict(testMonth[0], 'MMMM', i);
            equalTestStrict(testMonth[1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(testMonth[1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(testMonth[0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(testMonth[0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Didòmhnaich, An Gearran 14mh 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Did, 3PM'],
                ['M Mo MM MMMM MMM', '2 2na 02 An Gearran Gear'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14mh 14'],
                ['d do dddd ddd dd', '0 0mh Didòmhnaich Did Dò'],
                ['DDD DDDo DDDD', '45 45mh 045'],
                ['w wo ww', '6 6mh 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[an] DDDo [latha den bhliadhna]', 'an 45mh latha den bhliadhna'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 An Gearran 2010'],
                ['LLL', '14 An Gearran 2010 15:25'],
                ['LLLL', 'Didòmhnaich, 14 An Gearran 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Gear 2010'],
                ['lll', '14 Gear 2010 15:25'],
                ['llll', 'Did, 14 Gear 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1d', '1d');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2na', '2na');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3mh', '3mh');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4mh', '4mh');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5mh', '5mh');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6mh', '6mh');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7mh', '7mh');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8mh', '8mh');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9mh', '9mh');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10mh', '10mh');
        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11mh', '11mh');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12na', '12na');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13mh', '13mh');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14mh', '14mh');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15mh', '15mh');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16mh', '16mh');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17mh', '17mh');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18mh', '18mh');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19mh', '19mh');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20mh', '20mh');
        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21mh', '21mh');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22na', '22na');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23mh', '23mh');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24mh', '24mh');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25mh', '25mh');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26mh', '26mh');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27mh', '27mh');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28mh', '28mh');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29mh', '29mh');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30mh', '30mh');
        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31mh', '31mh');
    });

    test('format month', function (assert) {
        var expected = months,
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM,MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = [
                'Didòmhnaich Did Dò',
                'Diluain Dil Lu',
                'Dimàirt Dim Mà',
                'Diciadain Dic Ci',
                'Diardaoin Dia Ar',
                'Dihaoine Dih Ha',
                'Disathairne Dis Sa',
            ],
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'beagan diogan',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'mionaid',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'mionaid',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 mionaidean',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 mionaidean',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'uair',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'uair',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 uairean',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 uairean',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 uairean',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'latha',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'latha',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 latha',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'latha',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 latha',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 latha',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'mìos',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'mìos',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'mìos',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mìosan',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mìosan',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mìosan',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'mìos',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mìosan',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'bliadhna',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 bliadhna',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'bliadhna',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 bliadhna',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'ann an beagan diogan', 'prefix');
        assert.equal(moment(0).from(30000), 'bho chionn beagan diogan', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'bho chionn beagan diogan',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'ann an beagan diogan',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'ann an 5 latha',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'An-diugh aig 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'An-diugh aig 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'An-diugh aig 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'A-màireach aig 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'An-diugh aig 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'An-dè aig 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [aig] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [aig] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [aig] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [seo chaidh] [aig] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [seo chaidh] [aig] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [seo chaidh] [aig] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52na',
            'Faoi  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1d',
            'Faoi  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1d',
            'Faoi  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2na',
            'Faoi  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2na',
            'Faoi 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('gl');

    test('parse', function (assert) {
        var tests = 'xaneiro xan._febreiro feb._marzo mar._abril abr._maio mai._xuño xuñ._xullo xul._agosto ago._setembro set._outubro out._novembro nov._decembro dec.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'domingo, febreiro 14º 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dom., 3PM'],
                ['M Mo MM MMMM MMM', '2 2º 02 febreiro feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14º 14'],
                ['d do dddd ddd dd', '0 0º domingo dom. do'],
                ['DDD DDDo DDDD', '45 45º 045'],
                ['w wo ww', '6 6º 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45º day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 de febreiro de 2010'],
                ['LLL', '14 de febreiro de 2010 15:25'],
                ['LLLL', 'domingo, 14 de febreiro de 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 de feb. de 2010'],
                ['lll', '14 de feb. de 2010 15:25'],
                ['llll', 'dom., 14 de feb. de 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');
    });

    test('format month', function (assert) {
        var expected = 'xaneiro xan._febreiro feb._marzo mar._abril abr._maio mai._xuño xuñ._xullo xul._agosto ago._setembro set._outubro out._novembro nov._decembro dec.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'domingo dom. do_luns lun. lu_martes mar. ma_mércores mér. mé_xoves xov. xo_venres ven. ve_sábado sáb. sá'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'uns segundos',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'un minuto',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'un minuto',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutos',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutos',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'unha hora',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'unha hora',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 horas',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 horas',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 horas',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un día',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un día',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 días',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un día',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 días',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 días',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'un mes',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'un mes',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'un mes',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 meses',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 meses',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 meses',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'un mes',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 meses',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un ano',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 anos',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un ano',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 anos',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'nuns segundos', 'prefix');
        assert.equal(moment(0).from(30000), 'hai uns segundos', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'hai uns segundos',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'nuns segundos',
            'nuns segundos'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'en 5 días', 'en 5 días');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'hoxe ás 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'hoxe ás 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'hoxe ás 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'mañá ás 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).add({ d: 1, h: -1 }).calendar(),
            'mañá ás 11:00',
            'tomorrow minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'hoxe ás 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'onte á 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [' + (m.hours() !== 1 ? 'ás' : 'a') + '] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [' + (m.hours() !== 1 ? 'ás' : 'a') + '] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [' + (m.hours() !== 1 ? 'ás' : 'a') + '] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(
                    '[o] dddd [pasado ' + (m.hours() !== 1 ? 'ás' : 'a') + '] LT'
                ),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(
                    '[o] dddd [pasado ' + (m.hours() !== 1 ? 'ás' : 'a') + '] LT'
                ),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(
                    '[o] dddd [pasado ' + (m.hours() !== 1 ? 'ás' : 'a') + '] LT'
                ),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('regression tests', function (assert) {
        var lastWeek = moment().subtract({ d: 4 }).hours(1);
        assert.equal(
            lastWeek.calendar(),
            lastWeek.format('[o] dddd [pasado a] LT'),
            "1 o'clock bug"
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52º',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1º',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1º',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2º',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2º',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('gom-deva');

    test('parse', function (assert) {
        var i,
            tests = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च_एप्रील एप्री._मे मे_जून जून_जुलय जुल._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'आयतार, फेब्रुवारीच्या 14वेर 2010, 3:25:50 दनपारां',
                ],
                ['ddd, h A', 'आयत., 3 दनपारां'],
                ['M Mo MM MMMM MMM', '2 2 02 फेब्रुवारी फेब्रु.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14वेर 14'],
                ['d do dddd ddd dd', '0 0 आयतार आयत. आ'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '7 7 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'दनपारां दनपारां'],
                ['[वर्साचो] DDDo[वो दीस]', 'वर्साचो 45वो दीस'],
                ['LTS', 'दनपारां 3:25:50 वाजतां'],
                ['L', '14-02-2010'],
                ['LL', '14 फेब्रुवारी 2010'],
                ['LLL', '14 फेब्रुवारी 2010 दनपारां 3:25 वाजतां'],
                ['LLLL', 'आयतार, फेब्रुवारीच्या 14वेर, 2010, दनपारां 3:25 वाजतां'],
                ['l', '14-2-2010'],
                ['ll', '14 फेब्रु. 2010'],
                ['lll', '14 फेब्रु. 2010 दनपारां 3:25 वाजतां'],
                ['llll', 'आयत., 14 फेब्रु. 2010, दनपारां 3:25 वाजतां'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var i,
            expected = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च_एप्रील एप्री._मे मे_जून जून_जुलय जुल._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'आयतार आयत. आ_सोमार सोम. सो_मंगळार मंगळ. मं_बुधवार बुध. बु_बिरेस्तार ब्रेस्त. ब्रे_सुक्रार सुक्र. सु_शेनवार शेन. शे'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'थोडे सॅकंड',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'एक मिनूट',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'एक मिनूट',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 मिणटां',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 मिणटां',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'एक वर',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'एक वर',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 वरां',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 वरां',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 वरां',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'एक दीस',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'एक दीस',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 दीस',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'एक दीस',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 दीस',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 दीस',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'एक म्हयनो',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'एक म्हयनो',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'एक म्हयनो',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 म्हयने',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 म्हयने',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 म्हयने',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'एक म्हयनो',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 म्हयने',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'एक वर्स',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 वर्सां',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'एक वर्स',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 वर्सां',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'थोडया सॅकंडांनी', 'prefix');
        assert.equal(moment(0).from(30000), 'थोडे सॅकंड आदीं', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'थोडे सॅकंड आदीं',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'थोडया सॅकंडांनी',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 दिसांनी', 'in 5 days');
    });

    test('ago', function (assert) {
        assert.equal(
            moment().subtract({ h: 3 }).fromNow(),
            '3 वरां आदीं',
            '3 hours ago'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'आयज दनपारां 12:00 वाजतां',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'आयज दनपारां 12:25 वाजतां',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'आयज दनपारां 1:00 वाजतां',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'फाल्यां दनपारां 12:00 वाजतां',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'आयज सकाळीं 11:00 वाजतां',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'काल दनपारां 12:00 वाजतां',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[फुडलो] dddd[,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[फुडलो] dddd[,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[फुडलो] dddd[,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[फाटलो] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[फाटलो] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[फाटलो] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('gom-latn');

    test('parse', function (assert) {
        var i,
            tests = 'Janer Jan._Febrer Feb._Mars Mars_Abril Abr._Mai Mai_Jun Jun_Julai Jul._Agost Ago._Setembr Set._Otubr Otu._Novembr Nov._Dezembr Dez.'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Aitar, Febrerachea 14er 2010, 3:25:50 donparam',
                ],
                ['ddd, h A', 'Ait., 3 donparam'],
                ['M Mo MM MMMM MMM', '2 2 02 Febrer Feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14er 14'],
                ['d do dddd ddd dd', '0 0 Aitar Ait. Ai'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '7 7 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'donparam donparam'],
                ['[Vorsacho] DDDo[vo dis]', 'Vorsacho 45vo dis'],
                ['LTS', 'donparam 3:25:50 vazta'],
                ['L', '14-02-2010'],
                ['LL', '14 Febrer 2010'],
                ['LLL', '14 Febrer 2010 donparam 3:25 vazta'],
                ['LLLL', 'Aitar, Febrerachea 14er, 2010, donparam 3:25 vazta'],
                ['l', '14-2-2010'],
                ['ll', '14 Feb. 2010'],
                ['lll', '14 Feb. 2010 donparam 3:25 vazta'],
                ['llll', 'Ait., 14 Feb. 2010, donparam 3:25 vazta'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var i,
            expected = 'Janer Jan._Febrer Feb._Mars Mars_Abril Abr._Mai Mai_Jun Jun_Julai Jul._Agost Ago._Setembr Set._Otubr Otu._Novembr Nov._Dezembr Dez.'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = "Aitar Ait. Ai_Somar Som. Sm_Mongllar Mon. Mo_Budhvar Bud. Bu_Birestar Bre. Br_Sukrar Suk. Su_Son'var Son. Sn".split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'thodde sekond',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ek minut',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ek minut',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 mintam',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 mintam',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ek vor',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ek vor',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 voram',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 voram',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 voram',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ek dis',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ek dis',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dis',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ek dis',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dis',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dis',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ek mhoino',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ek mhoino',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ek mhoino',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mhoine',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mhoine',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mhoine',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ek mhoino',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mhoine',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ek voros',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 vorsam',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ek voros',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 vorsam',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'thoddea sekondamni', 'prefix');
        assert.equal(moment(0).from(30000), 'thodde sekond adim', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'thodde sekond adim',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'thoddea sekondamni',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 disamni', 'in 5 days');
    });

    test('ago', function (assert) {
        assert.equal(
            moment().subtract({ h: 3 }).fromNow(),
            '3 voram adim',
            '3 hours ago'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Aiz donparam 12:00 vazta',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Aiz donparam 12:25 vazta',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Aiz donparam 1:00 vazta',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Faleam donparam 12:00 vazta',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Aiz sokallim 11:00 vazta',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Kal donparam 12:00 vazta',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Fuddlo] dddd[,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Fuddlo] dddd[,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Fuddlo] dddd[,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Fattlo] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Fattlo] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Fattlo] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('gu');

    test('parse', function (assert) {
        var tests = 'જાન્યુઆરી જાન્યુ._ફેબ્રુઆરી ફેબ્રુ._માર્ચ માર્ચ_એપ્રિલ એપ્રિ._મે મે_જૂન જૂન_જુલાઈ જુલા._ઑગસ્ટ ઑગ._સપ્ટેમ્બર સપ્ટે._ઑક્ટ્બર ઑક્ટ્._નવેમ્બર નવે._ડિસેમ્બર ડિસે..'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            // Fails only for month 12 (index 11)
            // equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            // Fails only for month 12 (index 11)
            // equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            // Fails only for month 12 (index 11)
            // equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, a h:mm:ss વાગ્યે',
                    'રવિવાર, ૧૪ ફેબ્રુઆરી ૨૦૧૦, બપોર ૩:૨૫:૫૦ વાગ્યે',
                ],
                ['ddd, a h વાગ્યે', 'રવિ, બપોર ૩ વાગ્યે'],
                ['M Mo MM MMMM MMM', '૨ ૨ ૦૨ ફેબ્રુઆરી ફેબ્રુ.'],
                ['YYYY YY', '૨૦૧૦ ૧૦'],
                ['D Do DD', '૧૪ ૧૪ ૧૪'],
                ['d do dddd ddd dd', '૦ ૦ રવિવાર રવિ ર'],
                ['DDD DDDo DDDD', '૪૫ ૪૫ ૦૪૫'],
                ['w wo ww', '૮ ૮ ૦૮'],
                ['h hh', '૩ ૦૩'],
                ['H HH', '૧૫ ૧૫'],
                ['m mm', '૨૫ ૨૫'],
                ['s ss', '૫૦ ૫૦'],
                ['a A', 'બપોર બપોર'],
                ['LTS', 'બપોર ૩:૨૫:૫૦ વાગ્યે'],
                ['L', '૧૪/૦૨/૨૦૧૦'],
                ['LL', '૧૪ ફેબ્રુઆરી ૨૦૧૦'],
                ['LLL', '૧૪ ફેબ્રુઆરી ૨૦૧૦, બપોર ૩:૨૫ વાગ્યે'],
                ['LLLL', 'રવિવાર, ૧૪ ફેબ્રુઆરી ૨૦૧૦, બપોર ૩:૨૫ વાગ્યે'],
                ['l', '૧૪/૨/૨૦૧૦'],
                ['ll', '૧૪ ફેબ્રુ. ૨૦૧૦'],
                ['lll', '૧૪ ફેબ્રુ. ૨૦૧૦, બપોર ૩:૨૫ વાગ્યે'],
                ['llll', 'રવિ, ૧૪ ફેબ્રુ. ૨૦૧૦, બપોર ૩:૨૫ વાગ્યે'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '૧', '૧');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '૨', '૨');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '૩', '૩');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '૪', '૪');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '૫', '૫');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '૬', '૬');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '૭', '૭');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '૮', '૮');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '૯', '૯');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '૧૦', '૧૦');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '૧૧', '૧૧');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '૧૨', '૧૨');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '૧૩', '૧૩');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '૧૪', '૧૪');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '૧૫', '૧૫');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '૧૬', '૧૬');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '૧૭', '૧૭');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '૧૮', '૧૮');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '૧૯', '૧૯');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '૨૦', '૨૦');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '૨૧', '૨૧');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '૨૨', '૨૨');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '૨૩', '૨૩');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '૨૪', '૨૪');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '૨૫', '૨૫');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '૨૬', '૨૬');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '૨૭', '૨૭');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '૨૮', '૨૮');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '૨૯', '૨૯');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '૩૦', '૩૦');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '૩૧', '૩૧');
    });

    test('format month', function (assert) {
        var expected = 'જાન્યુઆરી જાન્યુ._ફેબ્રુઆરી ફેબ્રુ._માર્ચ માર્ચ_એપ્રિલ એપ્રિ._મે મે_જૂન જૂન_જુલાઈ જુલા._ઑગસ્ટ ઑગ._સપ્ટેમ્બર સપ્ટે._ઑક્ટ્બર ઑક્ટ્._નવેમ્બર નવે._ડિસેમ્બર ડિસે.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'રવિવાર રવિ ર_સોમવાર સોમ સો_મંગળવાર મંગળ મં_બુધ્વાર બુધ્ બુ_ગુરુવાર ગુરુ ગુ_શુક્રવાર શુક્ર શુ_શનિવાર શનિ શ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'અમુક પળો',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'એક મિનિટ',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'એક મિનિટ',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '૨ મિનિટ',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '૪૪ મિનિટ',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'એક કલાક',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'એક કલાક',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '૨ કલાક',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '૫ કલાક',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '૨૧ કલાક',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'એક દિવસ',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'એક દિવસ',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '૨ દિવસ',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'એક દિવસ',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '૫ દિવસ',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '૨૫ દિવસ',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'એક મહિનો',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'એક મહિનો',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'એક મહિનો',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '૨ મહિનો',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '૨ મહિનો',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '૩ મહિનો',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'એક મહિનો',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '૫ મહિનો',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'એક વર્ષ',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '૨ વર્ષ',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'એક વર્ષ',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '૫ વર્ષ',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'અમુક પળો મા', 'prefix');
        assert.equal(moment(0).from(30000), 'અમુક પળો પહેલા', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'અમુક પળો પહેલા',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'અમુક પળો મા',
            'અમુક પળો મા'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '૫ દિવસ મા', '૫ દિવસ મા');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(2).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'આજ રાત ૨:૦૦ વાગ્યે',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'આજ રાત ૨:૨૫ વાગ્યે',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 3 }).calendar(),
            'આજ સવાર ૫:૦૦ વાગ્યે',
            'Now plus 3 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'કાલે રાત ૨:૦૦ વાગ્યે',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'આજ રાત ૧:૦૦ વાગ્યે',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ગઇકાલે રાત ૨:૦૦ વાગ્યે',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[પાછલા] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[પાછલા] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[પાછલા] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('a'),
            'રાત',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('a'), 'સવાર', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('a'),
            'બપોર',
            'during day'
        );
        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'સાંજ', 'evening');
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('a'),
            'સાંજ',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'રાત', 'night');

        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('A'),
            'રાત',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('A'), 'સવાર', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('A'),
            'બપોર',
            ' during day'
        );
        assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'સાંજ', 'evening');
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('A'),
            'સાંજ',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'રાત', 'night');
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '૧ ૦૧ ૧',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '૧ ૦૧ ૧',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '૨ ૦૨ ૨',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '૨ ૦૨ ૨',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '૩ ૦૩ ૩',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('he');

    test('parse', function (assert) {
        var tests = 'ינואר ינו׳_פברואר פבר׳_מרץ מרץ_אפריל אפר׳_מאי מאי_יוני יוני_יולי יולי_אוגוסט אוג׳_ספטמבר ספט׳_אוקטובר אוק׳_נובמבר נוב׳_דצמבר דצמ׳'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'ראשון, פברואר 14 2010, 3:25:50 אחה"צ',
                ],
                ['ddd, h A', 'א׳, 3 אחרי הצהריים'],
                ['M Mo MM MMMM MMM', '2 2 02 פברואר פבר׳'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 ראשון א׳ א'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '8 8 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'אחה"צ אחרי הצהריים'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 בפברואר 2010'],
                ['LLL', '14 בפברואר 2010 15:25'],
                ['LLLL', 'ראשון, 14 בפברואר 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 פבר׳ 2010'],
                ['lll', '14 פבר׳ 2010 15:25'],
                ['llll', 'א׳, 14 פבר׳ 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format month', function (assert) {
        var expected = 'ינואר ינו׳_פברואר פבר׳_מרץ מרץ_אפריל אפר׳_מאי מאי_יוני יוני_יולי יולי_אוגוסט אוג׳_ספטמבר ספט׳_אוקטובר אוק׳_נובמבר נוב׳_דצמבר דצמ׳'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'ראשון א׳ א|שני ב׳ ב|שלישי ג׳ ג|רביעי ד׳ ד|חמישי ה׳ ה|שישי ו׳ ו|שבת ש׳ ש'.split(
                '|'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'מספר שניות',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'דקה',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'דקה',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 דקות',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 דקות',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'שעה',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'שעה',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            'שעתיים',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 שעות',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 שעות',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'יום',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'יום',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            'יומיים',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'יום',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 ימים',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 ימים',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'חודש',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'חודש',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'חודש',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            'חודשיים',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            'חודשיים',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 חודשים',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'חודש',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 חודשים',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'שנה',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            'שנתיים',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 3699 }), true),
            '10 שנים',
            '345 days = 10 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 7340 }), true),
            '20 שנה',
            '548 days = 20 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'שנה',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 שנים',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'בעוד מספר שניות', 'prefix');
        assert.equal(moment(0).from(30000), 'לפני מספר שניות', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'לפני מספר שניות',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'בעוד מספר שניות',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'בעוד 5 ימים', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'היום ב־12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'היום ב־12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'היום ב־13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'מחר ב־12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'היום ב־11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'אתמול ב־12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [בשעה] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [בשעה] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [בשעה] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[ביום] dddd [האחרון בשעה] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[ביום] dddd [האחרון בשעה] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[ביום] dddd [האחרון בשעה] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('hi');

    test('parse', function (assert) {
        var testsFormat = 'जनवरी जन._फ़रवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितम्बर सित._अक्टूबर अक्टू._नवम्बर नव._दिसम्बर दिस.'.split(
                '_'
            ),
            testsStandalone = 'जनवरी जन._फरवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितंबर सित._अक्टूबर अक्टू._नवंबर नव._दिसंबर दिस.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            testsFormat[i] = testsFormat[i].split(' ');
            equalTest(testsFormat[i][0], 'MMM', i);
            equalTest(testsFormat[i][1], 'MMM', i);
            equalTest(testsFormat[i][0], 'MMMM', i);
            equalTest(testsFormat[i][1], 'MMMM', i);
            equalTest(testsFormat[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(testsFormat[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(testsFormat[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(testsFormat[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(testsFormat[i][1], 'MMM', i);
            equalTestStrict(testsFormat[i][0], 'MMMM', i);
            equalTestStrict(testsFormat[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(testsFormat[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(testsFormat[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(testsFormat[i][0].toLocaleUpperCase(), 'MMMM', i);
        }

        for (i = 0; i < 12; i++) {
            testsStandalone[i] = testsStandalone[i].split(' ');
            equalTest(testsStandalone[i][0], 'MMM', i);
            equalTest(testsStandalone[i][1], 'MMM', i);
            equalTest(testsStandalone[i][0], 'MMMM', i);
            equalTest(testsStandalone[i][1], 'MMMM', i);
            equalTest(testsStandalone[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(testsStandalone[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(testsStandalone[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(testsStandalone[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(testsStandalone[i][1], 'MMM', i);
            equalTestStrict(testsStandalone[i][0], 'MMMM', i);
            equalTestStrict(testsStandalone[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(testsStandalone[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(testsStandalone[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(testsStandalone[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, a h:mm:ss बजे',
                    'रविवार, १४ फ़रवरी २०१०, दोपहर ३:२५:५० बजे',
                ],
                ['ddd, a h बजे', 'रवि, दोपहर ३ बजे'],
                ['M Mo MM MMMM MMM', '२ २ ०२ फरवरी फ़र.'],
                ['YYYY YY', '२०१० १०'],
                ['D Do DD', '१४ १४ १४'],
                ['d do dddd ddd dd', '० ० रविवार रवि र'],
                ['DDD DDDo DDDD', '४५ ४५ ०४५'],
                ['w wo ww', '८ ८ ०८'],
                ['h hh', '३ ०३'],
                ['H HH', '१५ १५'],
                ['m mm', '२५ २५'],
                ['s ss', '५० ५०'],
                ['a A', 'दोपहर दोपहर'],
                ['LTS', 'दोपहर ३:२५:५० बजे'],
                ['L', '१४/०२/२०१०'],
                ['LL', '१४ फ़रवरी २०१०'],
                ['LLL', '१४ फ़रवरी २०१०, दोपहर ३:२५ बजे'],
                ['LLLL', 'रविवार, १४ फ़रवरी २०१०, दोपहर ३:२५ बजे'],
                ['l', '१४/२/२०१०'],
                ['ll', '१४ फ़र. २०१०'],
                ['lll', '१४ फ़र. २०१०, दोपहर ३:२५ बजे'],
                ['llll', 'रवि, १४ फ़र. २०१०, दोपहर ३:२५ बजे'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');
    });

    test('format month', function (assert) {
        var expected = 'जनवरी जन._फरवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितंबर सित._अक्टूबर अक्टू._नवंबर नव._दिसंबर दिस.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format month case', function (assert) {
        var months = {
                nominative: 'जनवरी_फरवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितंबर_अक्टूबर_नवंबर_दिसंबर'.split(
                    '_'
                ),
                accusative: 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split(
                    '_'
                ),
            },
            i;
        for (i = 0; i < 12; i++) {
            assert.equal(
                moment([2011, i, 1]).format('D MMMM'),
                '१ ' + months.accusative[i],
                '१ ' + months.accusative[i]
            );
            assert.equal(
                moment([2011, i, 1]).format('MMMM'),
                months.nominative[i],
                '१ ' + months.nominative[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'रविवार रवि र_सोमवार सोम सो_मंगलवार मंगल मं_बुधवार बुध बु_गुरूवार गुरू गु_शुक्रवार शुक्र शु_शनिवार शनि श'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'कुछ ही क्षण',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'एक मिनट',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'एक मिनट',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '२ मिनट',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '४४ मिनट',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'एक घंटा',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'एक घंटा',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '२ घंटे',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '५ घंटे',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '२१ घंटे',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'एक दिन',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'एक दिन',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '२ दिन',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'एक दिन',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '५ दिन',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '२५ दिन',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'एक महीने',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'एक महीने',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'एक महीने',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '२ महीने',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '२ महीने',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '३ महीने',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'एक महीने',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '५ महीने',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'एक वर्ष',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '२ वर्ष',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'एक वर्ष',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '५ वर्ष',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'कुछ ही क्षण में', 'prefix');
        assert.equal(moment(0).from(30000), 'कुछ ही क्षण पहले', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'कुछ ही क्षण पहले',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'कुछ ही क्षण में',
            'कुछ ही क्षण में'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '५ दिन में', '५ दिन में');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'आज दोपहर १२:०० बजे',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'आज दोपहर १२:२५ बजे',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 3 }).calendar(),
            'आज दोपहर ३:०० बजे',
            'Now plus 3 hours'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'कल दोपहर १२:०० बजे',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'आज दोपहर ११:०० बजे',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'कल दोपहर १२:०० बजे',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[पिछले] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[पिछले] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[पिछले] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('a'),
            'रात',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('a'), 'सुबह', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('a'),
            'दोपहर',
            'during day'
        );
        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'शाम', 'evening');
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('a'),
            'शाम',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'रात', 'night');

        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('A'),
            'रात',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('A'), 'सुबह', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('A'),
            'दोपहर',
            ' during day'
        );
        assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'शाम', 'evening');
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('A'),
            'शाम',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'रात', 'night');
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '१ ०१ १',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '१ ०१ १',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '२ ०२ २',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '२ ०२ २',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '३ ०३ ३',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('hr');

    test('parse', function (assert) {
        var tests = 'siječanj sij._veljača velj._ožujak ožu._travanj tra._svibanj svi._lipanj lip._srpanj srp._kolovoz kol._rujan ruj._listopad lis._studeni stu._prosinac pro.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'nedjelja, 14. veljače 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'ned., 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 veljača velj.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. nedjelja ned. ne'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '7 7. 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. veljače 2010'],
                ['LLL', '14. veljače 2010 15:25'],
                ['LLLL', 'nedjelja, 14. veljače 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14. velj. 2010'],
                ['lll', '14. velj. 2010 15:25'],
                ['llll', 'ned., 14. velj. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'siječanj sij._veljača velj._ožujak ožu._travanj tra._svibanj svi._lipanj lip._srpanj srp._kolovoz kol._rujan ruj._listopad lis._studeni stu._prosinac pro.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'par sekundi',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'jedna minuta',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'jedna minuta',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minute',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuta',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'jedan sat',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'jedan sat',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 sata',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 sati',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 sati',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'dan',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'dan',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dana',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'dan',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dana',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dana',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'mjesec',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'mjesec',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'mjesec',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mjeseca',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mjeseca',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mjeseca',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'mjesec',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mjeseci',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'godinu',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 godine',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'godinu',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 godina',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'za par sekundi', 'prefix');
        assert.equal(moment(0).from(30000), 'prije par sekundi', 'prefix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'prije par sekundi',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'za par sekundi',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'za 5 dana', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'danas u 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'danas u 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'danas u 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'sutra u 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'danas u 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'jučer u 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                    return '[u] [nedjelju] [u] LT';
                case 3:
                    return '[u] [srijedu] [u] LT';
                case 6:
                    return '[u] [subotu] [u] LT';
                case 1:
                case 2:
                case 4:
                case 5:
                    return '[u] dddd [u] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                    return '[prošlu] [nedjelju] [u] LT';
                case 3:
                    return '[prošlu] [srijedu] [u] LT';
                case 6:
                    return '[prošle] [subote] [u] LT';
                case 1:
                case 2:
                case 4:
                case 5:
                    return '[prošli] dddd [u] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1.',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1.',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2.',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2.',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3.',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('hu');

    test('parse', function (assert) {
        var tests = 'január jan._február feb._március márc._április ápr._május máj._június jún._július júl._augusztus aug._szeptember szept._október okt._november nov._december dec.'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, HH:mm:ss',
                    'vasárnap, február 14. 2010, 15:25:50',
                ],
                ['ddd, HH', 'vas, 15'],
                ['M Mo MM MMMM MMM', '2 2. 02 február feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. vasárnap vas v'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['[az év] DDDo [napja]', 'az év 45. napja'],
                ['LTS', '15:25:50'],
                ['L', '2010.02.14.'],
                ['LL', '2010. február 14.'],
                ['LLL', '2010. február 14. 15:25'],
                ['LLLL', '2010. február 14., vasárnap 15:25'],
                ['l', '2010.2.14.'],
                ['ll', '2010. feb. 14.'],
                ['lll', '2010. feb. 14. 15:25'],
                ['llll', '2010. feb. 14., vas 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('meridiem', function (assert) {
        assert.equal(moment([2011, 2, 23, 0, 0]).format('a'), 'de', 'am');
        assert.equal(moment([2011, 2, 23, 11, 59]).format('a'), 'de', 'am');
        assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), 'du', 'pm');
        assert.equal(moment([2011, 2, 23, 23, 59]).format('a'), 'du', 'pm');

        assert.equal(moment([2011, 2, 23, 0, 0]).format('A'), 'DE', 'AM');
        assert.equal(moment([2011, 2, 23, 11, 59]).format('A'), 'DE', 'AM');
        assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), 'DU', 'PM');
        assert.equal(moment([2011, 2, 23, 23, 59]).format('A'), 'DU', 'PM');
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'január jan._február feb._március márc._április ápr._május máj._június jún._július júl._augusztus aug._szeptember szept._október okt._november nov._december dec.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'vasárnap vas_hétfő hét_kedd kedd_szerda sze_csütörtök csüt_péntek pén_szombat szo'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'néhány másodperc',
            '44 másodperc = néhány másodperc'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'egy perc',
            '45 másodperc = egy perc'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'egy perc',
            '89 másodperc = egy perc'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 perc',
            '90 másodperc = 2 perc'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 perc',
            '44 perc = 44 perc'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'egy óra',
            '45 perc = egy óra'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'egy óra',
            '89 perc = egy óra'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 óra',
            '90 perc = 2 óra'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 óra',
            '5 óra = 5 óra'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 óra',
            '21 óra = 21 óra'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'egy nap',
            '22 óra = egy nap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'egy nap',
            '35 óra = egy nap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 nap',
            '36 óra = 2 nap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'egy nap',
            '1 nap = egy nap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 nap',
            '5 nap = 5 nap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 nap',
            '25 nap = 25 nap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'egy hónap',
            '26 nap = egy hónap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'egy hónap',
            '30 nap = egy hónap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'egy hónap',
            '45 nap = egy hónap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 hónap',
            '46 nap = 2 hónap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 hónap',
            '75 nap = 2 hónap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 hónap',
            '76 nap = 3 hónap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'egy hónap',
            '1 hónap = egy hónap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 hónap',
            '5 hónap = 5 hónap'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'egy év',
            '345 nap = egy év'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 év',
            '548 nap = 2 év'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'egy év',
            '1 év = egy év'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 év',
            '5 év = 5 év'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'néhány másodperc múlva', 'prefix');
        assert.equal(moment(0).from(30000), 'néhány másodperce', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'néhány másodperce',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'néhány másodperc múlva',
            'néhány másodperc múlva'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            '5 nap múlva',
            '5 nap múlva'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'ma 12:00-kor',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'ma 12:25-kor',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'ma 13:00-kor',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'holnap 12:00-kor',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'ma 11:00-kor',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'tegnap 12:00-kor',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i,
            m,
            days = 'vasárnap_hétfőn_kedden_szerdán_csütörtökön_pénteken_szombaton'.split(
                '_'
            );
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[' + days[m.day()] + '] LT[-kor]'),
                'today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[' + days[m.day()] + '] LT[-kor]'),
                'today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[' + days[m.day()] + '] LT[-kor]'),
                'today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i,
            m,
            days = 'vasárnap_hétfőn_kedden_szerdán_csütörtökön_pénteken_szombaton'.split(
                '_'
            );

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),
                'today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),
                'today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),
                'today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), 'egy héte');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'egy hét múlva'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 hete');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            '2 hét múlva'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '52 52 52.',
            'Dec 26 2011 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('hy-am');

    test('parse', function (assert) {
        var tests = 'հունվար հնվ_փետրվար փտր_մարտ մրտ_ապրիլ ապր_մայիս մյս_հունիս հնս_հուլիս հլս_օգոստոս օգս_սեպտեմբեր սպտ_հոկտեմբեր հկտ_նոյեմբեր նմբ_դեկտեմբեր դկտ'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('parse exceptional case', function (assert) {
        assert.equal(
            moment('11 մայիսի 1989', ['DD MMMM YYYY']).format('DD-MM-YYYY'),
            '11-05-1989'
        );
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, HH:mm:ss',
                    'կիրակի, 14 փետրվարի 2010, 15:25:50',
                ],
                ['ddd, h A', 'կրկ, 3 ցերեկվա'],
                ['M Mo MM MMMM MMM', '2 2 02 փետրվար փտր'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 կիրակի կրկ կրկ'],
                ['DDD DDDo DDDD', '45 45-րդ 045'],
                ['w wo ww', '7 7-րդ 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'ցերեկվա ցերեկվա'],
                ['[տարվա] DDDo [օրը]', 'տարվա 45-րդ օրը'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 փետրվարի 2010 թ.'],
                ['LLL', '14 փետրվարի 2010 թ., 15:25'],
                ['LLLL', 'կիրակի, 14 փետրվարի 2010 թ., 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 փտր 2010 թ.'],
                ['lll', '14 փտր 2010 թ., 15:25'],
                ['llll', 'կրկ, 14 փտր 2010 թ., 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format meridiem', function (assert) {
        assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'գիշերվա', 'night');
        assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'գիշերվա', 'night');
        assert.equal(
            moment([2012, 11, 28, 4, 0]).format('A'),
            'առավոտվա',
            'morning'
        );
        assert.equal(
            moment([2012, 11, 28, 11, 59]).format('A'),
            'առավոտվա',
            'morning'
        );
        assert.equal(
            moment([2012, 11, 28, 12, 0]).format('A'),
            'ցերեկվա',
            'afternoon'
        );
        assert.equal(
            moment([2012, 11, 28, 16, 59]).format('A'),
            'ցերեկվա',
            'afternoon'
        );
        assert.equal(
            moment([2012, 11, 28, 17, 0]).format('A'),
            'երեկոյան',
            'evening'
        );
        assert.equal(
            moment([2012, 11, 28, 23, 59]).format('A'),
            'երեկոյան',
            'evening'
        );
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ին', '1-ին');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-րդ', '2-րդ');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-րդ', '3-րդ');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-րդ', '4-րդ');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-րդ', '5-րդ');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-րդ', '6-րդ');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-րդ', '7-րդ');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-րդ', '8-րդ');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-րդ', '9-րդ');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-րդ', '10-րդ');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-րդ', '11-րդ');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-րդ', '12-րդ');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-րդ', '13-րդ');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-րդ', '14-րդ');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-րդ', '15-րդ');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-րդ', '16-րդ');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-րդ', '17-րդ');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-րդ', '18-րդ');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-րդ', '19-րդ');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-րդ', '20-րդ');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-րդ', '21-րդ');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-րդ', '22-րդ');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-րդ', '23-րդ');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-րդ', '24-րդ');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-րդ', '25-րդ');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-րդ', '26-րդ');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-րդ', '27-րդ');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-րդ', '28-րդ');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-րդ', '29-րդ');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-րդ', '30-րդ');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-րդ', '31-րդ');
    });

    test('format month', function (assert) {
        var expected = 'հունվար հնվ_փետրվար փտր_մարտ մրտ_ապրիլ ապր_մայիս մյս_հունիս հնս_հուլիս հլս_օգոստոս օգս_սեպտեմբեր սպտ_հոկտեմբեր հկտ_նոյեմբեր նմբ_դեկտեմբեր դկտ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format month case', function (assert) {
        var months = {
                nominative: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split(
                    '_'
                ),
                accusative: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split(
                    '_'
                ),
            },
            i;
        for (i = 0; i < 12; i++) {
            assert.equal(
                moment([2011, i, 1]).format('D MMMM'),
                '1 ' + months.accusative[i],
                '1 ' + months.accusative[i]
            );
            assert.equal(
                moment([2011, i, 1]).format('MMMM'),
                months.nominative[i],
                '1 ' + months.nominative[i]
            );
        }
    });

    test('format month short case', function (assert) {
        var monthsShort = {
                nominative: 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split(
                    '_'
                ),
                accusative: 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split(
                    '_'
                ),
            },
            i;
        for (i = 0; i < 12; i++) {
            assert.equal(
                moment([2011, i, 1]).format('D MMM'),
                '1 ' + monthsShort.accusative[i],
                '1 ' + monthsShort.accusative[i]
            );
            assert.equal(
                moment([2011, i, 1]).format('MMM'),
                monthsShort.nominative[i],
                '1 ' + monthsShort.nominative[i]
            );
        }
    });

    test('format month case with escaped symbols', function (assert) {
        var months = {
                nominative: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split(
                    '_'
                ),
                accusative: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split(
                    '_'
                ),
            },
            i;
        for (i = 0; i < 12; i++) {
            assert.equal(
                moment([2013, i, 1]).format('D[] MMMM'),
                '1 ' + months.accusative[i],
                '1 ' + months.accusative[i]
            );
            assert.equal(
                moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'),
                '<i>1</i> <b>' + months.accusative[i] + '</b>',
                '1 <b>' + months.accusative[i] + '</b>'
            );
            assert.equal(
                moment([2013, i, 1]).format('D[-ին օրը] MMMM'),
                '1-ին օրը ' + months.accusative[i],
                '1-ին օրը ' + months.accusative[i]
            );
            assert.equal(
                moment([2013, i, 1]).format('D, MMMM'),
                '1, ' + months.nominative[i],
                '1, ' + months.nominative[i]
            );
        }
    });

    test('format month short case with escaped symbols', function (assert) {
        var monthsShort = {
                nominative: 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split(
                    '_'
                ),
                accusative: 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split(
                    '_'
                ),
            },
            i;
        for (i = 0; i < 12; i++) {
            assert.equal(
                moment([2013, i, 1]).format('D[] MMM'),
                '1 ' + monthsShort.accusative[i],
                '1 ' + monthsShort.accusative[i]
            );
            assert.equal(
                moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMM[</b>]'),
                '<i>1</i> <b>' + monthsShort.accusative[i] + '</b>',
                '1 <b>' + monthsShort.accusative[i] + '</b>'
            );
            assert.equal(
                moment([2013, i, 1]).format('D[-ին օրը] MMM'),
                '1-ին օրը ' + monthsShort.accusative[i],
                '1-ին օրը ' + monthsShort.accusative[i]
            );
            assert.equal(
                moment([2013, i, 1]).format('D, MMM'),
                '1, ' + monthsShort.nominative[i],
                '1, ' + monthsShort.nominative[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'կիրակի կրկ կրկ_երկուշաբթի երկ երկ_երեքշաբթի երք երք_չորեքշաբթի չրք չրք_հինգշաբթի հնգ հնգ_ուրբաթ ուրբ ուրբ_շաբաթ շբթ շբթ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'մի քանի վայրկյան',
            '44 seconds = seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'րոպե',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'րոպե',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 րոպե',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 րոպե',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ժամ',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ժամ',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ժամ',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ժամ',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ժամ',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'օր',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'օր',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 օր',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'օր',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 օր',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 11 }), true),
            '11 օր',
            '11 days = 11 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 21 }), true),
            '21 օր',
            '21 days = 21 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 օր',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ամիս',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ամիս',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ամիս',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 ամիս',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 ամիս',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 ամիս',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ամիս',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 ամիս',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'տարի',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 տարի',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'տարի',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 տարի',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'մի քանի վայրկյան հետո', 'prefix');
        assert.equal(moment(0).from(30000), 'մի քանի վայրկյան առաջ', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'մի քանի վայրկյան հետո',
            'in seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 օր հետո', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), 'այսօր 12:00', 'today at the same time');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'այսօր 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'այսօր 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'վաղը 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'այսօր 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'երեկ 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        function makeFormat(d) {
            return 'dddd [օրը ժամը] LT';
        }

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat()),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat()),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat()),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        function makeFormat(d) {
            return '[անցած] dddd [օրը ժամը] LT';
        }

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat()),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat()),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat()),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1-ին',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1-ին',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2-րդ',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2-րդ',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3-րդ',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('id');

    test('parse', function (assert) {
        var tests = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Agt_September Sep_Oktober Okt_November Nov_Desember Des'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Minggu, Februari 14 2010, 3:25:50 sore',
                ],
                ['ddd, hA', 'Min, 3sore'],
                ['M Mo MM MMMM MMM', '2 2 02 Februari Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Minggu Min Mg'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '8 8 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'sore sore'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LTS', '15.25.50'],
                ['L', '14/02/2010'],
                ['LL', '14 Februari 2010'],
                ['LLL', '14 Februari 2010 pukul 15.25'],
                ['LLLL', 'Minggu, 14 Februari 2010 pukul 15.25'],
                ['l', '14/2/2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 pukul 15.25'],
                ['llll', 'Min, 14 Feb 2010 pukul 15.25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format month', function (assert) {
        var expected = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Agt_September Sep_Oktober Okt_November Nov_Desember Des'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Minggu Min Mg_Senin Sen Sn_Selasa Sel Sl_Rabu Rab Rb_Kamis Kam Km_Jumat Jum Jm_Sabtu Sab Sb'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'beberapa detik',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'semenit',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'semenit',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 menit',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 menit',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'sejam',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'sejam',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 jam',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 jam',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 jam',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'sehari',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'sehari',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 hari',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'sehari',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 hari',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 hari',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'sebulan',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'sebulan',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'sebulan',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 bulan',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 bulan',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 bulan',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'sebulan',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 bulan',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'setahun',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 tahun',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'setahun',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 tahun',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'dalam beberapa detik', 'prefix');
        assert.equal(moment(0).from(30000), 'beberapa detik yang lalu', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'beberapa detik yang lalu',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'dalam beberapa detik',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'dalam 5 hari', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Hari ini pukul 12.00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Hari ini pukul 12.25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Hari ini pukul 13.00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Besok pukul 12.00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Hari ini pukul 11.00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Kemarin pukul 12.00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [pukul] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [pukul] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [pukul] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [lalu pukul] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [lalu pukul] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [lalu pukul] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan 1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2',
            'Jan  14 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('is');

    test('parse', function (assert) {
        var tests = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'sunnudagur, 14. febrúar 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'sun, 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 febrúar feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. sunnudagur sun Su'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. febrúar 2010'],
                ['LLL', '14. febrúar 2010 kl. 15:25'],
                ['LLLL', 'sunnudagur, 14. febrúar 2010 kl. 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14. feb 2010'],
                ['lll', '14. feb 2010 kl. 15:25'],
                ['llll', 'sun, 14. feb 2010 kl. 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'sunnudagur sun Su_mánudagur mán Má_þriðjudagur þri Þr_miðvikudagur mið Mi_fimmtudagur fim Fi_föstudagur fös Fö_laugardagur lau La'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'nokkrar sekúndur',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'mínúta',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'mínúta',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 mínútur',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 mínútur',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 21 }), true),
            '21 mínúta',
            '21 minutes = 21 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'klukkustund',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'klukkustund',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 klukkustundir',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 klukkustundir',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 klukkustund',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'dagur',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'dagur',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dagar',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'dagur',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dagar',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dagar',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 11 }), true),
            '11 dagar',
            '11 days = 11 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 21 }), true),
            '21 dagur',
            '21 days = 21 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'mánuður',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'mánuður',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'mánuður',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mánuðir',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mánuðir',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mánuðir',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'mánuður',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mánuðir',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ár',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ár',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ár',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ár',
            '5 years = 5 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 21 }), true),
            '21 ár',
            '21 years = 21 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'eftir nokkrar sekúndur', 'prefix');
        assert.equal(
            moment(0).from(30000),
            'fyrir nokkrum sekúndum síðan',
            'suffix'
        );
        assert.equal(
            moment().subtract({ m: 1 }).fromNow(),
            'fyrir mínútu síðan',
            'a minute ago'
        );
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'fyrir nokkrum sekúndum síðan',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'eftir nokkrar sekúndur',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ m: 1 }).fromNow(),
            'eftir mínútu',
            'in a minute'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'eftir 5 daga', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'í dag kl. 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'í dag kl. 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'í dag kl. 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'á morgun kl. 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'í dag kl. 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'í gær kl. 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [kl.] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [kl.] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [kl.] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[síðasta] dddd [kl.] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[síðasta] dddd [kl.] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[síðasta] dddd [kl.] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('it-ch');

    test('parse', function (assert) {
        var tests = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'domenica, febbraio 14º 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dom, 3PM'],
                ['M Mo MM MMMM MMM', '2 2º 02 febbraio feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14º 14'],
                ['d do dddd ddd dd', '0 0º domenica dom do'],
                ['DDD DDDo DDDD', '45 45º 045'],
                ['w wo ww', '6 6º 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45º day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 febbraio 2010'],
                ['LLL', '14 febbraio 2010 15:25'],
                ['LLLL', 'domenica 14 febbraio 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 feb 2010'],
                ['lll', '14 feb 2010 15:25'],
                ['llll', 'dom 14 feb 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');
    });

    test('format month', function (assert) {
        var expected = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'domenica dom do_lunedì lun lu_martedì mar ma_mercoledì mer me_giovedì gio gi_venerdì ven ve_sabato sab sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'alcuni secondi',
            '44 seconds = seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'un minuto',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'un minuto',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuti',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuti',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            "un'ora",
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            "un'ora",
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ore',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ore',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ore',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un giorno',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un giorno',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 giorni',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un giorno',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 giorni',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 giorni',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'un mese',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'un mese',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'un mese',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mesi',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mesi',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mesi',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'un mese',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mesi',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un anno',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 anni',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un anno',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 anni',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'in alcuni secondi', 'prefix');
        assert.equal(moment(0).from(30000), 'alcuni secondi fa', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'in alcuni secondi',
            'in seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'tra 5 giorni', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Oggi alle 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Oggi alle 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Oggi alle 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Domani alle 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Oggi alle 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Ieri alle 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [alle] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [alle] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [alle] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m, weekday, datestring;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            // Different date string
            weekday = parseInt(m.format('d'), 10);
            datestring =
                weekday === 0
                    ? '[la scorsa] dddd [alle] LT'
                    : '[lo scorso] dddd [alle] LT';
            assert.equal(
                m.calendar(),
                m.format(datestring),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(datestring),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(datestring),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52º',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1º',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1º',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2º',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2º',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('it');

    test('parse', function (assert) {
        var tests = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'domenica, febbraio 14º 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dom, 3PM'],
                ['M Mo MM MMMM MMM', '2 2º 02 febbraio feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14º 14'],
                ['d do dddd ddd dd', '0 0º domenica dom do'],
                ['DDD DDDo DDDD', '45 45º 045'],
                ['w wo ww', '6 6º 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45º day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 febbraio 2010'],
                ['LLL', '14 febbraio 2010 15:25'],
                ['LLLL', 'domenica 14 febbraio 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 feb 2010'],
                ['lll', '14 feb 2010 15:25'],
                ['llll', 'dom 14 feb 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');
    });

    test('format month', function (assert) {
        var expected = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'domenica dom do_lunedì lun lu_martedì mar ma_mercoledì mer me_giovedì gio gi_venerdì ven ve_sabato sab sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'alcuni secondi',
            '44 seconds = seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'un minuto',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'un minuto',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuti',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuti',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            "un'ora",
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            "un'ora",
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ore',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ore',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ore',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un giorno',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un giorno',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 giorni',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un giorno',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 giorni',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 giorni',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'un mese',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'un mese',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'un mese',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mesi',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mesi',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mesi',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'un mese',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mesi',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un anno',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 anni',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un anno',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 anni',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'tra alcuni secondi', 'prefix');
        assert.equal(moment(0).from(30000), 'alcuni secondi fa', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'tra alcuni secondi',
            'tra seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'tra 5 giorni', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Oggi alle 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Oggi alle 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Oggi alle 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Domani alle 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).add({ d: 1, h: -1 }).calendar(),
            'Domani alle 11:00',
            'tomorrow minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Oggi alle 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Ieri alle 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format(
                    'dddd [a' +
                        (m.hours() > 1 ? 'lle ' : m.hours() === 0 ? ' ' : "ll'") +
                        ']LT'
                ),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(
                    'dddd [a' +
                        (m.hours() > 1 ? 'lle ' : m.hours() === 0 ? ' ' : "ll'") +
                        ']LT'
                ),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(
                    'dddd [a' +
                        (m.hours() > 1 ? 'lle ' : m.hours() === 0 ? ' ' : "ll'") +
                        ']LT'
                ),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m, weekday, datestring;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            // Different date string
            weekday = parseInt(m.format('d'), 10);
            datestring =
                weekday === 0
                    ? '[La scorsa] dddd [a' +
                      (m.hours() > 1 ? 'lle ' : m.hours() === 0 ? ' ' : "ll'") +
                      ']LT'
                    : '[Lo scorso] dddd [a' +
                      (m.hours() > 1 ? 'lle ' : m.hours() === 0 ? ' ' : "ll'") +
                      ']LT';
            assert.equal(
                m.calendar(),
                m.format(datestring),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            datestring =
                weekday === 0
                    ? '[La scorsa] dddd [a' +
                      (m.hours() > 1 ? 'lle ' : m.hours() === 0 ? ' ' : "ll'") +
                      ']LT'
                    : '[Lo scorso] dddd [a' +
                      (m.hours() > 1 ? 'lle ' : m.hours() === 0 ? ' ' : "ll'") +
                      ']LT';
            assert.equal(
                m.calendar(),
                m.format(datestring),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            datestring =
                weekday === 0
                    ? '[La scorsa] dddd [a' +
                      (m.hours() > 1 ? 'lle ' : m.hours() === 0 ? ' ' : "ll'") +
                      ']LT'
                    : '[Lo scorso] dddd [a' +
                      (m.hours() > 1 ? 'lle ' : m.hours() === 0 ? ' ' : "ll'") +
                      ']LT';
            assert.equal(
                m.calendar(),
                m.format(datestring),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52º',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1º',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1º',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2º',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2º',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ja');

    test('parse', function (assert) {
        var tests = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, a h:mm:ss',
                    '日曜日, 2月 14日 2010, 午後 3:25:50',
                ],
                ['ddd, Ah', '日, 午後3'],
                ['M Mo MM MMMM MMM', '2 2 02 2月 2月'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14日 14'],
                ['d do dddd ddd dd', '0 0日 日曜日 日 日'],
                ['DDD DDDo DDDD', '45 45日 045'],
                ['w wo ww', '8 8 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', '午後 午後'],
                ['[the] DDDo [day of the year]', 'the 45日 day of the year'],
                ['LTS', '15:25:50'],
                ['L', '2010/02/14'],
                ['LL', '2010年2月14日'],
                ['LLL', '2010年2月14日 15:25'],
                ['LLLL', '2010年2月14日 日曜日 15:25'],
                ['l', '2010/02/14'],
                ['ll', '2010年2月14日'],
                ['lll', '2010年2月14日 15:25'],
                ['llll', '2010年2月14日(日) 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('parse era', function (assert) {
        // strict
        assert.equal(moment('令和2年', 'NNNNy年', true).isValid(), true, '令和2年');
        assert.equal(moment('令和2年', 'NNNNy年', true).year(), 2020, '令和2年');
        assert.equal(moment('令和2年', 'NNNNyo', true).isValid(), true, '令和2年');
        assert.equal(moment('令和2年', 'NNNNyo', true).year(), 2020, '令和2年');

        assert.equal(moment('令和2年', 'Ny年', true).isValid(), false, '令和2年');
        assert.equal(moment('令和2年', 'Ny年', false).isValid(), true, '令和2年');
        assert.equal(moment('㋿2年', 'Ny年', true).isValid(), false, '㋿2年');
        assert.equal(moment('㋿2年', 'Ny年', false).isValid(), true, '㋿2年');
        assert.equal(moment('R2', 'Ny', false).isValid(), true, 'R2');

        // abbrv
        assert.equal(moment('R2', 'Ny', true).isValid(), true, 'R2');
        assert.equal(moment('R2', 'Ny', true).year(), 2020, 'R2');
        assert.equal(moment('R2', 'NNNNy', true).isValid(), false, 'R2');
        assert.equal(moment('R2', 'NNNNNy', true).isValid(), false, 'R2');

        // narrow
        assert.equal(moment('㋿2年', 'Ny年', true).isValid(), false, '㋿2年');
        assert.equal(moment('㋿2年', 'NNNNy年', true).isValid(), false, '㋿2年');
        assert.equal(moment('㋿2年', 'NNNNNy年', true).isValid(), true, '㋿2年');
        assert.equal(moment('㋿2年', 'NNNNNy年', true).year(), 2020, '㋿2年');

        // ordinal year
        assert.equal(moment('令和2年', 'NNNNyo', true).year(), 2020, '平成30年');
        assert.equal(moment('令和元年', 'NNNNyo', true).year(), 2019, '平成元年');

        // old eras
        assert.equal(moment('平成30年', 'NNNNyo', true).year(), 2018, '平成30年');
        assert.equal(moment('平成元年', 'NNNNyo', true).year(), 1989, '平成元年');
        assert.equal(moment('昭和64年', 'NNNNyo', true).year(), 1989, '昭和64年');
        assert.equal(moment('昭和元年', 'NNNNyo', true).year(), 1926, '昭和元年');
        assert.equal(moment('大正元年', 'NNNNyo', true).year(), 1912, '大正元年');
        assert.equal(moment('明治6年', 'NNNNyo', true).year(), 1873, '明治6年');
    });

    test('format era', function (assert) {
        var a = [
                /* First day of Reiwa Era */
                ['+002019-05-01', 'N, NN, NNN', 'R, R, R'],
                ['+002019-05-01', 'NNNN', '令和'],
                ['+002019-05-01', 'NNNNN', '㋿'],
                ['+002019-05-01', 'y yy yyy yyyy', '1 01 001 0001'],
                ['+002019-05-01', 'yo', '元年'],

                /* Last day of Heisei Era */
                ['+002019-04-30', 'N, NN, NNN', 'H, H, H'],
                ['+002019-04-30', 'NNNN', '平成'],
                ['+002019-04-30', 'NNNNN', '㍻'],
                ['+002019-04-30', 'y yy yyy yyyy', '31 31 031 0031'],
                ['+002019-04-30', 'yo', '31年'],

                /* First day of Heisei Era */
                ['+001989-01-08', 'N, NN, NNN', 'H, H, H'],
                ['+001989-01-08', 'NNNN', '平成'],
                ['+001989-01-08', 'NNNNN', '㍻'],
                ['+001989-01-08', 'y yy yyy yyyy', '1 01 001 0001'],
                ['+001989-01-08', 'yo', '元年'],

                /* Last day of Showa Era */
                ['+001989-01-07', 'N, NN, NNN', 'S, S, S'],
                ['+001989-01-07', 'NNNN', '昭和'],
                ['+001989-01-07', 'NNNNN', '㍼'],
                ['+001989-01-07', 'y yy yyy yyyy', '64 64 064 0064'],
                ['+001989-01-07', 'yo', '64年'],

                /* Last day of Showa Era */
                ['+001926-12-25', 'N, NN, NNN', 'S, S, S'],
                ['+001926-12-25', 'NNNN', '昭和'],
                ['+001926-12-25', 'NNNNN', '㍼'],
                ['+001926-12-25', 'y yy yyy yyyy', '1 01 001 0001'],
                ['+001926-12-25', 'yo', '元年'],

                /* Last day of Taisho Era */
                ['+001926-12-24', 'N, NN, NNN', 'T, T, T'],
                ['+001926-12-24', 'NNNN', '大正'],
                ['+001926-12-24', 'NNNNN', '㍽'],
                ['+001926-12-24', 'y yy yyy yyyy', '15 15 015 0015'],
                ['+001926-12-24', 'yo', '15年'],

                /* First day of Taisho Era */
                ['+001912-07-30', 'N, NN, NNN', 'T, T, T'],
                ['+001912-07-30', 'NNNN', '大正'],
                ['+001912-07-30', 'NNNNN', '㍽'],
                ['+001912-07-30', 'y yy yyy yyyy', '1 01 001 0001'],
                ['+001912-07-30', 'yo', '元年'],

                /* Last day of Meiji Era */
                ['+001912-07-29', 'N, NN, NNN', 'M, M, M'],
                ['+001912-07-29', 'NNNN', '明治'],
                ['+001912-07-29', 'NNNNN', '㍾'],
                ['+001912-07-29', 'y yy yyy yyyy', '45 45 045 0045'],
                ['+001912-07-29', 'yo', '45年'],

                /* The day the Japanese government had began using the Gregorian calendar */
                ['+001873-01-01', 'N, NN, NNN', 'M, M, M'],
                ['+001873-01-01', 'NNNN', '明治'],
                ['+001873-01-01', 'NNNNN', '㍾'],
                ['+001873-01-01', 'y yy yyy yyyy', '6 06 006 0006'],
                ['+001873-01-01', 'yo', '6年'],

                /* Christinan Era */
                ['+001872-12-31', 'N, NN, NNN', 'AD, AD, AD'],
                ['+001872-12-31', 'NNNN', '西暦'],
                ['+001872-12-31', 'NNNNN', 'AD'],
                ['+001872-12-31', 'y yy yyy yyyy', '1872 1872 1872 1872'],
                ['+001872-12-31', 'yo', '1872年'],

                ['+000001-01-01', 'N, NN, NNN', 'AD, AD, AD'],
                ['+000001-01-01', 'NNNN', '西暦'],
                ['+000001-01-01', 'NNNNN', 'AD'],
                ['+000001-01-01', 'y', '1'],

                ['+000000-12-31', 'N, NN, NNN', 'BC, BC, BC'],
                ['+000000-12-31', 'NNNN', '紀元前'],
                ['+000000-12-31', 'NNNNN', 'BC'],
                ['+000000-12-31', 'y', '1'],

                ['-000001-12-31', 'N, NN, NNN', 'BC, BC, BC'],
                ['-000001-12-31', 'NNNN', '紀元前'],
                ['-000001-12-31', 'NNNNN', 'BC'],
                ['-000001-12-31', 'y', '2'],
            ],
            i,
            l;

        for (i = 0, l = a.length; i < l; ++i) {
            assert.equal(
                moment(a[i][0]).format(a[i][1]),
                a[i][2],
                a[i][0] + '; ' + a[i][1] + ' ---> ' + a[i][2]
            );
        }
    });

    test('format month', function (assert) {
        var expected = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = '日曜日 日 日_月曜日 月 月_火曜日 火 火_水曜日 水 水_木曜日 木 木_金曜日 金 金_土曜日 土 土'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            '数秒',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            '1分',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            '1分',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2分',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44分',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            '1時間',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            '1時間',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2時間',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5時間',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21時間',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            '1日',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            '1日',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2日',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            '1日',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5日',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25日',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            '1ヶ月',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            '1ヶ月',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            '1ヶ月',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2ヶ月',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2ヶ月',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3ヶ月',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            '1ヶ月',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5ヶ月',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            '1年',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2年',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            '1年',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5年',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), '数秒後', 'prefix');
        assert.equal(moment(0).from(30000), '数秒前', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            '数秒前',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            '数秒後',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5日後', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), '今日 12:00', 'today at the same time');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            '今日 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            '今日 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            '明日 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            '今日 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            '昨日 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i,
            m,
            dow = moment().day();
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            if (dow + i < 7) {
                assert.equal(
                    m.calendar(),
                    m.format('dddd LT'),
                    'Today + ' + i + ' days current time'
                );
                m.hours(0).minutes(0).seconds(0).milliseconds(0);
                assert.equal(
                    m.calendar(),
                    m.format('dddd LT'),
                    'Today + ' + i + ' days beginning of day'
                );
                m.hours(23).minutes(59).seconds(59).milliseconds(999);
                assert.equal(
                    m.calendar(),
                    m.format('dddd LT'),
                    'Today + ' + i + ' days end of day'
                );
            } else {
                assert.equal(
                    m.calendar(),
                    m.format('[来週]dddd LT'),
                    'Today + ' + i + ' days current time'
                );
                m.hours(0).minutes(0).seconds(0).milliseconds(0);
                assert.equal(
                    m.calendar(),
                    m.format('[来週]dddd LT'),
                    'Today + ' + i + ' days beginning of day'
                );
                m.hours(23).minutes(59).seconds(59).milliseconds(999);
                assert.equal(
                    m.calendar(),
                    m.format('[来週]dddd LT'),
                    'Today + ' + i + ' days end of day'
                );
            }
        }
    });

    test('calendar last week', function (assert) {
        var i,
            m,
            dow = moment().day();
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            if (dow < i) {
                assert.equal(
                    m.calendar(),
                    m.format('[先週]dddd LT'),
                    'Today - ' + i + ' days current time'
                );
                m.hours(0).minutes(0).seconds(0).milliseconds(0);
                assert.equal(
                    m.calendar(),
                    m.format('[先週]dddd LT'),
                    'Today - ' + i + ' days beginning of day'
                );
                m.hours(23).minutes(59).seconds(59).milliseconds(999);
                assert.equal(
                    m.calendar(),
                    m.format('[先週]dddd LT'),
                    'Today - ' + i + ' days end of day'
                );
            } else {
                assert.equal(
                    m.calendar(),
                    m.format('dddd LT'),
                    'Today - ' + i + ' days current time'
                );
                m.hours(0).minutes(0).seconds(0).milliseconds(0);
                assert.equal(
                    m.calendar(),
                    m.format('dddd LT'),
                    'Today - ' + i + ' days beginning of day'
                );
                m.hours(23).minutes(59).seconds(59).milliseconds(999);
                assert.equal(
                    m.calendar(),
                    m.format('dddd LT'),
                    'Today - ' + i + ' days end of day'
                );
            }
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3',
            'Jan 15 2012 should be week 3'
        );
    });

    test('parse with japanese parentheses', function (assert) {
        assert.ok(
            moment('2016年5月18日（水）', 'YYYY年M月D日（dd）', true).isValid(),
            'parse with japanese parentheses'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('jv');

    test('parse', function (assert) {
        var tests = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_Nopember Nop_Desember Des'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Minggu, Februari 14 2010, 3:25:50 sonten',
                ],
                ['ddd, hA', 'Min, 3sonten'],
                ['M Mo MM MMMM MMM', '2 2 02 Februari Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Minggu Min Mg'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '7 7 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'sonten sonten'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LTS', '15.25.50'],
                ['L', '14/02/2010'],
                ['LL', '14 Februari 2010'],
                ['LLL', '14 Februari 2010 pukul 15.25'],
                ['LLLL', 'Minggu, 14 Februari 2010 pukul 15.25'],
                ['l', '14/2/2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 pukul 15.25'],
                ['llll', 'Min, 14 Feb 2010 pukul 15.25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format month', function (assert) {
        var expected = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_Nopember Nop_Desember Des'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Minggu Min Mg_Senen Sen Sn_Seloso Sel Sl_Rebu Reb Rb_Kemis Kem Km_Jemuwah Jem Jm_Septu Sep Sp'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'sawetawis detik',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'setunggal menit',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'setunggal menit',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 menit',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 menit',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'setunggal jam',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'setunggal jam',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 jam',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 jam',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 jam',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'sedinten',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'sedinten',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dinten',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'sedinten',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dinten',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dinten',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'sewulan',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'sewulan',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'sewulan',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 wulan',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 wulan',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 wulan',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'sewulan',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 wulan',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'setaun',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 taun',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'setaun',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 taun',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'wonten ing sawetawis detik', 'prefix');
        assert.equal(
            moment(0).from(30000),
            'sawetawis detik ingkang kepengker',
            'suffix'
        );
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'sawetawis detik ingkang kepengker',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'wonten ing sawetawis detik',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'wonten ing 5 dinten',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Dinten puniko pukul 12.00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Dinten puniko pukul 12.25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Dinten puniko pukul 13.00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Mbenjang pukul 12.00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Dinten puniko pukul 11.00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Kala wingi pukul 12.00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [pukul] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [pukul] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [pukul] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [kepengker pukul] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [kepengker pukul] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [kepengker pukul] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    // Monday is the first day of the week.
    // The week that contains Jan 1st is the first week of the year.

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ka');

    test('parse', function (assert) {
        var i,
            tests = 'იანვარი იან_თებერვალი თებ_მარტი მარ_აპრილი აპრ_მაისი მაი_ივნისი ივნ_ივლისი ივლ_აგვისტო აგვ_სექტემბერი სექ_ოქტომბერი ოქტ_ნოემბერი ნოე_დეკემბერი დეკ'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            // the last two are broken until https://github.com/nodejs/node/issues/22518 is fixed
            // equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            // equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'კვირა, თებერვალი მე-14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'კვი, 3PM'],
                ['M Mo MM MMMM MMM', '2 მე-2 02 თებერვალი თებ'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 მე-14 14'],
                ['d do dddd ddd dd', '0 0 კვირა კვი კვ'],
                ['DDD DDDo DDDD', '45 45-ე 045'],
                ['w wo ww', '7 მე-7 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['წლის DDDo დღე', 'წლის 45-ე დღე'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 თებერვალი 2010'],
                ['LLL', '14 თებერვალი 2010 15:25'],
                ['LLLL', 'კვირა, 14 თებერვალი 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 თებ 2010'],
                ['lll', '14 თებ 2010 15:25'],
                ['llll', 'კვი, 14 თებ 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ლი', '1-ლი');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), 'მე-2', 'მე-2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), 'მე-3', 'მე-3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), 'მე-4', 'მე-4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), 'მე-5', 'მე-5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), 'მე-6', 'მე-6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), 'მე-7', 'მე-7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), 'მე-8', 'მე-8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), 'მე-9', 'მე-9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), 'მე-10', 'მე-10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), 'მე-11', 'მე-11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), 'მე-12', 'მე-12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), 'მე-13', 'მე-13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), 'მე-14', 'მე-14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), 'მე-15', 'მე-15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), 'მე-16', 'მე-16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), 'მე-17', 'მე-17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), 'მე-18', 'მე-18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), 'მე-19', 'მე-19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), 'მე-20', 'მე-20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ე', '21-ე');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ე', '22-ე');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ე', '23-ე');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ე', '24-ე');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ე', '25-ე');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ე', '26-ე');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ე', '27-ე');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ე', '28-ე');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ე', '29-ე');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ე', '30-ე');

        assert.equal(
            moment('2011 40', 'YYYY DDD').format('DDDo'),
            'მე-40',
            'მე-40'
        );
        assert.equal(moment('2011 50', 'YYYY DDD').format('DDDo'), '50-ე', '50-ე');
        assert.equal(
            moment('2011 60', 'YYYY DDD').format('DDDo'),
            'მე-60',
            'მე-60'
        );
        assert.equal(
            moment('2011 100', 'YYYY DDD').format('DDDo'),
            'მე-100',
            'მე-100'
        );
        assert.equal(
            moment('2011 101', 'YYYY DDD').format('DDDo'),
            '101-ე',
            '101-ე'
        );
    });

    test('format month', function (assert) {
        var i,
            expected = 'იანვარი იან_თებერვალი თებ_მარტი მარ_აპრილი აპრ_მაისი მაი_ივნისი ივნ_ივლისი ივლ_აგვისტო აგვ_სექტემბერი სექ_ოქტომბერი ოქტ_ნოემბერი ნოე_დეკემბერი დეკ'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'კვირა კვი კვ_ორშაბათი ორშ ორ_სამშაბათი სამ სა_ოთხშაბათი ოთხ ოთ_ხუთშაბათი ხუთ ხუ_პარასკევი პარ პა_შაბათი შაბ შა'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'რამდენიმე წამი',
            '44 წამი  = რამდენიმე წამი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'წუთი',
            '45 წამი  = წუთი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'წუთი',
            '89 წამი  = წუთი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 წუთი',
            '90 წამი  = 2 წუთი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 წუთი',
            '44 წამი  = 44 წუთი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'საათი',
            '45 წამი  = საათი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'საათი',
            '89 წამი  = საათი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 საათი',
            '90 წამი  = 2 საათი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 საათი',
            '5 საათი  = 5 საათი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 საათი',
            '21 საათი = 21 საათი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'დღე',
            '22 საათი = დღე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'დღე',
            '35 საათი = დღე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 დღე',
            '36 საათი = 2 დღე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'დღე',
            '1 დღე    = დღე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 დღე',
            '5 დღე    = 5 დღე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 დღე',
            '25 დღე   = 25 დღე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'თვე',
            '26 დღე   = თვე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'თვე',
            '30 დღე   = თვე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'თვე',
            '45 დღე   = თვე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 თვე',
            '46 დღე   = 2 თვე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 თვე',
            '75 დღე   = 2 თვე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 თვე',
            '76 დღე   = 3 თვე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'თვე',
            '1 თვე    = თვე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 თვე',
            '5 თვე    = 5 თვე'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'წელი',
            '345 დღე  = წელი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 წელი',
            '548 დღე  = 2 წელი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'წელი',
            '1 წელი   = წელი'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 წელი',
            '5 წელი   = 5 წელი'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'რამდენიმე წამში', 'ში სუფიქსი');
        assert.equal(moment(0).from(30000), 'რამდენიმე წამის წინ', 'წინ სუფიქსი');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'რამდენიმე წამის წინ',
            'უნდა აჩვენოს როგორც წარსული'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'რამდენიმე წამში',
            'რამდენიმე წამში'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 დღეში', '5 დღეში');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), 'დღეს 12:00-ზე', 'დღეს ამავე დროს');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'დღეს 12:25-ზე',
            'ახლანდელ დროს დამატებული 25 წუთი'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'დღეს 13:00-ზე',
            'ახლანდელ დროს დამატებული 1 საათი'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'ხვალ 12:00-ზე',
            'ხვალ ამავე დროს'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'დღეს 11:00-ზე',
            'ახლანდელ დროს გამოკლებული 1 საათი'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'გუშინ 12:00-ზე',
            'გუშინ ამავე დროს'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[შემდეგ] dddd LT[-ზე]'),
                'დღეს + ' + i + ' დღე ახლანდელ დროს'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[შემდეგ] dddd LT[-ზე]'),
                'დღეს + ' + i + ' დღე დღის დასაწყისში'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[შემდეგ] dddd LT[-ზე]'),
                'დღეს + ' + i + ' დღე დღის დასასრულს'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[წინა] dddd LT[-ზე]'),
                'დღეს - ' + i + ' დღე ახლანდელ დროს'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[წინა] dddd LT[-ზე]'),
                'დღეს - ' + i + ' დღე დღის დასაწყისში'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[წინა] dddd LT[-ზე]'),
                'დღეს - ' + i + ' დღე დღის დასასრულს'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 კვირის წინ');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            '1 კვირაში'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 კვირის წინ');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            '2 კვირაში'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1-ლი',
            'დეკ 26 2011 უნდა იყოს კვირა 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1-ლი',
            'იან  1 2012 უნდა იყოს კვირა 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 მე-2',
            'იან  2 2012 უნდა იყოს კვირა 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 მე-2',
            'იან  8 2012 უნდა იყოს კვირა 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 მე-3',
            'იან  9 2012 უნდა იყოს კვირა 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('kk');

    test('parse', function (assert) {
        var tests = 'қаңтар қаң_ақпан ақп_наурыз нау_сәуір сәу_мамыр мам_маусым мау_шілде шіл_тамыз там_қыркүйек қыр_қазан қаз_қараша қар_желтоқсан жел'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, HH:mm:ss',
                    'жексенбі, 14-ші ақпан 2010, 15:25:50',
                ],
                ['ddd, hA', 'жек, 3PM'],
                ['M Mo MM MMMM MMM', '2 2-ші 02 ақпан ақп'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14-ші 14'],
                ['d do dddd ddd dd', '0 0-ші жексенбі жек жк'],
                ['DDD DDDo DDDD', '45 45-ші 045'],
                ['w wo ww', '7 7-ші 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[жылдың] DDDo [күні]', 'жылдың 45-ші күні'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 ақпан 2010'],
                ['LLL', '14 ақпан 2010 15:25'],
                ['LLLL', 'жексенбі, 14 ақпан 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 ақп 2010'],
                ['lll', '14 ақп 2010 15:25'],
                ['llll', 'жек, 14 ақп 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ші', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ші', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ші', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ші', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ші', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-шы', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ші', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ші', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-шы', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-шы', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ші', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ші', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ші', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ші', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ші', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-шы', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ші', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ші', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-шы', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-шы', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ші', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ші', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ші', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ші', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ші', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-шы', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ші', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ші', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-шы', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-шы', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ші', '31st');
    });

    test('format month', function (assert) {
        var expected = 'қаңтар қаң_ақпан ақп_наурыз нау_сәуір сәу_мамыр мам_маусым мау_шілде шіл_тамыз там_қыркүйек қыр_қазан қаз_қараша қар_желтоқсан жел'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'жексенбі жек жк_дүйсенбі дүй дй_сейсенбі сей сй_сәрсенбі сәр ср_бейсенбі бей бй_жұма жұм жм_сенбі сен сн'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'бірнеше секунд',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'бір минут',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'бір минут',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 минут',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 минут',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'бір сағат',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'бір сағат',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 сағат',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 сағат',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 сағат',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'бір күн',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'бір күн',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 күн',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'бір күн',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 күн',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 күн',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'бір ай',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'бір ай',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'бір ай',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 ай',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 ай',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 ай',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'бір ай',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 ай',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'бір жыл',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 жыл',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'бір жыл',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 жыл',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'бірнеше секунд ішінде', 'prefix');
        assert.equal(moment(0).from(30000), 'бірнеше секунд бұрын', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'бірнеше секунд бұрын',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'бірнеше секунд ішінде',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 күн ішінде', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Бүгін сағат 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Бүгін сағат 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Бүгін сағат 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Ертең сағат 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Бүгін сағат 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Кеше сағат 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [сағат] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [сағат] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [сағат] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Өткен аптаның] dddd [сағат] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Өткен аптаның] dddd [сағат] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Өткен аптаның] dddd [сағат] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1-ші',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2-ші',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2-ші',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3-ші',
            'Jan  9 2012 should be week 3'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3-ші',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('km');

    test('parse', function (assert) {
        var tests = 'មករា មករា_កុម្ភៈ កុម្ភៈ_មីនា មីនា_មេសា មេសា_ឧសភា ឧសភា_មិថុនា មិថុនា_កក្កដា កក្កដា_សីហា សីហា_កញ្ញា កញ្ញា_តុលា តុលា_វិច្ឆិកា វិច្ឆិកា_ធ្នូ ធ្នូ'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'អាទិត្យ, កុម្ភៈ ទី១៤ ២០១០, ៣:២៥:៥០ ល្ងាច',
                ],
                ['ddd, hA', 'អា, ៣ល្ងាច'],
                ['M Mo MM MMMM MMM', '២ ទី២ ០២ កុម្ភៈ កុម្ភៈ'],
                ['YYYY YY', '២០១០ ១០'],
                ['D Do DD', '១៤ ទី១៤ ១៤'],
                ['d do dddd ddd dd', '០ ទី០ អាទិត្យ អា អា'],
                ['DDD DDDo DDDD', '៤៥ ទី៤៥ ០៤៥'],
                ['w wo ww', '៦ ទី៦ ០៦'],
                ['h hh', '៣ ០៣'],
                ['H HH', '១៥ ១៥'],
                ['m mm', '២៥ ២៥'],
                ['s ss', '៥០ ៥០'],
                ['a A', 'ល្ងាច ល្ងាច'],
                ['[the] DDDo [day of the year]', 'the ទី៤៥ day of the year'],
                ['LTS', '១៥:២៥:៥០'],
                ['L', '១៤/០២/២០១០'],
                ['LL', '១៤ កុម្ភៈ ២០១០'],
                ['LLL', '១៤ កុម្ភៈ ២០១០ ១៥:២៥'],
                ['LLLL', 'អាទិត្យ, ១៤ កុម្ភៈ ២០១០ ១៥:២៥'],
                ['l', '១៤/២/២០១០'],
                ['ll', '១៤ កុម្ភៈ ២០១០'],
                ['lll', '១៤ កុម្ភៈ ២០១០ ១៥:២៥'],
                ['llll', 'អា, ១៤ កុម្ភៈ ២០១០ ១៥:២៥'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), 'ទី១', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), 'ទី២', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), 'ទី៣', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), 'ទី៤', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), 'ទី៥', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), 'ទី៦', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), 'ទី៧', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), 'ទី៨', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), 'ទី៩', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), 'ទី១០', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), 'ទី១១', '11st');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), 'ទី១២', '12nd');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), 'ទី១៣', '13rd');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), 'ទី១៤', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), 'ទី១៥', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), 'ទី១៦', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), 'ទី១៧', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), 'ទី១៨', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), 'ទី១៩', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), 'ទី២០', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), 'ទី២១', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), 'ទី២២', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), 'ទី២៣', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), 'ទី២៤', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), 'ទី២៥', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), 'ទី២៦', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), 'ទី២៧', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), 'ទី២៨', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), 'ទី២៩', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), 'ទី៣០', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), 'ទី៣១', '31st');
    });

    test('format month', function (assert) {
        var expected = 'មករា មករា_កុម្ភៈ កុម្ភៈ_មីនា មីនា_មេសា មេសា_ឧសភា ឧសភា_មិថុនា មិថុនា_កក្កដា កក្កដា_សីហា សីហា_កញ្ញា កញ្ញា_តុលា តុលា_វិច្ឆិកា វិច្ឆិកា_ធ្នូ ធ្នូ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'អាទិត្យ អា អា_ច័ន្ទ ច ច_អង្គារ អ អ_ពុធ ព ព_ព្រហស្បតិ៍ ព្រ ព្រ_សុក្រ សុ សុ_សៅរ៍ ស ស'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ប៉ុន្មានវិនាទី',
            '44 seconds = ប៉ុន្មានវិនាទី'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'មួយនាទី',
            '45 seconds = មួយនាទី'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'មួយនាទី',
            '89 seconds = មួយនាទី'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '២ នាទី',
            '90 seconds = 2 នាទី'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '៤៤ នាទី',
            '44 minutes = 44 នាទី'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'មួយម៉ោង',
            '45 minutes = មួយម៉ោង'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'មួយម៉ោង',
            '89 minutes = មួយម៉ោង'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '២ ម៉ោង',
            '90 minutes = 2 ម៉ោង'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '៥ ម៉ោង',
            '5 hours = 5 ម៉ោង'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '២១ ម៉ោង',
            '21 hours = 21 ម៉ោង'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'មួយថ្ងៃ',
            '22 hours = មួយថ្ងៃ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'មួយថ្ងៃ',
            '35 hours = មួយថ្ងៃ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '២ ថ្ងៃ',
            '36 hours = 2 ថ្ងៃ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'មួយថ្ងៃ',
            '1 day = មួយថ្ងៃ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '៥ ថ្ងៃ',
            '5 days = 5 ថ្ងៃ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '២៥ ថ្ងៃ',
            '25 days = 25 ថ្ងៃ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'មួយខែ',
            '26 days = មួយខែ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'មួយខែ',
            '30 days = មួយខែ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'មួយខែ',
            '43 days = មួយខែ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '២ ខែ',
            '46 days = 2 ខែ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '២ ខែ',
            '75 days = 2 ខែ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '៣ ខែ',
            '76 days = 3 ខែ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'មួយខែ',
            '1 month = មួយខែ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '៥ ខែ',
            '5 months = 5 ខែ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'មួយឆ្នាំ',
            '345 days = មួយឆ្នាំ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '២ ឆ្នាំ',
            '548 days = 2 ឆ្នាំ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'មួយឆ្នាំ',
            '1 year = មួយឆ្នាំ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '៥ ឆ្នាំ',
            '5 years = 5 ឆ្នាំ'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'ប៉ុន្មានវិនាទីទៀត', 'prefix');
        assert.equal(moment(0).from(30000), 'ប៉ុន្មានវិនាទីមុន', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'ប៉ុន្មានវិនាទីមុន',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment()
                .add({
                    s: 30,
                })
                .fromNow(),
            'ប៉ុន្មានវិនាទីទៀត',
            'in a few seconds'
        );
        assert.equal(
            moment()
                .add({
                    d: 5,
                })
                .fromNow(),
            '៥ ថ្ងៃទៀត',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'ថ្ងៃនេះ ម៉ោង ១២:០០',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'ថ្ងៃនេះ ម៉ោង ១២:២៥',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'ថ្ងៃនេះ ម៉ោង ១៣:០០',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'ស្អែក ម៉ោង ១២:០០',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'ថ្ងៃនេះ ម៉ោង ១១:០០',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ម្សិលមិញ ម៉ោង ១២:០០',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({
                d: i,
            });
            assert.equal(
                m.calendar(),
                m.format('dddd [ម៉ោង] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [ម៉ោង] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [ម៉ោង] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({
                d: i,
            });
            assert.equal(
                m.calendar(),
                m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({
                w: 1,
            }),
            weeksFromNow = moment().add({
                w: 1,
            });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({
            w: 2,
        });
        weeksFromNow = moment().add({
            w: 2,
        });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '៥២ ៥២ ទី៥២',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '១ ០១ ទី១',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '១ ០១ ទី១',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '២ ០២ ទី២',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '២ ០២ ទី២',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('kn');

    test('parse', function (assert) {
        var tests = 'ಜನವರಿ ಜನ_ಫೆಬ್ರವರಿ ಫೆಬ್ರ_ಮಾರ್ಚ್ ಮಾರ್ಚ್_ಏಪ್ರಿಲ್ ಏಪ್ರಿಲ್_ಮೇ ಮೇ_ಜೂನ್ ಜೂನ್_ಜುಲೈ ಜುಲೈ_ಆಗಸ್ಟ್ ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂ ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬರ್ ಅಕ್ಟೋ_ನವೆಂಬರ್ ನವೆಂ_ಡಿಸೆಂಬರ್ ಡಿಸೆಂ'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        // function equalTestStrict(input, mmm, monthIndex) {
        //     assert.equal(
        //         moment(input, mmm, true).month(),
        //         monthIndex,
        //         input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
        //     );
        // }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            // All strict parsing fails only for month 9 (index 8)
            // equalTestStrict(tests[i][1], 'MMM', i);
            // equalTestStrict(tests[i][0], 'MMMM', i);
            // equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            // equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            // equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            // equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, a h:mm:ss',
                    'ಭಾನುವಾರ, ೧೪ನೇ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫:೫೦',
                ],
                ['ddd, a h ಗಂಟೆ', 'ಭಾನು, ಮಧ್ಯಾಹ್ನ ೩ ಗಂಟೆ'],
                ['M Mo MM MMMM MMM', '೨ ೨ನೇ ೦೨ ಫೆಬ್ರವರಿ ಫೆಬ್ರ'],
                ['YYYY YY', '೨೦೧೦ ೧೦'],
                ['D Do DD', '೧೪ ೧೪ನೇ ೧೪'],
                ['d do dddd ddd dd', '೦ ೦ನೇ ಭಾನುವಾರ ಭಾನು ಭಾ'],
                ['DDD DDDo DDDD', '೪೫ ೪೫ನೇ ೦೪೫'],
                ['w wo ww', '೮ ೮ನೇ ೦೮'],
                ['h hh', '೩ ೦೩'],
                ['H HH', '೧೫ ೧೫'],
                ['m mm', '೨೫ ೨೫'],
                ['s ss', '೫೦ ೫೦'],
                ['a A', 'ಮಧ್ಯಾಹ್ನ ಮಧ್ಯಾಹ್ನ'],
                ['LTS', 'ಮಧ್ಯಾಹ್ನ ೩:೨೫:೫೦'],
                ['L', '೧೪/೦೨/೨೦೧೦'],
                ['LL', '೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦'],
                ['LLL', '೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],
                ['LLLL', 'ಭಾನುವಾರ, ೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],
                ['l', '೧೪/೨/೨೦೧೦'],
                ['ll', '೧೪ ಫೆಬ್ರ ೨೦೧೦'],
                ['lll', '೧೪ ಫೆಬ್ರ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],
                ['llll', 'ಭಾನು, ೧೪ ಫೆಬ್ರ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '೧ನೇ', '೧ನೇ');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '೨ನೇ', '೨ನೇ');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '೩ನೇ', '೩ನೇ');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '೪ನೇ', '೪ನೇ');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '೫ನೇ', '೫ನೇ');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '೬ನೇ', '೬ನೇ');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '೭ನೇ', '೭ನೇ');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '೮ನೇ', '೮ನೇ');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '೯ನೇ', '೯ನೇ');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '೧೦ನೇ', '೧೦ನೇ');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '೧೧ನೇ', '೧೧ನೇ');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '೧೨ನೇ', '೧೨ನೇ');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '೧೩ನೇ', '೧೩ನೇ');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '೧೪ನೇ', '೧೪ನೇ');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '೧೫ನೇ', '೧೫ನೇ');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '೧೬ನೇ', '೧೬ನೇ');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '೧೭ನೇ', '೧೭ನೇ');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '೧೮ನೇ', '೧೮ನೇ');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '೧೯ನೇ', '೧೯ನೇ');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '೨೦ನೇ', '೨೦ನೇ');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '೨೧ನೇ', '೨೧ನೇ');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '೨೨ನೇ', '೨೨ನೇ');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '೨೩ನೇ', '೨೩ನೇ');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '೨೪ನೇ', '೨೪ನೇ');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '೨೫ನೇ', '೨೫ನೇ');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '೨೬ನೇ', '೨೬ನೇ');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '೨೭ನೇ', '೨೭ನೇ');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '೨೮ನೇ', '೨೮ನೇ');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '೨೯ನೇ', '೨೯ನೇ');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '೩೦ನೇ', '೩೦ನೇ');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '೩೧ನೇ', '೩೧ನೇ');
    });

    test('format month', function (assert) {
        var expected = 'ಜನವರಿ ಜನ_ಫೆಬ್ರವರಿ ಫೆಬ್ರ_ಮಾರ್ಚ್ ಮಾರ್ಚ್_ಏಪ್ರಿಲ್ ಏಪ್ರಿಲ್_ಮೇ ಮೇ_ಜೂನ್ ಜೂನ್_ಜುಲೈ ಜುಲೈ_ಆಗಸ್ಟ್ ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್ ಸೆಪ್ಟೆಂ_ಅಕ್ಟೋಬರ್ ಅಕ್ಟೋ_ನವೆಂಬರ್ ನವೆಂ_ಡಿಸೆಂಬರ್ ಡಿಸೆಂ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'ಭಾನುವಾರ ಭಾನು ಭಾ_ಸೋಮವಾರ ಸೋಮ ಸೋ_ಮಂಗಳವಾರ ಮಂಗಳ ಮಂ_ಬುಧವಾರ ಬುಧ ಬು_ಗುರುವಾರ ಗುರು ಗು_ಶುಕ್ರವಾರ ಶುಕ್ರ ಶು_ಶನಿವಾರ ಶನಿ ಶ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ಕೆಲವು ಕ್ಷಣಗಳು',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ಒಂದು ನಿಮಿಷ',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ಒಂದು ನಿಮಿಷ',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '೨ ನಿಮಿಷ',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '೪೪ ನಿಮಿಷ',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ಒಂದು ಗಂಟೆ',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ಒಂದು ಗಂಟೆ',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '೨ ಗಂಟೆ',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '೫ ಗಂಟೆ',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '೨೧ ಗಂಟೆ',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ಒಂದು ದಿನ',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ಒಂದು ದಿನ',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '೨ ದಿನ',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ಒಂದು ದಿನ',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '೫ ದಿನ',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '೨೫ ದಿನ',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ಒಂದು ತಿಂಗಳು',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ಒಂದು ತಿಂಗಳು',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ಒಂದು ತಿಂಗಳು',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '೨ ತಿಂಗಳು',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '೨ ತಿಂಗಳು',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '೩ ತಿಂಗಳು',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ಒಂದು ತಿಂಗಳು',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '೫ ತಿಂಗಳು',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ಒಂದು ವರ್ಷ',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '೨ ವರ್ಷ',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ಒಂದು ವರ್ಷ',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '೫ ವರ್ಷ',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ', 'prefix');
        assert.equal(moment(0).from(30000), 'ಕೆಲವು ಕ್ಷಣಗಳು ಹಿಂದೆ', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'ಕೆಲವು ಕ್ಷಣಗಳು ಹಿಂದೆ',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ',
            'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '೫ ದಿನ ನಂತರ', '೫ ದಿನ ನಂತರ');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೨:೨೫',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 3 }).calendar(),
            'ಇಂದು ಮಧ್ಯಾಹ್ನ ೩:೦೦',
            'Now plus 3 hours'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'ನಾಳೆ ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೧:೦೦',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ನಿನ್ನೆ ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[ಕೊನೆಯ] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[ಕೊನೆಯ] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[ಕೊನೆಯ] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('a'),
            'ರಾತ್ರಿ',
            'before dawn'
        );
        assert.equal(
            moment([2011, 2, 23, 9, 30]).format('a'),
            'ಬೆಳಿಗ್ಗೆ',
            'morning'
        );
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('a'),
            'ಮಧ್ಯಾಹ್ನ',
            'during day'
        );
        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'ಸಂಜೆ', 'evening');
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('a'),
            'ಸಂಜೆ',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'ರಾತ್ರಿ', 'night');

        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('A'),
            'ರಾತ್ರಿ',
            'before dawn'
        );
        assert.equal(
            moment([2011, 2, 23, 9, 30]).format('A'),
            'ಬೆಳಿಗ್ಗೆ',
            'morning'
        );
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('A'),
            'ಮಧ್ಯಾಹ್ನ',
            ' during day'
        );
        assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'ಸಂಜೆ', 'evening');
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('A'),
            'ಸಂಜೆ',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'ರಾತ್ರಿ', 'night');
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '೧ ೦೧ ೧ನೇ',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '೧ ೦೧ ೧ನೇ',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '೨ ೦೨ ೨ನೇ',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '೨ ೦೨ ೨ನೇ',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '೩ ೦೩ ೩ನೇ',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ko');

    test('parse', function (assert) {
        var tests = '1월 1월_2월 2월_3월 3월_4월 4월_5월 5월_6월 6월_7월 7월_8월 8월_9월 9월_10월 10월_11월 11월_12월 12월'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('parse meridiem', function (assert) {
        var elements = [
                {
                    expression: '1981년 9월 8일 오후 2시 30분',
                    inputFormat: 'YYYY[년] M[월] D[일] A h[시] m[분]',
                    outputFormat: 'A',
                    expected: '오후',
                },
                {
                    expression: '1981년 9월 8일 오전 2시 30분',
                    inputFormat: 'YYYY[년] M[월] D[일] A h[시] m[분]',
                    outputFormat: 'A h시',
                    expected: '오전 2시',
                },
                {
                    expression: '14시 30분',
                    inputFormat: 'H[시] m[분]',
                    outputFormat: 'A',
                    expected: '오후',
                },
                {
                    expression: '오후 4시',
                    inputFormat: 'A h[시]',
                    outputFormat: 'H',
                    expected: '16',
                },
            ],
            i,
            l,
            it,
            actual;

        for (i = 0, l = elements.length; i < l; ++i) {
            it = elements[i];
            actual = moment(it.expression, it.inputFormat).format(it.outputFormat);

            assert.equal(
                actual,
                it.expected,
                "'" +
                    it.outputFormat +
                    "' of '" +
                    it.expression +
                    "' must be '" +
                    it.expected +
                    "' but was '" +
                    actual +
                    "'."
            );
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'YYYY년 MMMM Do dddd a h:mm:ss',
                    '2010년 2월 14일 일요일 오후 3:25:50',
                ],
                ['ddd A h', '일 오후 3'],
                ['M Mo MM MMMM MMM', '2 2월 02 2월 2월'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14일 14'],
                ['d do dddd ddd dd', '0 0일 일요일 일 일'],
                ['DDD DDDo DDDD', '45 45일 045'],
                ['w wo ww', '8 8주 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', '오후 오후'],
                ['일년 중 DDDo째 되는 날', '일년 중 45일째 되는 날'],
                ['LTS', '오후 3:25:50'],
                ['L', '2010.02.14.'],
                ['LL', '2010년 2월 14일'],
                ['LLL', '2010년 2월 14일 오후 3:25'],
                ['LLLL', '2010년 2월 14일 일요일 오후 3:25'],
                ['l', '2010.02.14.'],
                ['ll', '2010년 2월 14일'],
                ['lll', '2010년 2월 14일 오후 3:25'],
                ['llll', '2010년 2월 14일 일요일 오후 3:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1일', '1일');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2일', '2일');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3일', '3일');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4일', '4일');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5일', '5일');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6일', '6일');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7일', '7일');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8일', '8일');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9일', '9일');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10일', '10일');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11일', '11일');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12일', '12일');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13일', '13일');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14일', '14일');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15일', '15일');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16일', '16일');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17일', '17일');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18일', '18일');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19일', '19일');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20일', '20일');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21일', '21일');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22일', '22일');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23일', '23일');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24일', '24일');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25일', '25일');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26일', '26일');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27일', '27일');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28일', '28일');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29일', '29일');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30일', '30일');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31일', '31일');
    });

    test('format month', function (assert) {
        var expected = '1월 1월_2월 2월_3월 3월_4월 4월_5월 5월_6월 6월_7월 7월_8월 8월_9월 9월_10월 10월_11월 11월_12월 12월'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = '일요일 일 일_월요일 월 월_화요일 화 화_수요일 수 수_목요일 목 목_금요일 금 금_토요일 토 토'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            '몇 초',
            '44초 = 몇 초'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            '1분',
            '45초 = 1분'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            '1분',
            '89초 = 1분'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2분',
            '90초 = 2분'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44분',
            '44분 = 44분'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            '한 시간',
            '45분 = 한 시간'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            '한 시간',
            '89분 = 한 시간'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2시간',
            '90분 = 2시간'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5시간',
            '5시간 = 5시간'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21시간',
            '21시간 = 21시간'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            '하루',
            '22시간 = 하루'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            '하루',
            '35시간 = 하루'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2일',
            '36시간 = 2일'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            '하루',
            '하루 = 하루'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5일',
            '5일 = 5일'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25일',
            '25일 = 25일'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            '한 달',
            '26일 = 한 달'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            '한 달',
            '30일 = 한 달'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            '한 달',
            '45일 = 한 달'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2달',
            '46일 = 2달'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2달',
            '75일 = 2달'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3달',
            '76일 = 3달'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            '한 달',
            '1달 = 한 달'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5달',
            '5달 = 5달'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            '일 년',
            '345일 = 일 년'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2년',
            '548일 = 2년'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            '일 년',
            '일 년 = 일 년'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5년',
            '5년 = 5년'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), '몇 초 후', 'prefix');
        assert.equal(moment(0).from(30000), '몇 초 전', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            '몇 초 전',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            '몇 초 후',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5일 후', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            '오늘 오후 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            '오늘 오후 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            '오늘 오후 1:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            '내일 오후 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            '오늘 오전 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            '어제 오후 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('지난주 dddd LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('지난주 dddd LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('지난주 dddd LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1주',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1주',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2주',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2주',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3주',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ku');

    var months = [
        'کانونی دووەم',
        'شوبات',
        'ئازار',
        'نیسان',
        'ئایار',
        'حوزەیران',
        'تەمموز',
        'ئاب',
        'ئەیلوول',
        'تشرینی یەكەم',
        'تشرینی دووەم',
        'كانونی یەکەم',
    ];

    test('parse', function (assert) {
        var tests = months,
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input +
                    ' should be month ' +
                    (i + 1) +
                    ' instead is month ' +
                    moment(input, mmm).month()
            );
        }
        for (i = 0; i < 12; i++) {
            equalTest(tests[i], 'MMM', i);
            equalTest(tests[i], 'MMM', i);
            equalTest(tests[i], 'MMMM', i);
            equalTest(tests[i], 'MMMM', i);
            equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'یه‌كشه‌ممه‌، شوبات ١٤ ٢٠١٠، ٣:٢٥:٥٠ ئێواره‌',
                ],
                ['ddd, hA', 'یه‌كشه‌م، ٣ئێواره‌'],
                ['M Mo MM MMMM MMM', '٢ ٢ ٠٢ شوبات شوبات'],
                ['YYYY YY', '٢٠١٠ ١٠'],
                ['D Do DD', '١٤ ١٤ ١٤'],
                ['d do dddd ddd dd', '٠ ٠ یه‌كشه‌ممه‌ یه‌كشه‌م ی'],
                ['DDD DDDo DDDD', '٤٥ ٤٥ ٠٤٥'],
                ['w wo ww', '٨ ٨ ٠٨'],
                ['h hh', '٣ ٠٣'],
                ['H HH', '١٥ ١٥'],
                ['m mm', '٢٥ ٢٥'],
                ['s ss', '٥٠ ٥٠'],
                ['a A', 'ئێواره‌ ئێواره‌'],
                ['[the] DDDo [day of the year]', 'the ٤٥ day of the year'],
                ['LTS', '١٥:٢٥:٥٠'],
                ['L', '١٤/٠٢/٢٠١٠'],
                ['LL', '١٤ شوبات ٢٠١٠'],
                ['LLL', '١٤ شوبات ٢٠١٠ ١٥:٢٥'],
                ['LLLL', 'یه‌كشه‌ممه‌، ١٤ شوبات ٢٠١٠ ١٥:٢٥'],
                ['l', '١٤/٢/٢٠١٠'],
                ['ll', '١٤ شوبات ٢٠١٠'],
                ['lll', '١٤ شوبات ٢٠١٠ ١٥:٢٥'],
                ['llll', 'یه‌كشه‌م، ١٤ شوبات ٢٠١٠ ١٥:٢٥'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');
        assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');
    });
    //ok
    test('format month', function (assert) {
        var expected = months,
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM'),
                expected[i],
                expected[i]
            );
            assert.equal(
                moment([2011, i, 1]).format('MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'یه‌كشه‌ممه‌ یه‌كشه‌م ی_دووشه‌ممه‌ دووشه‌م د_سێشه‌ممه‌ سێشه‌م س_چوارشه‌ممه‌ چوارشه‌م چ_پێنجشه‌ممه‌ پێنجشه‌م پ_هه‌ینی هه‌ینی ه_شه‌ممه‌ شه‌ممه‌ ش'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'چه‌ند چركه‌یه‌ك',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'یه‌ك خوله‌ك',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'یه‌ك خوله‌ك',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '٢ خوله‌ك',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '٤٤ خوله‌ك',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'یه‌ك كاتژمێر',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'یه‌ك كاتژمێر',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '٢ كاتژمێر',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '٥ كاتژمێر',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '٢١ كاتژمێر',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'یه‌ك ڕۆژ',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'یه‌ك ڕۆژ',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '٢ ڕۆژ',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'یه‌ك ڕۆژ',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '٥ ڕۆژ',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '٢٥ ڕۆژ',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'یه‌ك مانگ',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'یه‌ك مانگ',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'یه‌ك مانگ',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '٢ مانگ',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '٢ مانگ',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '٣ مانگ',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'یه‌ك مانگ',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '٥ مانگ',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'یه‌ك ساڵ',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '٢ ساڵ',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'یه‌ك ساڵ',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '٥ ساڵ',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'له‌ چه‌ند چركه‌یه‌ك', 'prefix');
        assert.equal(moment(0).from(30000), 'چه‌ند چركه‌یه‌ك', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'چه‌ند چركه‌یه‌ك',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'له‌ چه‌ند چركه‌یه‌ك',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'له‌ ٥ ڕۆژ', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'ئه‌مرۆ كاتژمێر ١٢:٠٠',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'ئه‌مرۆ كاتژمێر ١٢:٢٥',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'ئه‌مرۆ كاتژمێر ١٣:٠٠',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'به‌یانی كاتژمێر ١٢:٠٠',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'ئه‌مرۆ كاتژمێر ١١:٠٠',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'دوێنێ كاتژمێر ١٢:٠٠',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [كاتژمێر] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [كاتژمێر] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [كاتژمێر] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [كاتژمێر] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [كاتژمێر] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [كاتژمێر] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 31]).format('w ww wo'),
            '١ ٠١ ١',
            'Dec 31 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 6]).format('w ww wo'),
            '١ ٠١ ١',
            'Jan  6 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '٢ ٠٢ ٢',
            'Jan  7 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 13]).format('w ww wo'),
            '٢ ٠٢ ٢',
            'Jan 13 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '٣ ٠٣ ٣',
            'Jan 14 2012 should be week 3'
        );
    });

    // locale-specific
    test('ku strict mode parsing works', function (assert) {
        var m, formattedDate;
        m = moment().locale('ku');
        formattedDate = m.format('l');
        assert.equal(
            moment.utc(formattedDate, 'l', 'ku', false).isValid(),
            true,
            'Non-strict parsing works'
        );
        assert.equal(
            moment.utc(formattedDate, 'l', 'ku', true).isValid(),
            true,
            'Strict parsing must work'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ky');

    test('parse', function (assert) {
        var tests = 'январь янв_февраль фев_март март_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, HH:mm:ss',
                    'Жекшемби, 14-чү февраль 2010, 15:25:50',
                ],
                ['ddd, hA', 'Жек, 3PM'],
                ['M Mo MM MMMM MMM', '2 2-чи 02 февраль фев'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14-чү 14'],
                ['d do dddd ddd dd', '0 0-чү Жекшемби Жек Жк'],
                ['DDD DDDo DDDD', '45 45-чи 045'],
                ['w wo ww', '7 7-чи 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[жылдын] DDDo [күнү]', 'жылдын 45-чи күнү'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 февраль 2010'],
                ['LLL', '14 февраль 2010 15:25'],
                ['LLLL', 'Жекшемби, 14 февраль 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 фев 2010'],
                ['lll', '14 фев 2010 15:25'],
                ['llll', 'Жек, 14 фев 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-чи', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-чи', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-чү', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-чү', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-чи', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-чы', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-чи', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-чи', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-чу', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-чу', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-чи', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-чи', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-чү', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-чү', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-чи', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-чы', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-чи', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-чи', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-чу', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-чы', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-чи', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-чи', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-чү', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-чү', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-чи', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-чы', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-чи', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-чи', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-чу', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-чу', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-чи', '31st');
    });

    test('format month', function (assert) {
        var expected = 'январь янв_февраль фев_март март_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Жекшемби Жек Жк_Дүйшөмбү Дүй Дй_Шейшемби Шей Шй_Шаршемби Шар Шр_Бейшемби Бей Бй_Жума Жум Жм_Ишемби Ише Иш'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'бирнече секунд',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'бир мүнөт',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'бир мүнөт',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 мүнөт',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 мүнөт',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'бир саат',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'бир саат',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 саат',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 саат',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 саат',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'бир күн',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'бир күн',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 күн',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'бир күн',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 күн',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 күн',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'бир ай',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'бир ай',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'бир ай',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 ай',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 ай',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 ай',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'бир ай',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 ай',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'бир жыл',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 жыл',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'бир жыл',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 жыл',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'бирнече секунд ичинде', 'prefix');
        assert.equal(moment(0).from(30000), 'бирнече секунд мурун', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'бирнече секунд мурун',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'бирнече секунд ичинде',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 күн ичинде', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Бүгүн саат 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Бүгүн саат 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Бүгүн саат 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Эртең саат 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Бүгүн саат 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Кечээ саат 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [саат] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [саат] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [саат] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Өткөн аптанын] dddd [күнү] [саат] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Өткөн аптанын] dddd [күнү] [саат] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Өткөн аптанын] dddd [күнү] [саат] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1-чи',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2-чи',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2-чи',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3-чү',
            'Jan  9 2012 should be week 3'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3-чү',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('lb');

    test('parse', function (assert) {
        var tests = 'Januar Jan._Februar Febr._Mäerz Mrz._Abrëll Abr._Mee Mee_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, HH:mm:ss',
                    'Sonndeg, 14. Februar 2010, 15:25:50',
                ],
                ['ddd, HH:mm', 'So., 15:25'],
                ['M Mo MM MMMM MMM', '2 2. 02 Februar Febr.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. Sonndeg So. So'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50 Auer'],
                ['L', '14.02.2010'],
                ['LL', '14. Februar 2010'],
                ['LLL', '14. Februar 2010 15:25 Auer'],
                ['LLLL', 'Sonndeg, 14. Februar 2010 15:25 Auer'],
                ['l', '14.2.2010'],
                ['ll', '14. Febr. 2010'],
                ['lll', '14. Febr. 2010 15:25 Auer'],
                ['llll', 'So., 14. Febr. 2010 15:25 Auer'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format month', function (assert) {
        var expected = 'Januar Jan._Februar Febr._Mäerz Mrz._Abrëll Abr._Mee Mee_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Sonndeg So. So_Méindeg Mé. Mé_Dënschdeg Dë. Dë_Mëttwoch Më. Më_Donneschdeg Do. Do_Freideg Fr. Fr_Samschdeg Sa. Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'e puer Sekonnen',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'eng Minutt',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'eng Minutt',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 Minutten',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 Minutten',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'eng Stonn',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'eng Stonn',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 Stonnen',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 Stonnen',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 Stonnen',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'een Dag',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'een Dag',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 Deeg',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'een Dag',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 Deeg',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 Deeg',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ee Mount',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ee Mount',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ee Mount',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 Méint',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 Méint',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 Méint',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ee Mount',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 Méint',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ee Joer',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 Joer',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ee Joer',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 Joer',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'an e puer Sekonnen', 'prefix');
        assert.equal(moment(0).from(30000), 'virun e puer Sekonnen', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'an e puer Sekonnen',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 1 }).fromNow(),
            'an engem Dag',
            'in one day'
        );
        assert.equal(moment().add({ d: 2 }).fromNow(), 'an 2 Deeg', 'in 2 days');
        assert.equal(moment().add({ d: 3 }).fromNow(), 'an 3 Deeg', 'in 3 days');
        assert.equal(moment().add({ d: 4 }).fromNow(), 'a 4 Deeg', 'in 4 days');
        assert.equal(moment().add({ d: 5 }).fromNow(), 'a 5 Deeg', 'in 5 days');
        assert.equal(moment().add({ d: 6 }).fromNow(), 'a 6 Deeg', 'in 6 days');
        assert.equal(moment().add({ d: 7 }).fromNow(), 'a 7 Deeg', 'in 7 days');
        assert.equal(moment().add({ d: 8 }).fromNow(), 'an 8 Deeg', 'in 8 days');
        assert.equal(moment().add({ d: 9 }).fromNow(), 'an 9 Deeg', 'in 9 days');
        assert.equal(moment().add({ d: 10 }).fromNow(), 'an 10 Deeg', 'in 10 days');
        assert.equal(
            moment().add({ y: 100 }).fromNow(),
            'an 100 Joer',
            'in 100 years'
        );
        assert.equal(
            moment().add({ y: 400 }).fromNow(),
            'a 400 Joer',
            'in 400 years'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Haut um 12:00 Auer',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Haut um 12:25 Auer',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Haut um 13:00 Auer',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Muer um 12:00 Auer',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Haut um 11:00 Auer',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Gëschter um 12:00 Auer',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [um] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [um] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [um] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m, weekday, datestring;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });

            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday)
            weekday = parseInt(m.format('d'), 10);
            datestring =
                weekday === 2 || weekday === 4
                    ? '[Leschten] dddd [um] LT'
                    : '[Leschte] dddd [um] LT';

            assert.equal(
                m.calendar(),
                m.format(datestring),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(datestring),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(datestring),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1.',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2.',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('lo');

    test('parse', function (assert) {
        var tests = 'ມັງກອນ ມັງກອນ_ກຸມພາ ກຸມພາ_ມີນາ ມີນາ_ເມສາ ເມສາ_ພຶດສະພາ ພຶດສະພາ_ມິຖຸນາ ມິຖຸນາ_ກໍລະກົດ ກໍລະກົດ_ສິງຫາ ສິງຫາ_ກັນຍາ ກັນຍາ_ຕຸລາ ຕຸລາ_ພະຈິກ ພະຈິກ_ທັນວາ ທັນວາ'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'ອາທິດ, ກຸມພາ ທີ່14 2010, 3:25:50 ຕອນແລງ',
                ],
                ['ddd, hA', 'ທິດ, 3ຕອນແລງ'],
                ['M Mo MM MMMM MMM', '2 ທີ່2 02 ກຸມພາ ກຸມພາ'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 ທີ່14 14'],
                ['d do dddd ddd dd', '0 ທີ່0 ອາທິດ ທິດ ທ'],
                ['DDD DDDo DDDD', '45 ທີ່45 045'],
                ['w wo ww', '8 ທີ່8 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'ຕອນແລງ ຕອນແລງ'],
                ['[ວັນ]DDDo [ຂອງປີ]', 'ວັນທີ່45 ຂອງປີ'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 ກຸມພາ 2010'],
                ['LLL', '14 ກຸມພາ 2010 15:25'],
                ['LLLL', 'ວັນອາທິດ 14 ກຸມພາ 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 ກຸມພາ 2010'],
                ['lll', '14 ກຸມພາ 2010 15:25'],
                ['llll', 'ວັນທິດ 14 ກຸມພາ 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), 'ທີ່1', 'ທີ່1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), 'ທີ່2', 'ທີ່2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), 'ທີ່3', 'ທີ່3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), 'ທີ່4', 'ທີ່4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), 'ທີ່5', 'ທີ່5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), 'ທີ່6', 'ທີ່6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), 'ທີ່7', 'ທີ່7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), 'ທີ່8', 'ທີ່8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), 'ທີ່9', 'ທີ່9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), 'ທີ່10', 'ທີ່10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), 'ທີ່11', 'ທີ່11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), 'ທີ່12', 'ທີ່12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), 'ທີ່13', 'ທີ່13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), 'ທີ່14', 'ທີ່14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), 'ທີ່15', 'ທີ່15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), 'ທີ່16', 'ທີ່16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), 'ທີ່17', 'ທີ່17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), 'ທີ່18', 'ທີ່18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), 'ທີ່19', 'ທີ່19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), 'ທີ່20', 'ທີ່20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), 'ທີ່21', 'ທີ່21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), 'ທີ່22', 'ທີ່22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), 'ທີ່23', 'ທີ່23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), 'ທີ່24', 'ທີ່24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), 'ທີ່25', 'ທີ່25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), 'ທີ່26', 'ທີ່26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), 'ທີ່27', 'ທີ່27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), 'ທີ່28', 'ທີ່28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), 'ທີ່29', 'ທີ່29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), 'ທີ່30', 'ທີ່30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), 'ທີ່31', 'ທີ່31');
    });

    test('format month', function (assert) {
        var expected = 'ມັງກອນ ມັງກອນ_ກຸມພາ ກຸມພາ_ມີນາ ມີນາ_ເມສາ ເມສາ_ພຶດສະພາ ພຶດສະພາ_ມິຖຸນາ ມິຖຸນາ_ກໍລະກົດ ກໍລະກົດ_ສິງຫາ ສິງຫາ_ກັນຍາ ກັນຍາ_ຕຸລາ ຕຸລາ_ພະຈິກ ພະຈິກ_ທັນວາ ທັນວາ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'ອາທິດ ທິດ ທ_ຈັນ ຈັນ ຈ_ອັງຄານ ອັງຄານ ອຄ_ພຸດ ພຸດ ພ_ພະຫັດ ພະຫັດ ພຫ_ສຸກ ສຸກ ສກ_ເສົາ ເສົາ ສ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ບໍ່ເທົ່າໃດວິນາທີ',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            '1 ນາທີ',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            '1 ນາທີ',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 ນາທີ',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 ນາທີ',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            '1 ຊົ່ວໂມງ',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            '1 ຊົ່ວໂມງ',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ຊົ່ວໂມງ',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ຊົ່ວໂມງ',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ຊົ່ວໂມງ',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            '1 ມື້',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            '1 ມື້',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 ມື້',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            '1 ມື້',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 ມື້',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 ມື້',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            '1 ເດືອນ',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            '1 ເດືອນ',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            '1 ເດືອນ',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 ເດືອນ',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 ເດືອນ',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 ເດືອນ',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            '1 ເດືອນ',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 ເດືອນ',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            '1 ປີ',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ປີ',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            '1 ປີ',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ປີ',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'ອີກ ບໍ່ເທົ່າໃດວິນາທີ', 'prefix');
        assert.equal(moment(0).from(30000), 'ບໍ່ເທົ່າໃດວິນາທີຜ່ານມາ', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'ບໍ່ເທົ່າໃດວິນາທີຜ່ານມາ',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'ອີກ ບໍ່ເທົ່າໃດວິນາທີ',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'ອີກ 5 ມື້', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'ມື້ນີ້ເວລາ 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'ມື້ນີ້ເວລາ 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'ມື້ນີ້ເວລາ 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'ມື້ອື່ນເວລາ 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'ມື້ນີ້ເວລາ 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ມື້ວານນີ້ເວລາ 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 ທີ່1',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 ທີ່1',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 ທີ່2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 ທີ່2',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 ທີ່3',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('lt');

    test('parse', function (assert) {
        var tests = 'sausis sau_vasaris vas_kovas kov_balandis bal_gegužė geg_birželis bir_liepa lie_rugpjūtis rgp_rugsėjis rgs_spalis spa_lapkritis lap_gruodis grd'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'sekmadienis, 14-oji vasario 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Sek, 3PM'],
                ['M Mo MM MMMM MMM', '2 2-oji 02 vasaris vas'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14-oji 14'],
                ['d do dddd ddd dd', '0 0-oji sekmadienis Sek S'],
                ['DDD DDDo DDDD', '45 45-oji 045'],
                ['w wo ww', '6 6-oji 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['DDDo [metų diena]', '45-oji metų diena'],
                ['LTS', '15:25:50'],
                ['L', '2010-02-14'],
                ['LL', '2010 m. vasario 14 d.'],
                ['LLL', '2010 m. vasario 14 d., 15:25 val.'],
                ['LLLL', '2010 m. vasario 14 d., sekmadienis, 15:25 val.'],
                ['l', '2010-02-14'],
                ['ll', '2010 m. vasario 14 d.'],
                ['lll', '2010 m. vasario 14 d., 15:25 val.'],
                ['llll', '2010 m. vasario 14 d., Sek, 15:25 val.'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-oji', '1-oji');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-oji', '2-oji');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-oji', '3-oji');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-oji', '4-oji');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-oji', '5-oji');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-oji', '6-oji');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-oji', '7-oji');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-oji', '8-oji');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-oji', '9-oji');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-oji', '10-oji');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-oji', '11-oji');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-oji', '12-oji');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-oji', '13-oji');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-oji', '14-oji');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-oji', '15-oji');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-oji', '16-oji');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-oji', '17-oji');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-oji', '18-oji');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-oji', '19-oji');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-oji', '20-oji');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-oji', '21-oji');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-oji', '22-oji');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-oji', '23-oji');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-oji', '24-oji');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-oji', '25-oji');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-oji', '26-oji');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-oji', '27-oji');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-oji', '28-oji');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-oji', '29-oji');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-oji', '30-oji');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-oji', '31-oji');
    });

    test('format month', function (assert) {
        var expected = 'sausis sau_vasaris vas_kovas kov_balandis bal_gegužė geg_birželis bir_liepa lie_rugpjūtis rgp_rugsėjis rgs_spalis spa_lapkritis lap_gruodis grd'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'sekmadienis Sek S_pirmadienis Pir P_antradienis Ant A_trečiadienis Tre T_ketvirtadienis Ket K_penktadienis Pen Pn_šeštadienis Šeš Š'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week on US calendar', function (assert) {
        // Tests, whether the weekday names are correct, even if the week does not start on Monday
        moment.updateLocale('lt', { week: { dow: 0, doy: 6 } });
        var expected = 'sekmadienis Sek S_pirmadienis Pir P_antradienis Ant A_trečiadienis Tre T_ketvirtadienis Ket K_penktadienis Pen Pn_šeštadienis Šeš Š'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
        moment.updateLocale('lt', null);
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'kelios sekundės',
            '44 seconds = seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'minutė',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'minutė',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutės',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 10 }), true),
            '10 minučių',
            '10 minutes = 10 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 11 }), true),
            '11 minučių',
            '11 minutes = 11 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 19 }), true),
            '19 minučių',
            '19 minutes = 19 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 20 }), true),
            '20 minučių',
            '20 minutes = 20 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutės',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'valanda',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'valanda',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 valandos',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 valandos',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 10 }), true),
            '10 valandų',
            '10 hours = 10 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 valandos',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'diena',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'diena',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dienos',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'diena',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dienos',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 10 }), true),
            '10 dienų',
            '10 days = 10 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dienos',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'mėnuo',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'mėnuo',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'mėnuo',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mėnesiai',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mėnesiai',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mėnesiai',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'mėnuo',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mėnesiai',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 10 }), true),
            '10 mėnesių',
            '10 months = 10 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'metai',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 metai',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'metai',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 metai',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'po kelių sekundžių', 'prefix');
        assert.equal(moment(0).from(30000), 'prieš kelias sekundes', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'prieš kelias sekundes',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'po kelių sekundžių',
            'in seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'po 5 dienų', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Šiandien 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Šiandien 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Šiandien 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Rytoj 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Šiandien 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Vakar 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Praėjusį] dddd LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Praėjusį] dddd LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Praėjusį] dddd LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52-oji',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1-oji',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1-oji',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2-oji',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2-oji',
            'Jan 15 2012 should be week 2'
        );
    });

    test('month cases', function (assert) {
        assert.equal(
            moment([2015, 4, 1]).format('LL'),
            '2015 m. gegužės 1 d.',
            'uses format instead of standalone form'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('lv');

    test('parse', function (assert) {
        var tests = 'janvāris jan_februāris feb_marts mar_aprīlis apr_maijs mai_jūnijs jūn_jūlijs jūl_augusts aug_septembris sep_oktobris okt_novembris nov_decembris dec'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'svētdiena, 14. februāris 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Sv, 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 februāris feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. svētdiena Sv Sv'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010.'],
                ['LL', '2010. gada 14. februāris'],
                ['LLL', '2010. gada 14. februāris, 15:25'],
                ['LLLL', '2010. gada 14. februāris, svētdiena, 15:25'],
                ['l', '14.2.2010.'],
                ['ll', '2010. gada 14. feb'],
                ['lll', '2010. gada 14. feb, 15:25'],
                ['llll', '2010. gada 14. feb, Sv, 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'janvāris jan_februāris feb_marts mar_aprīlis apr_maijs mai_jūnijs jūn_jūlijs jūl_augusts aug_septembris sep_oktobris okt_novembris nov_decembris dec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'svētdiena Sv Sv_pirmdiena P P_otrdiena O O_trešdiena T T_ceturtdiena C C_piektdiena Pk Pk_sestdiena S S'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    // Includes testing the cases of withoutSuffix = true and false.
    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'dažas sekundes',
            '44 seconds = seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), false),
            'pirms dažām sekundēm',
            '44 seconds with suffix = seconds ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'minūte',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), false),
            'pirms minūtes',
            '45 seconds with suffix = a minute ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'minūte',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: -89 }), false),
            'pēc minūtes',
            '89 seconds with suffix/prefix = in a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minūtes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), false),
            'pirms 2 minūtēm',
            '90 seconds with suffix = 2 minutes ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minūtes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), false),
            'pirms 44 minūtēm',
            '44 minutes with suffix = 44 minutes ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'stunda',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), false),
            'pirms stundas',
            '45 minutes with suffix = an hour ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'stunda',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 stundas',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: -90 }), false),
            'pēc 2 stundām',
            '90 minutes with suffix = in 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 stundas',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), false),
            'pirms 5 stundām',
            '5 hours with suffix = 5 hours ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 stunda',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), false),
            'pirms 21 stundas',
            '21 hours with suffix = 21 hours ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'diena',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), false),
            'pirms dienas',
            '22 hours with suffix = a day ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'diena',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dienas',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), false),
            'pirms 2 dienām',
            '36 hours with suffix = 2 days ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'diena',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dienas',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), false),
            'pirms 5 dienām',
            '5 days with suffix = 5 days ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dienas',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), false),
            'pirms 25 dienām',
            '25 days with suffix = 25 days ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'mēnesis',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), false),
            'pirms mēneša',
            '26 days with suffix = a month ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'mēnesis',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'mēnesis',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mēneši',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), false),
            'pirms 2 mēnešiem',
            '46 days with suffix = 2 months ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mēneši',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mēneši',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), false),
            'pirms 3 mēnešiem',
            '76 days with suffix = 3 months ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'mēnesis',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mēneši',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), false),
            'pirms 5 mēnešiem',
            '5 months with suffix = 5 months ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'gads',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), false),
            'pirms gada',
            '345 days with suffix = a year ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 gadi',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), false),
            'pirms 2 gadiem',
            '548 days with suffix = 2 years ago'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'gads',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 gadi',
            '5 years = 5 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), false),
            'pirms 5 gadiem',
            '5 years with suffix = 5 years ago'
        );

        // test that numbers ending with 1 are singular except for when they end with 11 in which case they are plural
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 11 }), true),
            '11 gadi',
            '11 years = 11 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 21 }), true),
            '21 gads',
            '21 year = 21 year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 211 }), true),
            '211 gadi',
            '211 years = 211 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 221 }), false),
            'pirms 221 gada',
            '221 year with suffix = 221 years ago'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'pēc dažām sekundēm', 'prefix');
        assert.equal(moment(0).from(30000), 'pirms dažām sekundēm', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'pirms dažām sekundēm',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'pēc dažām sekundēm',
            'in seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'pēc 5 dienām', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Šodien pulksten 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Šodien pulksten 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Šodien pulksten 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Rīt pulksten 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Šodien pulksten 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Vakar pulksten 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [pulksten] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [pulksten] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [pulksten] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Pagājušā] dddd [pulksten] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Pagājušā] dddd [pulksten] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Pagājušā] dddd [pulksten] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('me');

    test('parse', function (assert) {
        var tests = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'nedjelja, 14. februar 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'ned., 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 februar feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. nedjelja ned. ne'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '7 7. 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. februar 2010'],
                ['LLL', '14. februar 2010 15:25'],
                ['LLLL', 'nedjelja, 14. februar 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14. feb. 2010'],
                ['lll', '14. feb. 2010 15:25'],
                ['llll', 'ned., 14. feb. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'nekoliko sekundi',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'jedan minut',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'jedan minut',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuta',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuta',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'jedan sat',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'jedan sat',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 sata',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 sati',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 sati',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'dan',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'dan',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dana',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'dan',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dana',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dana',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'mjesec',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'mjesec',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'mjesec',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mjeseca',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mjeseca',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mjeseca',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'mjesec',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mjeseci',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'godinu',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 godine',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'godinu',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 godina',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'za nekoliko sekundi', 'prefix');
        assert.equal(moment(0).from(30000), 'prije nekoliko sekundi', 'prefix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'prije nekoliko sekundi',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'za nekoliko sekundi',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'za 5 dana', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'danas u 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'danas u 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'danas u 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'sjutra u 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'danas u 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'juče u 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                    return '[u] [nedjelju] [u] LT';
                case 3:
                    return '[u] [srijedu] [u] LT';
                case 6:
                    return '[u] [subotu] [u] LT';
                case 1:
                case 2:
                case 4:
                case 5:
                    return '[u] dddd [u] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        function makeFormat(d) {
            var lastWeekDay = [
                '[prošle] [nedjelje] [u] LT',
                '[prošlog] [ponedjeljka] [u] LT',
                '[prošlog] [utorka] [u] LT',
                '[prošle] [srijede] [u] LT',
                '[prošlog] [četvrtka] [u] LT',
                '[prošlog] [petka] [u] LT',
                '[prošle] [subote] [u] LT',
            ];

            return lastWeekDay[d.day()];
        }

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    // Monday is the first day of the week.
    // The week that contains Jan 1st is the first week of the year.

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1.',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1.',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2.',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2.',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3.',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('mi');

    test('parse', function (assert) {
        var tests = 'Kohi-tāte Kohi_Hui-tanguru Hui_Poutū-te-rangi Pou_Paenga-whāwhā Pae_Haratua Hara_Pipiri Pipi_Hōngoingoi Hōngoi_Here-turi-kōkā Here_Mahuru Mahu_Whiringa-ā-nuku Whi-nu_Whiringa-ā-rangi Whi-ra_Hakihea Haki'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Rātapu, Hui-tanguru 14º 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Ta, 3PM'],
                ['M Mo MM MMMM MMM', '2 2º 02 Hui-tanguru Hui'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14º 14'],
                ['d do dddd ddd dd', '0 0º Rātapu Ta Ta'],
                ['DDD DDDo DDDD', '45 45º 045'],
                ['w wo ww', '6 6º 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45º day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 Hui-tanguru 2010'],
                ['LLL', '14 Hui-tanguru 2010 i 15:25'],
                ['LLLL', 'Rātapu, 14 Hui-tanguru 2010 i 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Hui 2010'],
                ['lll', '14 Hui 2010 i 15:25'],
                ['llll', 'Ta, 14 Hui 2010 i 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');
    });

    test('format month', function (assert) {
        var expected = 'Kohi-tāte Kohi_Hui-tanguru Hui_Poutū-te-rangi Pou_Paenga-whāwhā Pae_Haratua Hara_Pipiri Pipi_Hōngoingoi Hōngoi_Here-turi-kōkā Here_Mahuru Mahu_Whiringa-ā-nuku Whi-nu_Whiringa-ā-rangi Whi-ra_Hakihea Haki'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Rātapu Ta Ta_Mane Ma Ma_Tūrei Tū Tū_Wenerei We We_Tāite Tāi Tāi_Paraire Pa Pa_Hātarei Hā Hā'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'te hēkona ruarua',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'he meneti',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'he meneti',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 meneti',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 meneti',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'te haora',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'te haora',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 haora',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 haora',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 haora',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'he ra',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'he ra',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 ra',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'he ra',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 ra',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 ra',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'he marama',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'he marama',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'he marama',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 marama',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 marama',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 marama',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'he marama',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 marama',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'he tau',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 tau',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'he tau',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 tau',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'i roto i te hēkona ruarua', 'prefix');
        assert.equal(moment(0).from(30000), 'te hēkona ruarua i mua', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'te hēkona ruarua i mua',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'i roto i te hēkona ruarua',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'i roto i 5 ra',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'i teie mahana, i 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'i teie mahana, i 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'i teie mahana, i 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'apopo i 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'i teie mahana, i 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'inanahi i 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [i] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [i] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [i] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [whakamutunga i] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [whakamutunga i] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [whakamutunga i] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52º',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1º',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1º',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2º',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2º',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('mk');

    test('parse', function (assert) {
        var tests = 'јануари јан_февруари фев_март мар_април апр_мај мај_јуни јун_јули јул_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, H:mm:ss',
                    'недела, февруари 14-ти 2010, 15:25:50',
                ],
                ['ddd, hA', 'нед, 3PM'],
                ['M Mo MM MMMM MMM', '2 2-ри 02 февруари фев'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14-ти 14'],
                ['d do dddd ddd dd', '0 0-ев недела нед нe'],
                ['DDD DDDo DDDD', '45 45-ти 045'],
                ['w wo ww', '7 7-ми 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45-ти day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 февруари 2010'],
                ['LLL', '14 февруари 2010 15:25'],
                ['LLLL', 'недела, 14 февруари 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 фев 2010'],
                ['lll', '14 фев 2010 15:25'],
                ['llll', 'нед, 14 фев 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ви', '1-ви');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ри', '2-ри');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ти', '3-ти');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ти', '4-ти');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ти', '5-ти');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ти', '6-ти');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ми', '7-ми');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ми', '8-ми');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ти', '9-ти');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ти', '10-ти');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ти', '11-ти');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ти', '12-ти');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ти', '13-ти');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ти', '14-ти');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ти', '15-ти');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ти', '16-ти');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ти', '17-ти');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ти', '18-ти');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ти', '19-ти');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ти', '20-ти');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ви', '21-ви');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ри', '22-ри');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ти', '23-ти');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ти', '24-ти');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ти', '25-ти');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ти', '26-ти');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ми', '27-ми');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ми', '28-ми');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ти', '29-ти');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ти', '30-ти');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ви', '31-ви');
    });

    test('format month', function (assert) {
        var expected = 'јануари јан_февруари фев_март мар_април апр_мај мај_јуни јун_јули јул_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'недела нед нe_понеделник пон пo_вторник вто вт_среда сре ср_четврток чет че_петок пет пе_сабота саб сa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'неколку секунди',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'една минута',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'една минута',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 минути',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 минути',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'еден час',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'еден час',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 часа',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 часа',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 часа',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'еден ден',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'еден ден',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 дена',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'еден ден',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 дена',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 дена',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'еден месец',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'еден месец',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'еден месец',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 месеци',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 месеци',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 месеци',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'еден месец',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 месеци',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'една година',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 години',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'една година',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 години',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'за неколку секунди', 'prefix');
        assert.equal(moment(0).from(30000), 'пред неколку секунди', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'пред неколку секунди',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'за неколку секунди',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'за 5 дена', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Денес во 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Денес во 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Денес во 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Утре во 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Денес во 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Вчера во 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Во] dddd [во] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Во] dddd [во] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Во] dddd [во] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                case 3:
                case 6:
                    return '[Изминатата] dddd [во] LT';
                case 1:
                case 2:
                case 4:
                case 5:
                    return '[Изминатиот] dddd [во] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1-ви',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1-ви',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2-ри',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2-ри',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3-ти',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ml');

    test('parse', function (assert) {
        var tests = 'ജനുവരി ജനു._ഫെബ്രുവരി ഫെബ്രു._മാർച്ച് മാർ._ഏപ്രിൽ ഏപ്രി._മേയ് മേയ്_ജൂൺ ജൂൺ_ജൂലൈ ജൂലൈ._ഓഗസ്റ്റ് ഓഗ._സെപ്റ്റംബർ സെപ്റ്റ._ഒക്ടോബർ ഒക്ടോ._നവംബർ നവം._ഡിസംബർ ഡിസം.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, a h:mm:ss -നു',
                    'ഞായറാഴ്ച, 14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25:50 -നു',
                ],
                ['ddd, a h -നു', 'ഞായർ, ഉച്ച കഴിഞ്ഞ് 3 -നു'],
                ['M Mo MM MMMM MMM', '2 2 02 ഫെബ്രുവരി ഫെബ്രു.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 ഞായറാഴ്ച ഞായർ ഞാ'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '8 8 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'ഉച്ച കഴിഞ്ഞ് ഉച്ച കഴിഞ്ഞ്'],
                ['LTS', 'ഉച്ച കഴിഞ്ഞ് 3:25:50 -നു'],
                ['L', '14/02/2010'],
                ['LL', '14 ഫെബ്രുവരി 2010'],
                ['LLL', '14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],
                ['LLLL', 'ഞായറാഴ്ച, 14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],
                ['l', '14/2/2010'],
                ['ll', '14 ഫെബ്രു. 2010'],
                ['lll', '14 ഫെബ്രു. 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],
                ['llll', 'ഞായർ, 14 ഫെബ്രു. 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'ജനുവരി ജനു._ഫെബ്രുവരി ഫെബ്രു._മാർച്ച് മാർ._ഏപ്രിൽ ഏപ്രി._മേയ് മേയ്_ജൂൺ ജൂൺ_ജൂലൈ ജൂലൈ._ഓഗസ്റ്റ് ഓഗ._സെപ്റ്റംബർ സെപ്റ്റ._ഒക്ടോബർ ഒക്ടോ._നവംബർ നവം._ഡിസംബർ ഡിസം.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'ഞായറാഴ്ച ഞായർ ഞാ_തിങ്കളാഴ്ച തിങ്കൾ തി_ചൊവ്വാഴ്ച ചൊവ്വ ചൊ_ബുധനാഴ്ച ബുധൻ ബു_വ്യാഴാഴ്ച വ്യാഴം വ്യാ_വെള്ളിയാഴ്ച വെള്ളി വെ_ശനിയാഴ്ച ശനി ശ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'അൽപ നിമിഷങ്ങൾ',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ഒരു മിനിറ്റ്',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ഒരു മിനിറ്റ്',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 മിനിറ്റ്',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 മിനിറ്റ്',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ഒരു മണിക്കൂർ',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ഒരു മണിക്കൂർ',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 മണിക്കൂർ',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 മണിക്കൂർ',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 മണിക്കൂർ',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ഒരു ദിവസം',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ഒരു ദിവസം',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 ദിവസം',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ഒരു ദിവസം',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 ദിവസം',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 ദിവസം',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ഒരു മാസം',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ഒരു മാസം',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ഒരു മാസം',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 മാസം',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 മാസം',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 മാസം',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ഒരു മാസം',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 മാസം',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ഒരു വർഷം',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 വർഷം',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ഒരു വർഷം',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 വർഷം',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്', 'prefix');
        assert.equal(moment(0).from(30000), 'അൽപ നിമിഷങ്ങൾ മുൻപ്', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'അൽപ നിമിഷങ്ങൾ മുൻപ്',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്',
            'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            '5 ദിവസം കഴിഞ്ഞ്',
            '5 ദിവസം കഴിഞ്ഞ്'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 12:00 -നു',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 12:25 -നു',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 3 }).calendar(),
            'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 3:00 -നു',
            'Now plus 3 hours'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'നാളെ ഉച്ച കഴിഞ്ഞ് 12:00 -നു',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'ഇന്ന് രാവിലെ 11:00 -നു',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ഇന്നലെ ഉച്ച കഴിഞ്ഞ് 12:00 -നു',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[കഴിഞ്ഞ] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[കഴിഞ്ഞ] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[കഴിഞ്ഞ] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('a'),
            'രാത്രി',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('a'), 'രാവിലെ', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('a'),
            'ഉച്ച കഴിഞ്ഞ്',
            'during day'
        );
        assert.equal(
            moment([2011, 2, 23, 17, 30]).format('a'),
            'വൈകുന്നേരം',
            'evening'
        );
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('a'),
            'വൈകുന്നേരം',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'രാത്രി', 'night');

        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('A'),
            'രാത്രി',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('A'), 'രാവിലെ', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('A'),
            'ഉച്ച കഴിഞ്ഞ്',
            ' during day'
        );
        assert.equal(
            moment([2011, 2, 23, 17, 30]).format('A'),
            'വൈകുന്നേരം',
            'evening'
        );
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('A'),
            'വൈകുന്നേരം',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'രാത്രി', 'night');
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('mn');

    test('parse', function (assert) {
        var i,
            tests = 'Нэгдүгээр сар-1 сар_Хоёрдугаар сар-2 сар_Гуравдугаар сар-3 сар_Дөрөвдүгээр сар-4 сар_Тавдугаар сар-5 сар_Зургадугаар сар-6 сар_Долдугаар сар-7 сар_Наймдугаар сар-8 сар_Есдүгээр сар-9 сар_Аравдугаар сар-10 сар_Арван нэгдүгээр сар-11 сар_Арван хоёрдугаар сар-12 сар'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split('-');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }

        assert.equal(
            moment('5 сар 11 1989', ['MMM DD YYYY']).format('YYYY-MM-DD'),
            '1989-05-11'
        );
        assert.equal(
            moment('1989 он, Арван хоёрдугаар сар 11', [
                'YYYY [он], MMMM DD',
            ]).format('YYYY-MM-DD'),
            '1989-12-11'
        );
        assert.equal(
            moment('1989 оны 11 сарын 2', ['YYYY [оны] MMMM[ын] DD']).format(
                'YYYY-MM-D'
            ),
            '1989-11-2'
        );
        assert.equal(
            moment('1989 оны 5 сарын 11 өдөр', ['YYYY [оны] MMMM[ын] Do']).format(
                'YYYY-MM-DD'
            ),
            '1989-05-11'
        );
        assert.equal(
            moment('1989 оны 5 сарын 11 өдөр 11:25 ҮӨ', [
                'YYYY [оны] MMM[ын] Do h:mm a',
            ]).format('YYYY-MM-DD h:mm a'),
            '1989-05-11 11:25 ҮӨ'
        );
        assert.equal(
            moment('2003 оны Дөрөвдүгээр сарын 11 өдөр 17:25 ҮХ', [
                'YYYY [оны] MMMM[ын] Do HH:mm a',
            ]).format('YYYY-MM-DD HH:mm a'),
            '2003-04-11 17:25 ҮХ'
        );
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM[ын] Do YYYY, h:mm:ss a',
                    'Ням, Хоёрдугаар сарын 14 өдөр 2010, 3:25:50 ҮХ',
                ],
                ['ddd, hA', 'Ням, 3ҮХ'],
                ['M Mo MM MMMM MMM', '2 2 02 Хоёрдугаар сар 2 сар'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 өдөр 14'],
                ['d do dddd ddd dd', '0 0 өдөр Ням Ням Ня'],
                ['DDD DDDo DDDD', '45 45 өдөр 045'],
                ['w wo ww', '8 8 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'ҮХ ҮХ'],
                ['[the] DDDo [day of the year]', 'the 45 өдөр day of the year'],
                ['LTS', '15:25:50'],
                ['L', '2010-02-14'],
                ['LL', '2010 оны Хоёрдугаар сарын 14'],
                ['LLL', '2010 оны Хоёрдугаар сарын 14 15:25'],
                ['LLLL', 'Ням, 2010 оны Хоёрдугаар сарын 14 15:25'],
                ['l', '2010-2-14'],
                ['ll', '2010 оны 2 сарын 14'],
                ['lll', '2010 оны 2 сарын 14 15:25'],
                ['llll', 'Ням, 2010 оны 2 сарын 14 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format meridiem', function (assert) {
        assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ҮӨ', 'AM');
        assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'ҮӨ', 'AM');
        assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'ҮХ', 'PM');
        assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'ҮХ', 'PM');
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1 өдөр', '1st');
    });

    test('format month', function (assert) {
        var i,
            expected = 'Нэгдүгээр сар 1 сар_Хоёрдугаар сар 2 сар_Гуравдугаар сар 3 сар_Дөрөвдүгээр сар 4 сар_Тавдугаар сар 5 сар_Зургадугаар сар 6 сар_Долдугаар сар 7 сар_Наймдугаар сар 8 сар_Есдүгээр сар 9 сар_Аравдугаар сар 10 сар_Арван нэгдүгээр сар 11 сар_Арван хоёрдугаар сар 12 сар'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'Ням Ням Ня_Даваа Дав Да_Мягмар Мяг Мя_Лхагва Лха Лх_Пүрэв Пүр Пү_Баасан Баа Ба_Бямба Бям Бя'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'хэдхэн секунд',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            '1 минут',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            '1 минут',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 минут',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 минут',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            '1 цаг',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            '1 цаг',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 цаг',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 цаг',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 цаг',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            '1 өдөр',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            '1 өдөр',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 өдөр',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            '1 өдөр',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 өдөр',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 өдөр',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            '1 сар',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            '1 сар',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            '1 сар',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 сар',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 сар',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 сар',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            '1 сар',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 сар',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            '1 жил',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 жил',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            '1 жил',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 жил',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'хэдхэн секундын дараа', 'prefix');
        assert.equal(moment(0).from(30000), 'хэдхэн секундын өмнө', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'хэдхэн секундын өмнө',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'хэдхэн секундын дараа',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ s: 50 }).fromNow(),
            '1 минутын дараа',
            'in a minute'
        );
        assert.equal(
            moment().add({ m: 5 }).fromNow(),
            '5 минутын дараа',
            'in 5 minutes'
        );
        assert.equal(
            moment().add({ h: 2 }).fromNow(),
            '2 цагийн дараа',
            'in 2 hours'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            '5 өдрийн дараа',
            'in 5 days'
        );
        assert.equal(
            moment().add({ M: 2 }).fromNow(),
            '2 сарын дараа',
            'in 2 months'
        );
        assert.equal(
            moment().add({ M: 15 }).fromNow(),
            '1 жилийн дараа',
            'in a year'
        );
        assert.equal(
            moment().add({ M: 16 }).fromNow(),
            '1 жилийн дараа',
            'in a year'
        );
        assert.equal(
            moment().add({ M: 23 }).fromNow(),
            '2 жилийн дараа',
            'in 2 years'
        );
        assert.equal(
            moment().add({ y: 7 }).fromNow(),
            '7 жилийн дараа',
            'in 7 years'
        );

        assert.equal(
            moment().subtract({ s: 30 }).fromNow(),
            'хэдхэн секундын өмнө',
            'a few seconds ago'
        );
        assert.equal(
            moment().subtract({ s: 50 }).fromNow(),
            '1 минутын өмнө',
            'a minute ago'
        );
        assert.equal(
            moment().subtract({ m: 5 }).fromNow(),
            '5 минутын өмнө',
            '5 minutes ago'
        );
        assert.equal(
            moment().subtract({ h: 2 }).fromNow(),
            '2 цагийн өмнө',
            '2 hours ago'
        );
        assert.equal(
            moment().subtract({ d: 5 }).fromNow(),
            '5 өдрийн өмнө',
            '5 days ago'
        );
        assert.equal(
            moment().subtract({ M: 2 }).fromNow(),
            '2 сарын өмнө',
            '2 months ago'
        );
        assert.equal(
            moment().subtract({ M: 15 }).fromNow(),
            '1 жилийн өмнө',
            'a year ago'
        );
        assert.equal(
            moment().subtract({ M: 16 }).fromNow(),
            '1 жилийн өмнө',
            'a year ago'
        );
        assert.equal(
            moment().subtract({ M: 23 }).fromNow(),
            '2 жилийн өмнө',
            '2 years ago'
        );
        assert.equal(
            moment().subtract({ y: 7 }).fromNow(),
            '7 жилийн өмнө',
            '7 years ago'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Өнөөдөр 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Өнөөдөр 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Өнөөдөр 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Маргааш 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Өнөөдөр 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Өчигдөр 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Ирэх] dddd LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Ирэх] dddd LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Ирэх] dddd LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Өнгөрсөн] dddd LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Өнгөрсөн] dddd LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Өнгөрсөн] dddd LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('mr');

    test('parse', function (assert) {
        var tests = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च._एप्रिल एप्रि._मे मे._जून जून._जुलै जुलै._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, a h:mm:ss वाजता',
                    'रविवार, १४ फेब्रुवारी २०१०, दुपारी ३:२५:५० वाजता',
                ],
                ['ddd, a h वाजता', 'रवि, दुपारी ३ वाजता'],
                ['M Mo MM MMMM MMM', '२ २ ०२ फेब्रुवारी फेब्रु.'],
                ['YYYY YY', '२०१० १०'],
                ['D Do DD', '१४ १४ १४'],
                ['d do dddd ddd dd', '० ० रविवार रवि र'],
                ['DDD DDDo DDDD', '४५ ४५ ०४५'],
                ['w wo ww', '८ ८ ०८'],
                ['h hh', '३ ०३'],
                ['H HH', '१५ १५'],
                ['m mm', '२५ २५'],
                ['s ss', '५० ५०'],
                ['a A', 'दुपारी दुपारी'],
                ['LTS', 'दुपारी ३:२५:५० वाजता'],
                ['L', '१४/०२/२०१०'],
                ['LL', '१४ फेब्रुवारी २०१०'],
                ['LLL', '१४ फेब्रुवारी २०१०, दुपारी ३:२५ वाजता'],
                ['LLLL', 'रविवार, १४ फेब्रुवारी २०१०, दुपारी ३:२५ वाजता'],
                ['l', '१४/२/२०१०'],
                ['ll', '१४ फेब्रु. २०१०'],
                ['lll', '१४ फेब्रु. २०१०, दुपारी ३:२५ वाजता'],
                ['llll', 'रवि, १४ फेब्रु. २०१०, दुपारी ३:२५ वाजता'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');
    });

    test('format month', function (assert) {
        var expected = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च._एप्रिल एप्रि._मे मे._जून जून._जुलै जुलै._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'रविवार रवि र_सोमवार सोम सो_मंगळवार मंगळ मं_बुधवार बुध बु_गुरूवार गुरू गु_शुक्रवार शुक्र शु_शनिवार शनि श'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'काही सेकंद',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'एक मिनिट',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'एक मिनिट',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '२ मिनिटे',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '४४ मिनिटे',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'एक तास',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'एक तास',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '२ तास',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '५ तास',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '२१ तास',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'एक दिवस',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'एक दिवस',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '२ दिवस',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'एक दिवस',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '५ दिवस',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '२५ दिवस',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'एक महिना',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'एक महिना',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'एक महिना',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '२ महिने',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '२ महिने',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '३ महिने',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'एक महिना',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '५ महिने',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'एक वर्ष',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '२ वर्षे',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'एक वर्ष',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '५ वर्षे',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'काही सेकंदांमध्ये', 'prefix');
        assert.equal(moment(0).from(30000), 'काही सेकंदांपूर्वी', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'काही सेकंदांपूर्वी',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'काही सेकंदांमध्ये',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            '५ दिवसांमध्ये',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'आज दुपारी १२:०० वाजता',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'आज दुपारी १२:२५ वाजता',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 3 }).calendar(),
            'आज दुपारी ३:०० वाजता',
            'Now plus 3 hours'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'उद्या दुपारी १२:०० वाजता',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'आज सकाळी ११:०० वाजता',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'काल दुपारी १२:०० वाजता',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[मागील] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[मागील] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[मागील] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('a'),
            'पहाटे',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('a'), 'सकाळी', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('a'),
            'दुपारी',
            'during day'
        );
        assert.equal(
            moment([2011, 2, 23, 17, 30]).format('a'),
            'सायंकाळी',
            'evening'
        );
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('a'),
            'सायंकाळी',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'रात्री', 'night');

        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('A'),
            'पहाटे',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('A'), 'सकाळी', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('A'),
            'दुपारी',
            ' during day'
        );
        assert.equal(
            moment([2011, 2, 23, 17, 30]).format('A'),
            'सायंकाळी',
            'evening'
        );
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('A'),
            'सायंकाळी',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'रात्री', 'night');
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '१ ०१ १',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '१ ०१ १',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '२ ०२ २',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '२ ०२ २',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '३ ०३ ३',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ms-my');

    test('parse', function (assert) {
        var i,
            tests = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' sepatutnya bulan ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Ahad, Februari 14 2010, 3:25:50 petang',
                ],
                ['ddd, hA', 'Ahd, 3petang'],
                ['M Mo MM MMMM MMM', '2 2 02 Februari Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Ahad Ahd Ah'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '7 7 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'petang petang'],
                ['[hari] [ke] DDDo [tahun] ini', 'hari ke 45 tahun ini'],
                ['LTS', '15.25.50'],
                ['L', '14/02/2010'],
                ['LL', '14 Februari 2010'],
                ['LLL', '14 Februari 2010 pukul 15.25'],
                ['LLLL', 'Ahad, 14 Februari 2010 pukul 15.25'],
                ['l', '14/2/2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 pukul 15.25'],
                ['llll', 'Ahd, 14 Feb 2010 pukul 15.25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var i,
            expected = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'Ahad Ahd Ah_Isnin Isn Is_Selasa Sel Sl_Rabu Rab Rb_Khamis Kha Km_Jumaat Jum Jm_Sabtu Sab Sb'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'beberapa saat',
            '44 saat = beberapa saat'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'seminit',
            '45 saat = seminit'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'seminit',
            '89 saat = seminit'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minit',
            '90 saat = 2 minit'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minit',
            '44 minit = 44 minit'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'sejam',
            '45 minit = sejam'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'sejam',
            '89 minit = sejam'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 jam',
            '90 minit = 2 jam'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 jam',
            '5 jam = 5 jam'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 jam',
            '21 jam = 21 jam'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'sehari',
            '22 jam = sehari'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'sehari',
            '35 jam = sehari'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 hari',
            '36 jam = 2 hari'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'sehari',
            '1 hari = sehari'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 hari',
            '5 hari = 5 hari'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 hari',
            '25 hari = 25 hari'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'sebulan',
            '26 hari = sebulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'sebulan',
            '30 hari = sebulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'sebulan',
            '45 hari = sebulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 bulan',
            '46 hari = 2 bulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 bulan',
            '75 hari = 2 bulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 bulan',
            '76 hari = 3 bulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'sebulan',
            '1 bulan = sebulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 bulan',
            '5 bulan = 5 bulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'setahun',
            '345 hari = setahun'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 tahun',
            '548 hari = 2 tahun'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'setahun',
            '1 tahun = setahun'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 tahun',
            '5 tahun = 5 tahun'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'dalam beberapa saat', 'prefix');
        assert.equal(moment(0).from(30000), 'beberapa saat yang lepas', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'beberapa saat yang lepas',
            'waktu sekarang dari sekarang sepatutnya menunjukkan sebagai telah lepas'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'dalam beberapa saat',
            'dalam beberapa saat'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'dalam 5 hari',
            'dalam 5 hari'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Hari ini pukul 12.00',
            'hari ini pada waktu yang sama'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Hari ini pukul 12.25',
            'Sekarang tambah 25 minit'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Hari ini pukul 13.00',
            'Sekarang tambah 1 jam'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Esok pukul 12.00',
            'esok pada waktu yang sama'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Hari ini pukul 11.00',
            'Sekarang tolak 1 jam'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Kelmarin pukul 12.00',
            'kelmarin pada waktu yang sama'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [pukul] LT'),
                'Hari ini + ' + i + ' hari waktu sekarang'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [pukul] LT'),
                'Hari ini + ' + i + ' hari permulaan hari'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [pukul] LT'),
                'Hari ini + ' + i + ' hari tamat hari'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [lepas] [pukul] LT'),
                'Hari ini - ' + i + ' hari waktu sekarang'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [lepas] [pukul] LT'),
                'Hari ini - ' + i + ' hari permulaan hari'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [lepas] [pukul] LT'),
                'Hari ini - ' + i + ' hari tamat hari'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 minggu lepas');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'dalam 1 minggu'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 minggu lepas');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'dalam 2 minggu'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 sepatutnya minggu 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '2 02 2',
            'Jan  7 2012 sepatutnya minggu 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 sepatutnya minggu 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '3 03 3',
            'Jan 14 2012 sepatutnya minggu 3'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3',
            'Jan 15 2012 sepatutnya minggu 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ms');

    test('parse', function (assert) {
        var i,
            tests = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' sepatutnya bulan ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Ahad, Februari 14 2010, 3:25:50 petang',
                ],
                ['ddd, hA', 'Ahd, 3petang'],
                ['M Mo MM MMMM MMM', '2 2 02 Februari Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Ahad Ahd Ah'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '7 7 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'petang petang'],
                ['[hari] [ke] DDDo [tahun] ini', 'hari ke 45 tahun ini'],
                ['LTS', '15.25.50'],
                ['L', '14/02/2010'],
                ['LL', '14 Februari 2010'],
                ['LLL', '14 Februari 2010 pukul 15.25'],
                ['LLLL', 'Ahad, 14 Februari 2010 pukul 15.25'],
                ['l', '14/2/2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 pukul 15.25'],
                ['llll', 'Ahd, 14 Feb 2010 pukul 15.25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var i,
            expected = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'Ahad Ahd Ah_Isnin Isn Is_Selasa Sel Sl_Rabu Rab Rb_Khamis Kha Km_Jumaat Jum Jm_Sabtu Sab Sb'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'beberapa saat',
            '44 saat = beberapa saat'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'seminit',
            '45 saat = seminit'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'seminit',
            '89 saat = seminit'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minit',
            '90 saat = 2 minit'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minit',
            '44 minit = 44 minit'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'sejam',
            '45 minit = sejam'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'sejam',
            '89 minit = sejam'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 jam',
            '90 minit = 2 jam'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 jam',
            '5 jam = 5 jam'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 jam',
            '21 jam = 21 jam'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'sehari',
            '22 jam = sehari'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'sehari',
            '35 jam = sehari'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 hari',
            '36 jam = 2 hari'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'sehari',
            '1 hari = sehari'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 hari',
            '5 hari = 5 hari'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 hari',
            '25 hari = 25 hari'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'sebulan',
            '26 hari = sebulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'sebulan',
            '30 hari = sebulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'sebulan',
            '45 hari = sebulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 bulan',
            '46 hari = 2 bulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 bulan',
            '75 hari = 2 bulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 bulan',
            '76 hari = 3 bulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'sebulan',
            '1 bulan = sebulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 bulan',
            '5 bulan = 5 bulan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'setahun',
            '345 hari = setahun'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 tahun',
            '548 hari = 2 tahun'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'setahun',
            '1 tahun = setahun'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 tahun',
            '5 tahun = 5 tahun'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'dalam beberapa saat', 'prefix');
        assert.equal(moment(0).from(30000), 'beberapa saat yang lepas', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'beberapa saat yang lepas',
            'waktu sekarang dari sekarang sepatutnya menunjukkan sebagai telah lepas'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'dalam beberapa saat',
            'dalam beberapa saat'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'dalam 5 hari',
            'dalam 5 hari'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Hari ini pukul 12.00',
            'hari ini pada waktu yang sama'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Hari ini pukul 12.25',
            'Sekarang tambah 25 minit'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Hari ini pukul 13.00',
            'Sekarang tambah 1 jam'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Esok pukul 12.00',
            'esok pada waktu yang sama'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Hari ini pukul 11.00',
            'Sekarang tolak 1 jam'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Kelmarin pukul 12.00',
            'kelmarin pada waktu yang sama'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [pukul] LT'),
                'Hari ini + ' + i + ' hari waktu sekarang'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [pukul] LT'),
                'Hari ini + ' + i + ' hari permulaan hari'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [pukul] LT'),
                'Hari ini + ' + i + ' hari tamat hari'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [lepas] [pukul] LT'),
                'Hari ini - ' + i + ' hari waktu sekarang'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [lepas] [pukul] LT'),
                'Hari ini - ' + i + ' hari permulaan hari'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [lepas] [pukul] LT'),
                'Hari ini - ' + i + ' hari tamat hari'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 minggu lepas');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'dalam 1 minggu'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 minggu lepas');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'dalam 2 minggu'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 sepatutnya minggu 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '2 02 2',
            'Jan  7 2012 sepatutnya minggu 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 sepatutnya minggu 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '3 03 3',
            'Jan 14 2012 sepatutnya minggu 3'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3',
            'Jan 15 2012 sepatutnya minggu 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('mt');

    test('parse', function (assert) {
        var tests = 'Jannar Jan_Frar Fra_Marzu Mar_April Apr_Mejju Mej_Ġunju Ġun_Lulju Lul_Awwissu Aww_Settembru Set_Ottubru Ott_Novembru Nov_Diċembru Diċ'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Il-Ħadd, Frar 14º 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Ħad, 3PM'],
                ['M Mo MM MMMM MMM', '2 2º 02 Frar Fra'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14º 14'],
                ['d do dddd ddd dd', '0 0º Il-Ħadd Ħad Ħa'],
                ['DDD DDDo DDDD', '45 45º 045'],
                ['w wo ww', '6 6º 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45º day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 Frar 2010'],
                ['LLL', '14 Frar 2010 15:25'],
                ['LLLL', 'Il-Ħadd, 14 Frar 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Fra 2010'],
                ['lll', '14 Fra 2010 15:25'],
                ['llll', 'Ħad, 14 Fra 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');
    });

    test('format month', function (assert) {
        var expected = 'Jannar Jan_Frar Fra_Marzu Mar_April Apr_Mejju Mej_Ġunju Ġun_Lulju Lul_Awwissu Aww_Settembru Set_Ottubru Ott_Novembru Nov_Diċembru Diċ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Il-Ħadd Ħad Ħa_It-Tnejn Tne Tn_It-Tlieta Tli Tl_L-Erbgħa Erb Er_Il-Ħamis Ħam Ħa_Il-Ġimgħa Ġim Ġi_Is-Sibt Sib Si'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ftit sekondi',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'minuta',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'minuta',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuti',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuti',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'siegħa',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'siegħa',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 siegħat',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 siegħat',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 siegħat',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ġurnata',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ġurnata',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 ġranet',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ġurnata',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 ġranet',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 ġranet',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'xahar',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'xahar',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'xahar',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 xhur',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 xhur',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 xhur',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'xahar',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 xhur',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'sena',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 sni',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'sena',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 sni',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'f’ ftit sekondi', 'prefix');
        assert.equal(moment(0).from(30000), 'ftit sekondi ilu', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'ftit sekondi ilu',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'f’ ftit sekondi',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'f’ 5 ġranet', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Illum fil-12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Illum fil-12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Illum fil-13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Għada fil-12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Illum fil-11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Il-bieraħ fil-12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [fil-]LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [fil-]LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [fil-]LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [li għadda] [fil-]LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [li għadda] [fil-]LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [li għadda] [fil-]LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52º',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1º',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1º',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2º',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2º',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('my');

    test('parse', function (assert) {
        var tests = 'ဇန်နဝါရီ ဇန်_ဖေဖော်ဝါရီ ဖေ_မတ် မတ်_ဧပြီ ပြီ_မေ မေ_ဇွန် ဇွန်_ဇူလိုင် လိုင်_သြဂုတ် သြ_စက်တင်ဘာ စက်_အောက်တိုဘာ အောက်_နိုဝင်ဘာ နို_ဒီဇင်ဘာ ဒီ'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'တနင်္ဂနွေ, ဖေဖော်ဝါရီ ၁၄ ၂၀၁၀, ၃:၂၅:၅၀ pm',
                ],
                ['ddd, hA', 'နွေ, ၃PM'],
                ['M Mo MM MMMM MMM', '၂ ၂ ၀၂ ဖေဖော်ဝါရီ ဖေ'],
                ['YYYY YY', '၂၀၁၀ ၁၀'],
                ['D Do DD', '၁၄ ၁၄ ၁၄'],
                ['d do dddd ddd dd', '၀ ၀ တနင်္ဂနွေ နွေ နွေ'],
                ['DDD DDDo DDDD', '၄၅ ၄၅ ၀၄၅'],
                ['w wo ww', '၆ ၆ ၀၆'],
                ['h hh', '၃ ၀၃'],
                ['H HH', '၁၅ ၁၅'],
                ['m mm', '၂၅ ၂၅'],
                ['s ss', '၅၀ ၅၀'],
                ['a A', 'pm PM'],
                ['[နှစ်၏] DDDo [ရက်မြောက်]', 'နှစ်၏ ၄၅ ရက်မြောက်'],
                ['LTS', '၁၅:၂၅:၅၀'],
                ['L', '၁၄/၀၂/၂၀၁၀'],
                ['LL', '၁၄ ဖေဖော်ဝါရီ ၂၀၁၀'],
                ['LLL', '၁၄ ဖေဖော်ဝါရီ ၂၀၁၀ ၁၅:၂၅'],
                ['LLLL', 'တနင်္ဂနွေ ၁၄ ဖေဖော်ဝါရီ ၂၀၁၀ ၁၅:၂၅'],
                ['l', '၁၄/၂/၂၀၁၀'],
                ['ll', '၁၄ ဖေ ၂၀၁၀'],
                ['lll', '၁၄ ဖေ ၂၀၁၀ ၁၅:၂၅'],
                ['llll', 'နွေ ၁၄ ဖေ ၂၀၁၀ ၁၅:၂၅'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '၁', '၁');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '၂', '၂');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '၃', '၃');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '၄', '၄');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '၅', '၅');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '၆', '၆');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '၇', '၇');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '၈', '၈');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '၉', '၉');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '၁၀', '၁၀');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '၁၁', '၁၁');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '၁၂', '၁၂');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '၁၃', '၁၃');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '၁၄', '၁၄');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '၁၅', '၁၅');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '၁၆', '၁၆');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '၁၇', '၁၇');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '၁၈', '၁၈');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '၁၉', '၁၉');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '၂၀', '၂၀');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '၂၁', '၂၁');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '၂၂', '၂၂');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '၂၃', '၂၃');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '၂၄', '၂၄');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '၂၅', '၂၅');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '၂၆', '၂၆');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '၂၇', '၂၇');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '၂၈', '၂၈');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '၂၉', '၂၉');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '၃၀', '၃၀');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '၃၁', '၃၁');
    });

    test('format month', function (assert) {
        var expected = 'ဇန်နဝါရီ ဇန်_ဖေဖော်ဝါရီ ဖေ_မတ် မတ်_ဧပြီ ပြီ_မေ မေ_ဇွန် ဇွန်_ဇူလိုင် လိုင်_သြဂုတ် သြ_စက်တင်ဘာ စက်_အောက်တိုဘာ အောက်_နိုဝင်ဘာ နို_ဒီဇင်ဘာ ဒီ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'တနင်္ဂနွေ နွေ နွေ_တနင်္လာ လာ လာ_အင်္ဂါ ဂါ ဂါ_ဗုဒ္ဓဟူး ဟူး ဟူး_ကြာသပတေး ကြာ ကြာ_သောကြာ သော သော_စနေ နေ နေ'.split(
                '_'
            ),
            i;

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    s: 44,
                }),
                true
            ),
            'စက္ကန်.အနည်းငယ်',
            '၄၄ စက္ကန်. = စက္ကန်.အနည်းငယ်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    s: 45,
                }),
                true
            ),
            'တစ်မိနစ်',
            '၄၅ စက္ကန်. = တစ်မိနစ်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    s: 89,
                }),
                true
            ),
            'တစ်မိနစ်',
            '၈၉ စက္ကန်. = တစ်မိနစ်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    s: 90,
                }),
                true
            ),
            '၂ မိနစ်',
            '၉၀ စက္ကန်. =  ၂ မိနစ်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    m: 44,
                }),
                true
            ),
            '၄၄ မိနစ်',
            '၄၄ မိနစ် = ၄၄ မိနစ်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    m: 45,
                }),
                true
            ),
            'တစ်နာရီ',
            '၄၅ မိနစ် = ၁ နာရီ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    m: 89,
                }),
                true
            ),
            'တစ်နာရီ',
            '၈၉ မိနစ် = တစ်နာရီ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    m: 90,
                }),
                true
            ),
            '၂ နာရီ',
            'မိနစ် ၉၀= ၂ နာရီ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    h: 5,
                }),
                true
            ),
            '၅ နာရီ',
            '၅ နာရီ= ၅ နာရီ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    h: 21,
                }),
                true
            ),
            '၂၁ နာရီ',
            '၂၁ နာရီ =၂၁ နာရီ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    h: 22,
                }),
                true
            ),
            'တစ်ရက်',
            '၂၂ နာရီ =တစ်ရက်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    h: 35,
                }),
                true
            ),
            'တစ်ရက်',
            '၃၅ နာရီ =တစ်ရက်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    h: 36,
                }),
                true
            ),
            '၂ ရက်',
            '၃၆ နာရီ = ၂ ရက်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 1,
                }),
                true
            ),
            'တစ်ရက်',
            '၁ ရက်= တစ်ရက်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 5,
                }),
                true
            ),
            '၅ ရက်',
            '၅ ရက် = ၅ ရက်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 25,
                }),
                true
            ),
            '၂၅ ရက်',
            '၂၅ ရက်= ၂၅ ရက်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 26,
                }),
                true
            ),
            'တစ်လ',
            '၂၆ ရက် = တစ်လ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 30,
                }),
                true
            ),
            'တစ်လ',
            'ရက် ၃၀ = တစ်လ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 43,
                }),
                true
            ),
            'တစ်လ',
            '၄၃ ရက် = တစ်လ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 46,
                }),
                true
            ),
            '၂ လ',
            '၄၆ ရက် = ၂ လ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 74,
                }),
                true
            ),
            '၂ လ',
            '၇၅ ရက်= ၂ လ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 76,
                }),
                true
            ),
            '၃ လ',
            '၇၆ ရက် = ၃ လ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    M: 1,
                }),
                true
            ),
            'တစ်လ',
            '၁ လ = တစ်လ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    M: 5,
                }),
                true
            ),
            '၅ လ',
            '၅ လ = ၅ လ'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 345,
                }),
                true
            ),
            'တစ်နှစ်',
            '၃၄၅ ရက် = တစ်နှစ်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    d: 548,
                }),
                true
            ),
            '၂ နှစ်',
            '၅၄၈ ရက် = ၂ နှစ်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    y: 1,
                }),
                true
            ),
            'တစ်နှစ်',
            '၁ နှစ် = တစ်နှစ်'
        );
        assert.equal(
            start.from(
                moment([2007, 1, 28]).add({
                    y: 5,
                }),
                true
            ),
            '၅ နှစ်',
            '၅ နှစ် = ၅ နှစ်'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'လာမည့် စက္ကန်.အနည်းငယ် မှာ', 'prefix');
        assert.equal(
            moment(0).from(30000),
            'လွန်ခဲ့သော စက္ကန်.အနည်းငယ် က',
            'suffix'
        );
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'လွန်ခဲ့သော စက္ကန်.အနည်းငယ် က',
            'ယခုမှစပြီး အတိတ်တွင်ဖော်ပြသလိုဖော်ပြမည်'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment()
                .add({
                    s: 30,
                })
                .fromNow(),
            'လာမည့် စက္ကန်.အနည်းငယ် မှာ',
            'လာမည့် စက္ကန်.အနည်းငယ် မှာ'
        );
        assert.equal(
            moment()
                .add({
                    d: 5,
                })
                .fromNow(),
            'လာမည့် ၅ ရက် မှာ',
            'လာမည့် ၅ ရက် မှာ'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), 'ယနေ. ၁၂:၀၀ မှာ', 'ယနေ. ဒီအချိန်');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'ယနေ. ၁၂:၂၅ မှာ',
            'ယခုမှ ၂၅ မိနစ်ပေါင်းထည့်'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'ယနေ. ၁၃:၀၀ မှာ',
            'ယခုမှ ၁ နာရီပေါင်းထည့်'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'မနက်ဖြန် ၁၂:၀၀ မှာ',
            'မနက်ဖြန် ဒီအချိန်'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'ယနေ. ၁၁:၀၀ မှာ',
            'ယခုမှ ၁ နာရီနှုတ်'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'မနေ.က ၁၂:၀၀ မှာ',
            'မနေ.က ဒီအချိန်'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({
                d: i,
            });
            assert.equal(
                m.calendar(),
                m.format('dddd LT [မှာ]'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd LT [မှာ]'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd LT [မှာ]'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({
                d: i,
            });
            assert.equal(
                m.calendar(),
                m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({
                w: 1,
            }),
            weeksFromNow = moment().add({
                w: 1,
            });

        assert.equal(
            weeksAgo.calendar(),
            weeksAgo.format('L'),
            'လွန်ခဲ့သော ၁ ပတ်က'
        );
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            '၁ ပတ်အတွင်း'
        );

        weeksAgo = moment().subtract({
            w: 2,
        });
        weeksFromNow = moment().add({
            w: 2,
        });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '၂ ပတ် အရင်က');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            '၂ ပတ် အတွင်း'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '၅၂ ၅၂ ၅၂',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '၁ ၀၁ ၁',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '၁ ၀၁ ၁',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '၂ ၀၂ ၂',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '၂ ၀၂ ၂',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('nb');

    test('parse', function (assert) {
        var tests = 'januar jan._februar feb._mars mars_april apr._mai mai_juni juni_juli juli_august aug._september sep._oktober okt._november nov._desember des.'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'søndag, februar 14. 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'sø., 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 februar feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. søndag sø. sø'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[den] DDDo [dagen i året]', 'den 45. dagen i året'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. februar 2010'],
                ['LLL', '14. februar 2010 kl. 15:25'],
                ['LLLL', 'søndag 14. februar 2010 kl. 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14. feb. 2010'],
                ['lll', '14. feb. 2010 kl. 15:25'],
                ['llll', 'sø. 14. feb. 2010 kl. 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'januar jan._februar feb._mars mars_april apr._mai mai_juni juni_juli juli_august aug._september sep._oktober okt._november nov._desember des.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'søndag sø. sø_mandag ma. ma_tirsdag ti. ti_onsdag on. on_torsdag to. to_fredag fr. fr_lørdag lø. lø'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'noen sekunder',
            '44 sekunder = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ett minutt',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ett minutt',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutter',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutter',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'en time',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'en time',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 timer',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 timer',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 timer',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'en dag',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'en dag',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dager',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'en dag',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dager',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dager',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'en måned',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'en måned',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'en måned',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 måneder',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 måneder',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 måneder',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'en måned',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 måneder',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ett år',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 år',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ett år',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 år',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'om noen sekunder', 'prefix');
        assert.equal(moment(0).from(30000), 'noen sekunder siden', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'noen sekunder siden',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'om noen sekunder',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'om 5 dager', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'i dag kl. 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'i dag kl. 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'i dag kl. 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'i morgen kl. 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'i dag kl. 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'i går kl. 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [kl.] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [kl.] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [kl.] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[forrige] dddd [kl.] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[forrige] dddd [kl.] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[forrige] dddd [kl.] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ne');

    test('parse', function (assert) {
        var tests = 'जनवरी जन._फेब्रुवरी फेब्रु._मार्च मार्च_अप्रिल अप्रि._मई मई_जुन जुन_जुलाई जुलाई._अगष्ट अग._सेप्टेम्बर सेप्ट._अक्टोबर अक्टो._नोभेम्बर नोभे._डिसेम्बर डिसे.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, aको h:mm:ss बजे',
                    'आइतबार, १४ फेब्रुवरी २०१०, दिउँसोको ३:२५:५० बजे',
                ],
                ['ddd, aको h बजे', 'आइत., दिउँसोको ३ बजे'],
                ['M Mo MM MMMM MMM', '२ २ ०२ फेब्रुवरी फेब्रु.'],
                ['YYYY YY', '२०१० १०'],
                ['D Do DD', '१४ १४ १४'],
                ['d do dddd ddd dd', '० ० आइतबार आइत. आ.'],
                ['DDD DDDo DDDD', '४५ ४५ ०४५'],
                ['w wo ww', '८ ८ ०८'],
                ['h hh', '३ ०३'],
                ['H HH', '१५ १५'],
                ['m mm', '२५ २५'],
                ['s ss', '५० ५०'],
                ['a A', 'दिउँसो दिउँसो'],
                ['LTS', 'दिउँसोको ३:२५:५० बजे'],
                ['L', '१४/०२/२०१०'],
                ['LL', '१४ फेब्रुवरी २०१०'],
                ['LLL', '१४ फेब्रुवरी २०१०, दिउँसोको ३:२५ बजे'],
                ['LLLL', 'आइतबार, १४ फेब्रुवरी २०१०, दिउँसोको ३:२५ बजे'],
                ['l', '१४/२/२०१०'],
                ['ll', '१४ फेब्रु. २०१०'],
                ['lll', '१४ फेब्रु. २०१०, दिउँसोको ३:२५ बजे'],
                ['llll', 'आइत., १४ फेब्रु. २०१०, दिउँसोको ३:२५ बजे'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');
    });

    test('format month', function (assert) {
        var expected = 'जनवरी जन._फेब्रुवरी फेब्रु._मार्च मार्च_अप्रिल अप्रि._मई मई_जुन जुन_जुलाई जुलाई._अगष्ट अग._सेप्टेम्बर सेप्ट._अक्टोबर अक्टो._नोभेम्बर नोभे._डिसेम्बर डिसे.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'आइतबार आइत. आ._सोमबार सोम. सो._मङ्गलबार मङ्गल. मं._बुधबार बुध. बु._बिहिबार बिहि. बि._शुक्रबार शुक्र. शु._शनिबार शनि. श.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'केही क्षण',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'एक मिनेट',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'एक मिनेट',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '२ मिनेट',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '४४ मिनेट',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'एक घण्टा',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'एक घण्टा',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '२ घण्टा',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '५ घण्टा',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '२१ घण्टा',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'एक दिन',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'एक दिन',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '२ दिन',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'एक दिन',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '५ दिन',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '२५ दिन',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'एक महिना',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'एक महिना',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'एक महिना',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '२ महिना',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '२ महिना',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '३ महिना',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'एक महिना',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '५ महिना',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'एक बर्ष',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '२ बर्ष',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'एक बर्ष',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '५ बर्ष',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'केही क्षणमा', 'prefix');
        assert.equal(moment(0).from(30000), 'केही क्षण अगाडि', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'केही क्षण अगाडि',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'केही क्षणमा',
            'केही क्षणमा'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '५ दिनमा', '५ दिनमा');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'आज दिउँसोको १२:०० बजे',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'आज दिउँसोको १२:२५ बजे',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'आज दिउँसोको १:०० बजे',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'भोलि दिउँसोको १२:०० बजे',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'आज बिहानको ११:०० बजे',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'हिजो दिउँसोको १२:०० बजे',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[आउँदो] dddd[,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[आउँदो] dddd[,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[आउँदो] dddd[,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[गएको] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[गएको] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[गएको] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('a'),
            'राति',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('a'), 'बिहान', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('a'),
            'दिउँसो',
            'during day'
        );
        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'साँझ', 'evening');
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('a'),
            'साँझ',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'राति', 'night');

        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('A'),
            'राति',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('A'), 'बिहान', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('A'),
            'दिउँसो',
            'during day'
        );
        assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'साँझ', 'evening');
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('A'),
            'साँझ',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'राति', 'night');
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '५३ ५३ ५३',
            'Dec 26 2011 should be week 53'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '१ ०१ १',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '१ ०१ १',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '२ ०२ २',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '२ ०२ २',
            'Jan  9 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('nl-be');

    test('parse', function (assert) {
        var tests = 'januari jan._februari feb._maart mrt._april apr._mei mei._juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            // Fails only for month 5 (index 4)
            // equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            // Fails only for month 5 (index 4)
            // equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            // Fails only for month 5 (index 4)
            // equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, HH:mm:ss',
                    'zondag, februari 14de 2010, 15:25:50',
                ],
                ['ddd, HH', 'zo., 15'],
                ['M Mo MM MMMM MMM', '2 2de 02 februari feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14de 14'],
                ['d do dddd ddd dd', '0 0de zondag zo. zo'],
                ['DDD DDDo DDDD', '45 45ste 045'],
                ['w wo ww', '6 6de 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45ste day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 februari 2010'],
                ['LLL', '14 februari 2010 15:25'],
                ['LLLL', 'zondag 14 februari 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 feb. 2010'],
                ['lll', '14 feb. 2010 15:25'],
                ['llll', 'zo. 14 feb. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');
    });

    test('format month', function (assert) {
        var expected = 'januari jan._februari feb._maart mrt._april apr._mei mei_juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'zondag zo. zo_maandag ma. ma_dinsdag di. di_woensdag wo. wo_donderdag do. do_vrijdag vr. vr_zaterdag za. za'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'een paar seconden',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'één minuut',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'één minuut',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuten',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuten',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'één uur',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'één uur',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 uur',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 uur',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 uur',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'één dag',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'één dag',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dagen',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'één dag',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dagen',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dagen',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'één maand',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'één maand',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'één maand',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 maanden',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 maanden',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 maanden',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'één maand',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 maanden',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'één jaar',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 jaar',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'één jaar',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 jaar',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'over een paar seconden', 'prefix');
        assert.equal(moment(0).from(30000), 'een paar seconden geleden', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'een paar seconden geleden',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'over een paar seconden',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'over 5 dagen', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'vandaag om 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'vandaag om 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'vandaag om 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'morgen om 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'vandaag om 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'gisteren om 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [om] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [om] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [om] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[afgelopen] dddd [om] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[afgelopen] dddd [om] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[afgelopen] dddd [om] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('month abbreviation', function (assert) {
        assert.equal(
            moment([2012, 5, 23]).format('D-MMM-YYYY'),
            '23-jun-2012',
            'format month abbreviation surrounded by dashes should not include a dot'
        );
        assert.equal(
            moment([2012, 5, 23]).unix(),
            moment('23-jun-2012', 'D-MMM-YYYY').unix(),
            'parse month abbreviation surrounded by dashes without dot'
        );
        assert.equal(
            moment([2012, 5, 23]).format('D MMM YYYY'),
            '23 jun. 2012',
            'format month abbreviation not surrounded by dashes should include a dot'
        );
        assert.equal(
            moment([2012, 5, 23]).unix(),
            moment('23 jun. 2012', 'D MMM YYYY').unix(),
            'parse month abbreviation not surrounded by dashes with dot'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52ste',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1ste',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1ste',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2de',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2de',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('nl');

    test('parse', function (assert) {
        var tests = 'januari jan._februari feb._maart mrt._april apr._mei mei._juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            // Fails only for month 5 (index 4)
            // equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            // Fails only for month 5 (index 4)
            // equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            // Fails only for month 5 (index 4)
            // equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, HH:mm:ss',
                    'zondag, februari 14de 2010, 15:25:50',
                ],
                ['ddd, HH', 'zo., 15'],
                ['M Mo MM MMMM MMM', '2 2de 02 februari feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14de 14'],
                ['d do dddd ddd dd', '0 0de zondag zo. zo'],
                ['DDD DDDo DDDD', '45 45ste 045'],
                ['w wo ww', '6 6de 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45ste day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14-02-2010'],
                ['LL', '14 februari 2010'],
                ['LLL', '14 februari 2010 15:25'],
                ['LLLL', 'zondag 14 februari 2010 15:25'],
                ['l', '14-2-2010'],
                ['ll', '14 feb. 2010'],
                ['lll', '14 feb. 2010 15:25'],
                ['llll', 'zo. 14 feb. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');
    });

    test('format month', function (assert) {
        var expected = 'januari jan._februari feb._maart mrt._april apr._mei mei_juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'zondag zo. zo_maandag ma. ma_dinsdag di. di_woensdag wo. wo_donderdag do. do_vrijdag vr. vr_zaterdag za. za'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'een paar seconden',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'één minuut',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'één minuut',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuten',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuten',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'één uur',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'één uur',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 uur',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 uur',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 uur',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'één dag',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'één dag',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dagen',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'één dag',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dagen',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dagen',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'één maand',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'één maand',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'één maand',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 maanden',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 maanden',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 maanden',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'één maand',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 maanden',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'één jaar',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 jaar',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'één jaar',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 jaar',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'over een paar seconden', 'prefix');
        assert.equal(moment(0).from(30000), 'een paar seconden geleden', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'een paar seconden geleden',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'over een paar seconden',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'over 5 dagen', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'vandaag om 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'vandaag om 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'vandaag om 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'morgen om 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'vandaag om 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'gisteren om 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [om] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [om] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [om] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[afgelopen] dddd [om] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[afgelopen] dddd [om] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[afgelopen] dddd [om] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('month abbreviation', function (assert) {
        assert.equal(
            moment([2012, 5, 23]).format('D-MMM-YYYY'),
            '23-jun-2012',
            'format month abbreviation surrounded by dashes should not include a dot'
        );
        assert.equal(
            moment([2012, 5, 23]).unix(),
            moment('23-jun-2012', 'D-MMM-YYYY').unix(),
            'parse month abbreviation surrounded by dashes without dot'
        );
        assert.equal(
            moment([2012, 5, 23]).format('D MMM YYYY'),
            '23 jun. 2012',
            'format month abbreviation not surrounded by dashes should include a dot'
        );
        assert.equal(
            moment([2012, 5, 23]).unix(),
            moment('23 jun. 2012', 'D MMM YYYY').unix(),
            'parse month abbreviation not surrounded by dashes with dot'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52ste',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1ste',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1ste',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2de',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2de',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('nn');

    test('parse', function (assert) {
        var tests = 'januar jan._februar feb._mars mars_april apr._mai mai_juni juni_juli juli_august aug._september sep._oktober okt._november nov._desember des.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'sundag, februar 14. 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'su., 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 februar feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. sundag su. su'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. februar 2010'],
                ['LLL', '14. februar 2010 kl. 15:25'],
                ['LLLL', 'sundag 14. februar 2010 kl. 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14. feb. 2010'],
                ['lll', '14. feb. 2010 kl. 15:25'],
                ['llll', 'su. 14. feb. 2010 kl. 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'januar jan._februar feb._mars mars_april apr._mai mai_juni juni_juli juli_august aug._september sep._oktober okt._november nov._desember des.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'sundag su. su_måndag må. må_tysdag ty. ty_onsdag on. on_torsdag to. to_fredag fr. fr_laurdag lau. la'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'nokre sekund',
            '44 sekunder = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'eit minutt',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'eit minutt',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutt',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutt',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ein time',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ein time',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 timar',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 timar',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 timar',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ein dag',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ein dag',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dagar',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ein dag',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dagar',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dagar',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ein månad',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ein månad',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ein månad',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 månader',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 månader',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 månader',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ein månad',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 månader',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'eit år',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 år',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'eit år',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 år',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'om nokre sekund', 'prefix');
        assert.equal(moment(0).from(30000), 'nokre sekund sidan', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'nokre sekund sidan',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'om nokre sekund',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'om 5 dagar', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'I dag klokka 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'I dag klokka 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'I dag klokka 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'I morgon klokka 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'I dag klokka 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'I går klokka 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [klokka] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [klokka] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [klokka] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Føregåande] dddd [klokka] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Føregåande] dddd [klokka] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Føregåande] dddd [klokka] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('oc-lnc');

    test('parse', function (assert) {
        var tests = 'genièr gen._febrièr febr._març març_abril abr._mai mai_junh junh_julhet julh._agost ago._setembre set._octòbre oct._novembre nov._decembre dec.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'dimenge, 14è de febrièr 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dg., 3PM'],
                ['M Mo MM MMMM MMM', '2 2n 02 febrièr febr.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14è 14'],
                ['d do dddd ddd dd', '0 0è dimenge dg. dg'],
                ['DDD DDDo DDDD', '45 45è 045'],
                ['w wo ww', '6 6a 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45è day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 de febrièr de 2010'],
                ['LLL', '14 de febrièr de 2010 a 15:25'],
                ['LLLL', 'dimenge 14 de febrièr de 2010 a 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 febr. 2010'],
                ['lll', '14 febr. 2010, 15:25'],
                ['llll', 'dg. 14 febr. 2010, 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1r', '1r');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2n', '2n');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3r', '3r');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4t', '4t');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5è', '5è');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6è', '6è');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7è', '7è');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8è', '8è');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9è', '9è');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10è', '10è');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11è', '11è');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12è', '12è');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13è', '13è');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14è', '14è');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15è', '15è');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16è', '16è');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17è', '17è');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18è', '18è');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19è', '19è');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20è', '20è');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21è', '21è');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22è', '22è');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23è', '23è');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24è', '24è');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25è', '25è');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26è', '26è');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27è', '27è');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28è', '28è');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29è', '29è');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30è', '30è');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31è', '31è');
    });

    test('format month', function (assert) {
        var expected = 'genièr gen._febrièr febr._març març_abril abr._mai mai_junh junh_julhet julh._agost ago._setembre set._octòbre oct._novembre nov._decembre dec.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'dimenge dg. dg_diluns dl. dl_dimars dm. dm_dimècres dc. dc_dijòus dj. dj_divendres dv. dv_dissabte ds. ds'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'unas segondas',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'una minuta',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'una minuta',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutas',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutas',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'una ora',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'una ora',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 oras',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 oras',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 oras',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'un jorn',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'un jorn',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 jorns',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'un jorn',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 jorns',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 jorns',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'un mes',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'un mes',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'un mes',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 meses',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 meses',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 meses',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'un mes',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 meses',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un an',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ans',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un an',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ans',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), "d'aquí unas segondas", 'prefix');
        assert.equal(moment(0).from(30000), 'fa unas segondas', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'fa unas segondas',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            "d'aquí unas segondas",
            "d'aquí unas segondas"
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            "d'aquí 5 jorns",
            "d'aquí 5 jorns"
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), 'uèi a 12:00', 'today at the same time');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'uèi a 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'uèi a 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'deman a 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).add({ d: 1, h: -1 }).calendar(),
            'deman a 11:00',
            'tomorrow minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'uèi a 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ièr a 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [a] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [a] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [a] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [passat a] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [passat a] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [passat a] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52a',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1a',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1a',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2a',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2a',
            'Jan 15 2012 should be week 2'
        );
    });

    test('day and month', function (assert) {
        assert.equal(moment([2012, 1, 15]).format('D MMMM'), '15 de febrièr');
        assert.equal(moment([2012, 9, 15]).format('D MMMM'), "15 d'octòbre");
        assert.equal(moment([2012, 9, 15]).format('MMMM, D'), 'octòbre, 15');
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('pa-in');

    test('parse', function (assert) {
        var tests = 'ਜਨਵਰੀ ਜਨਵਰੀ_ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ_ਮਾਰਚ ਮਾਰਚ_ਅਪ੍ਰੈਲ ਅਪ੍ਰੈਲ_ਮਈ ਮਈ_ਜੂਨ ਜੂਨ_ਜੁਲਾਈ ਜੁਲਾਈ_ਅਗਸਤ ਅਗਸਤ_ਸਤੰਬਰ ਸਤੰਬਰ_ਅਕਤੂਬਰ ਅਕਤੂਬਰ_ਨਵੰਬਰ ਨਵੰਬਰ_ਦਸੰਬਰ ਦਸੰਬਰ'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, a h:mm:ss ਵਜੇ',
                    'ਐਤਵਾਰ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫:੫੦ ਵਜੇ',
                ],
                ['ddd, a h ਵਜੇ', 'ਐਤ, ਦੁਪਹਿਰ ੩ ਵਜੇ'],
                ['M Mo MM MMMM MMM', '੨ ੨ ੦੨ ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ'],
                ['YYYY YY', '੨੦੧੦ ੧੦'],
                ['D Do DD', '੧੪ ੧੪ ੧੪'],
                ['d do dddd ddd dd', '੦ ੦ ਐਤਵਾਰ ਐਤ ਐਤ'],
                ['DDD DDDo DDDD', '੪੫ ੪੫ ੦੪੫'],
                ['w wo ww', '੮ ੮ ੦੮'],
                ['h hh', '੩ ੦੩'],
                ['H HH', '੧੫ ੧੫'],
                ['m mm', '੨੫ ੨੫'],
                ['s ss', '੫੦ ੫੦'],
                ['a A', 'ਦੁਪਹਿਰ ਦੁਪਹਿਰ'],
                ['LTS', 'ਦੁਪਹਿਰ ੩:੨੫:੫੦ ਵਜੇ'],
                ['L', '੧੪/੦੨/੨੦੧੦'],
                ['LL', '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦'],
                ['LLL', '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],
                ['LLLL', 'ਐਤਵਾਰ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],
                ['l', '੧੪/੨/੨੦੧੦'],
                ['ll', '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦'],
                ['lll', '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],
                ['llll', 'ਐਤ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '੧', '੧');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '੨', '੨');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '੩', '੩');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '੪', '੪');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '੫', '੫');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '੬', '੬');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '੭', '੭');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '੮', '੮');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '੯', '੯');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '੧੦', '੧੦');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '੧੧', '੧੧');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '੧੨', '੧੨');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '੧੩', '੧੩');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '੧੪', '੧੪');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '੧੫', '੧੫');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '੧੬', '੧੬');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '੧੭', '੧੭');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '੧੮', '੧੮');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '੧੯', '੧੯');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '੨੦', '੨੦');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '੨੧', '੨੧');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '੨੨', '੨੨');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '੨੩', '੨੩');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '੨੪', '੨੪');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '੨੫', '੨੫');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '੨੬', '੨੬');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '੨੭', '੨੭');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '੨੮', '੨੮');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '੨੯', '੨੯');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '੩੦', '੩੦');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '੩੧', '੩੧');
    });

    test('format month', function (assert) {
        var expected = 'ਜਨਵਰੀ ਜਨਵਰੀ_ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ_ਮਾਰਚ ਮਾਰਚ_ਅਪ੍ਰੈਲ ਅਪ੍ਰੈਲ_ਮਈ ਮਈ_ਜੂਨ ਜੂਨ_ਜੁਲਾਈ ਜੁਲਾਈ_ਅਗਸਤ ਅਗਸਤ_ਸਤੰਬਰ ਸਤੰਬਰ_ਅਕਤੂਬਰ ਅਕਤੂਬਰ_ਨਵੰਬਰ ਨਵੰਬਰ_ਦਸੰਬਰ ਦਸੰਬਰ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'ਐਤਵਾਰ ਐਤ ਐਤ_ਸੋਮਵਾਰ ਸੋਮ ਸੋਮ_ਮੰਗਲਵਾਰ ਮੰਗਲ ਮੰਗਲ_ਬੁਧਵਾਰ ਬੁਧ ਬੁਧ_ਵੀਰਵਾਰ ਵੀਰ ਵੀਰ_ਸ਼ੁੱਕਰਵਾਰ ਸ਼ੁਕਰ ਸ਼ੁਕਰ_ਸ਼ਨੀਚਰਵਾਰ ਸ਼ਨੀ ਸ਼ਨੀ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ਕੁਝ ਸਕਿੰਟ',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ਇਕ ਮਿੰਟ',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ਇਕ ਮਿੰਟ',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '੨ ਮਿੰਟ',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '੪੪ ਮਿੰਟ',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ਇੱਕ ਘੰਟਾ',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ਇੱਕ ਘੰਟਾ',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '੨ ਘੰਟੇ',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '੫ ਘੰਟੇ',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '੨੧ ਘੰਟੇ',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ਇੱਕ ਦਿਨ',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ਇੱਕ ਦਿਨ',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '੨ ਦਿਨ',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ਇੱਕ ਦਿਨ',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '੫ ਦਿਨ',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '੨੫ ਦਿਨ',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ਇੱਕ ਮਹੀਨਾ',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ਇੱਕ ਮਹੀਨਾ',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ਇੱਕ ਮਹੀਨਾ',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '੨ ਮਹੀਨੇ',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '੨ ਮਹੀਨੇ',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '੩ ਮਹੀਨੇ',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ਇੱਕ ਮਹੀਨਾ',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '੫ ਮਹੀਨੇ',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ਇੱਕ ਸਾਲ',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '੨ ਸਾਲ',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ਇੱਕ ਸਾਲ',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '੫ ਸਾਲ',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ', 'prefix');
        assert.equal(moment(0).from(30000), 'ਕੁਝ ਸਕਿੰਟ ਪਿਛਲੇ', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'ਕੁਝ ਸਕਿੰਟ ਪਿਛਲੇ',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ',
            'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '੫ ਦਿਨ ਵਿੱਚ', '੫ ਦਿਨ ਵਿੱਚ');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'ਅਜ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'ਅਜ ਦੁਪਹਿਰ ੧੨:੨੫ ਵਜੇ',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 3 }).calendar(),
            'ਅਜ ਦੁਪਹਿਰ ੩:੦੦ ਵਜੇ',
            'Now plus 3 hours'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'ਕਲ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'ਅਜ ਦੁਪਹਿਰ ੧੧:੦੦ ਵਜੇ',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ਕਲ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[ਅਗਲਾ] dddd[,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[ਅਗਲਾ] dddd[,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[ਅਗਲਾ] dddd[,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[ਪਿਛਲੇ] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[ਪਿਛਲੇ] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[ਪਿਛਲੇ] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem invariant', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('a'),
            'ਰਾਤ',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('a'), 'ਸਵੇਰ', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('a'),
            'ਦੁਪਹਿਰ',
            'during day'
        );
        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'ਸ਼ਾਮ', 'evening');
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('a'),
            'ਸ਼ਾਮ',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'ਰਾਤ', 'night');

        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('A'),
            'ਰਾਤ',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('A'), 'ਸਵੇਰ', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('A'),
            'ਦੁਪਹਿਰ',
            ' during day'
        );
        assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'ਸ਼ਾਮ', 'evening');
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('A'),
            'ਸ਼ਾਮ',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'ਰਾਤ', 'night');
    });

    test('weeks year starting sunday', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).week(),
            1,
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).week(),
            1,
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).week(),
            2,
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).week(),
            2,
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).week(),
            3,
            'Jan 15 2012 should be week 3'
        );
    });

    test('weeks year starting monday', function (assert) {
        assert.equal(
            moment([2006, 11, 31]).week(),
            1,
            'Dec 31 2006 should be week 1'
        );
        assert.equal(
            moment([2007, 0, 1]).week(),
            1,
            'Jan  1 2007 should be week 1'
        );
        assert.equal(
            moment([2007, 0, 6]).week(),
            1,
            'Jan  6 2007 should be week 1'
        );
        assert.equal(
            moment([2007, 0, 7]).week(),
            2,
            'Jan  7 2007 should be week 2'
        );
        assert.equal(
            moment([2007, 0, 13]).week(),
            2,
            'Jan 13 2007 should be week 2'
        );
        assert.equal(
            moment([2007, 0, 14]).week(),
            3,
            'Jan 14 2007 should be week 3'
        );
    });

    test('weeks year starting tuesday', function (assert) {
        assert.equal(
            moment([2007, 11, 29]).week(),
            52,
            'Dec 29 2007 should be week 52'
        );
        assert.equal(
            moment([2008, 0, 1]).week(),
            1,
            'Jan  1 2008 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 5]).week(),
            1,
            'Jan  5 2008 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 6]).week(),
            2,
            'Jan  6 2008 should be week 2'
        );
        assert.equal(
            moment([2008, 0, 12]).week(),
            2,
            'Jan 12 2008 should be week 2'
        );
        assert.equal(
            moment([2008, 0, 13]).week(),
            3,
            'Jan 13 2008 should be week 3'
        );
    });

    test('weeks year starting wednesday', function (assert) {
        assert.equal(
            moment([2002, 11, 29]).week(),
            1,
            'Dec 29 2002 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 1]).week(),
            1,
            'Jan  1 2003 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 4]).week(),
            1,
            'Jan  4 2003 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 5]).week(),
            2,
            'Jan  5 2003 should be week 2'
        );
        assert.equal(
            moment([2003, 0, 11]).week(),
            2,
            'Jan 11 2003 should be week 2'
        );
        assert.equal(
            moment([2003, 0, 12]).week(),
            3,
            'Jan 12 2003 should be week 3'
        );
    });

    test('weeks year starting thursday', function (assert) {
        assert.equal(
            moment([2008, 11, 28]).week(),
            1,
            'Dec 28 2008 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 1]).week(),
            1,
            'Jan  1 2009 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 3]).week(),
            1,
            'Jan  3 2009 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 4]).week(),
            2,
            'Jan  4 2009 should be week 2'
        );
        assert.equal(
            moment([2009, 0, 10]).week(),
            2,
            'Jan 10 2009 should be week 2'
        );
        assert.equal(
            moment([2009, 0, 11]).week(),
            3,
            'Jan 11 2009 should be week 3'
        );
    });

    test('weeks year starting friday', function (assert) {
        assert.equal(
            moment([2009, 11, 27]).week(),
            1,
            'Dec 27 2009 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 1]).week(),
            1,
            'Jan  1 2010 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 2]).week(),
            1,
            'Jan  2 2010 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 3]).week(),
            2,
            'Jan  3 2010 should be week 2'
        );
        assert.equal(
            moment([2010, 0, 9]).week(),
            2,
            'Jan  9 2010 should be week 2'
        );
        assert.equal(
            moment([2010, 0, 10]).week(),
            3,
            'Jan 10 2010 should be week 3'
        );
    });

    test('weeks year starting saturday', function (assert) {
        assert.equal(
            moment([2010, 11, 26]).week(),
            1,
            'Dec 26 2010 should be week 1'
        );
        assert.equal(
            moment([2011, 0, 1]).week(),
            1,
            'Jan  1 2011 should be week 1'
        );
        assert.equal(
            moment([2011, 0, 2]).week(),
            2,
            'Jan  2 2011 should be week 2'
        );
        assert.equal(
            moment([2011, 0, 8]).week(),
            2,
            'Jan  8 2011 should be week 2'
        );
        assert.equal(
            moment([2011, 0, 9]).week(),
            3,
            'Jan  9 2011 should be week 3'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '੧ ੦੧ ੧',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '੧ ੦੧ ੧',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '੨ ੦੨ ੨',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '੨ ੦੨ ੨',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '੩ ੦੩ ੩',
            'Jan 15 2012 should be week 3'
        );
    });

    test('lenient day of month ordinal parsing', function (assert) {
        var i, ordinalStr, testMoment;
        for (i = 1; i <= 31; ++i) {
            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
            testMoment = moment(ordinalStr, 'YYYY MM Do');
            assert.equal(
                testMoment.year(),
                2014,
                'lenient day of month ordinal parsing ' + i + ' year check'
            );
            assert.equal(
                testMoment.month(),
                0,
                'lenient day of month ordinal parsing ' + i + ' month check'
            );
            assert.equal(
                testMoment.date(),
                i,
                'lenient day of month ordinal parsing ' + i + ' date check'
            );
        }
    });

    test('lenient day of month ordinal parsing of number', function (assert) {
        var i, testMoment;
        for (i = 1; i <= 31; ++i) {
            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
            assert.equal(
                testMoment.year(),
                2014,
                'lenient day of month ordinal parsing of number ' +
                    i +
                    ' year check'
            );
            assert.equal(
                testMoment.month(),
                0,
                'lenient day of month ordinal parsing of number ' +
                    i +
                    ' month check'
            );
            assert.equal(
                testMoment.date(),
                i,
                'lenient day of month ordinal parsing of number ' +
                    i +
                    ' date check'
            );
        }
    });

    test('strict day of month ordinal parsing', function (assert) {
        var i, ordinalStr, testMoment;
        for (i = 1; i <= 31; ++i) {
            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
            testMoment = moment(ordinalStr, 'YYYY MM Do', true);
            assert.ok(
                testMoment.isValid(),
                'strict day of month ordinal parsing ' + i
            );
        }
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('pl');

    test('months', function (assert) {
        assert.deepEqual(moment.months(), [
            'styczeń',
            'luty',
            'marzec',
            'kwiecień',
            'maj',
            'czerwiec',
            'lipiec',
            'sierpień',
            'wrzesień',
            'październik',
            'listopad',
            'grudzień',
        ]);
    });

    test('parse', function (assert) {
        var tests = 'styczeń stycznia sty_luty lutego lut_marzec marca mar_kwiecień kwietnia kwi_maj maja maj_czerwiec czerwca cze_lipiec lipca lip_sierpień sierpnia sie_wrzesień września wrz_październik października paź_listopad listopada lis_grudzień grudnia gru'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][2], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][2], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][2].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][2].toLocaleUpperCase(), 'MMMM', i);

            // Fails for all months
            // equalTestStrict(tests[i][0], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1], 'MMMM', i);
            // Fails for all months
            // equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMM', i);
            // Fails for all months
            // equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('parse strict', function (assert) {
        var tests = 'styczeń stycznia sty_luty lutego lut_marzec marca mar_kwiecień kwietnia kwi_maj maja maj_czerwiec czerwca cze_lipiec lipca lip_sierpień sierpnia sie_wrzesień września wrz_październik października paź_listopad listopada lis_grudzień grudnia gru'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm, true).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][2], 'MMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][2].toLocaleLowerCase(), 'MMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][2].toLocaleUpperCase(), 'MMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'niedziela, luty 14. 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'ndz, 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 luty lut'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. niedziela ndz Nd'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 lutego 2010'],
                ['LLL', '14 lutego 2010 15:25'],
                ['LLLL', 'niedziela, 14 lutego 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 lut 2010'],
                ['lll', '14 lut 2010 15:25'],
                ['llll', 'ndz, 14 lut 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'styczeń sty_luty lut_marzec mar_kwiecień kwi_maj maj_czerwiec cze_lipiec lip_sierpień sie_wrzesień wrz_październik paź_listopad lis_grudzień gru'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'niedziela ndz Nd_poniedziałek pon Pn_wtorek wt Wt_środa śr Śr_czwartek czw Cz_piątek pt Pt_sobota sob So'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'kilka sekund',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'minuta',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'minuta',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuty',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuty',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'godzina',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'godzina',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 godziny',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 godzin',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 godzin',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            '1 dzień',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            '1 dzień',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dni',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            '1 dzień',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dni',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dni',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'miesiąc',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'miesiąc',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'miesiąc',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 miesiące',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 miesiące',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 miesiące',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'miesiąc',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 miesięcy',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'rok',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 lata',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'rok',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 lat',
            '5 years = 5 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 112 }), true),
            '112 lat',
            '112 years = 112 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 122 }), true),
            '122 lata',
            '122 years = 122 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 213 }), true),
            '213 lat',
            '213 years = 213 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 223 }), true),
            '223 lata',
            '223 years = 223 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'za kilka sekund', 'prefix');
        assert.equal(moment(0).from(30000), 'kilka sekund temu', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'kilka sekund temu',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'za kilka sekund',
            'in a few seconds'
        );
        assert.equal(moment().add({ h: 1 }).fromNow(), 'za godzinę', 'in an hour');
        assert.equal(moment().add({ d: 5 }).fromNow(), 'za 5 dni', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Dziś o 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Dziś o 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Dziś o 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Jutro o 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Dziś o 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Wczoraj o 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                    return '[W niedzielę o] LT';

                case 2:
                    return '[We wtorek o] LT';

                case 3:
                    return '[W środę o] LT';

                case 6:
                    return '[W sobotę o] LT';

                default:
                    return '[W] dddd [o] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days current time'
            );

            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days beginning of day'
            );

            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                    return '[W zeszłą niedzielę o] LT';
                case 3:
                    return '[W zeszłą środę o] LT';
                case 6:
                    return '[W zeszłą sobotę o] LT';
                default:
                    return '[W zeszły] dddd [o] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days current time'
            );

            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days beginning of day'
            );

            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('pt-br');

    test('parse', function (assert) {
        var tests = 'janeiro jan_fevereiro fev_março mar_abril abr_maio mai_junho jun_julho jul_agosto ago_setembro set_outubro out_novembro nov_dezembro dez'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'domingo, fevereiro 14º 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'dom, 3PM'],
                ['M Mo MM MMMM MMM', '2 2º 02 fevereiro fev'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14º 14'],
                ['d do dddd ddd', '0 0º domingo dom'],
                ['DDD DDDo DDDD', '45 45º 045'],
                ['w wo ww', '8 8º 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45º day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 de fevereiro de 2010'],
                ['LLL', '14 de fevereiro de 2010 às 15:25'],
                ['LLLL', 'domingo, 14 de fevereiro de 2010 às 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 de fev de 2010'],
                ['lll', '14 de fev de 2010 às 15:25'],
                ['llll', 'dom, 14 de fev de 2010 às 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');
    });

    test('format month', function (assert) {
        var expected = 'janeiro jan_fevereiro fev_março mar_abril abr_maio mai_junho jun_julho jul_agosto ago_setembro set_outubro out_novembro nov_dezembro dez'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'domingo dom do_segunda-feira seg 2ª_terça-feira ter 3ª_quarta-feira qua 4ª_quinta-feira qui 5ª_sexta-feira sex 6ª_sábado sáb sá'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'poucos segundos',
            '44 seconds = seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'um minuto',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'um minuto',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutos',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutos',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'uma hora',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'uma hora',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 horas',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 horas',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 horas',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'um dia',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'um dia',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dias',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'um dia',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dias',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dias',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'um mês',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'um mês',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'um mês',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 meses',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 meses',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 meses',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'um mês',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 meses',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'um ano',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 anos',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'um ano',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 anos',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'em poucos segundos', 'prefix');
        assert.equal(moment(0).from(30000), 'há poucos segundos', 'prefix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'em poucos segundos',
            'in seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'em 5 dias', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Hoje às 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Hoje às 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Hoje às 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Amanhã às 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Hoje às 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Ontem às 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [às] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [às] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [às] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(
                    m.day() === 0 || m.day() === 6
                        ? '[Último] dddd [às] LT'
                        : '[Última] dddd [às] LT'
                ),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(
                    m.day() === 0 || m.day() === 6
                        ? '[Último] dddd [às] LT'
                        : '[Última] dddd [às] LT'
                ),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(
                    m.day() === 0 || m.day() === 6
                        ? '[Último] dddd [às] LT'
                        : '[Última] dddd [às] LT'
                ),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1º',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1º',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2º',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2º',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3º',
            'Jan 15 2012 should be week 3'
        );
    });

    test('relative time threshold', function (assert) {
        var rts = moment(),
            rtsDefault = moment.relativeTimeThreshold('ss');

        moment.relativeTimeThreshold('ss', 3);

        rts.subtract(3, 'seconds');
        assert.equal(
            rts.fromNow(),
            'há poucos segundos',
            'Below custom a few seconds to seconds threshold'
        );
        rts.subtract(1, 'seconds');
        assert.equal(
            rts.fromNow(),
            'há 4 segundos',
            'Above custom a few seconds to seconds threshold'
        );

        moment.relativeTimeThreshold('ss', rtsDefault);
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('pt');

    test('parse', function (assert) {
        var tests = 'janeiro jan_fevereiro fev_março mar_abril abr_maio mai_junho jun_julho jul_agosto ago_setembro set_outubro out_novembro nov_dezembro dez'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Domingo, fevereiro 14º 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Dom, 3PM'],
                ['M Mo MM MMMM MMM', '2 2º 02 fevereiro fev'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14º 14'],
                ['d do dddd ddd', '0 0º Domingo Dom'],
                ['DDD DDDo DDDD', '45 45º 045'],
                ['w wo ww', '6 6º 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45º day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 de fevereiro de 2010'],
                ['LLL', '14 de fevereiro de 2010 15:25'],
                ['LLLL', 'Domingo, 14 de fevereiro de 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 de fev de 2010'],
                ['lll', '14 de fev de 2010 15:25'],
                ['llll', 'Dom, 14 de fev de 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');
    });

    test('format month', function (assert) {
        var expected = 'janeiro jan_fevereiro fev_março mar_abril abr_maio mai_junho jun_julho jul_agosto ago_setembro set_outubro out_novembro nov_dezembro dez'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Domingo Dom Do_Segunda-feira Seg 2ª_Terça-feira Ter 3ª_Quarta-feira Qua 4ª_Quinta-feira Qui 5ª_Sexta-feira Sex 6ª_Sábado Sáb Sá'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'segundos',
            '44 seconds = seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'um minuto',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'um minuto',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minutos',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minutos',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'uma hora',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'uma hora',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 horas',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 horas',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 horas',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'um dia',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'um dia',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dias',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'um dia',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dias',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dias',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'um mês',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'um mês',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'um mês',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 meses',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 meses',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 meses',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'um mês',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 meses',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'um ano',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 anos',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'um ano',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 anos',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'em segundos', 'prefix');
        assert.equal(moment(0).from(30000), 'há segundos', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'em segundos',
            'in seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'em 5 dias', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Hoje às 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Hoje às 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Hoje às 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Amanhã às 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Hoje às 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Ontem às 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [às] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [às] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [às] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(
                    m.day() === 0 || m.day() === 6
                        ? '[Último] dddd [às] LT'
                        : '[Última] dddd [às] LT'
                ),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(
                    m.day() === 0 || m.day() === 6
                        ? '[Último] dddd [às] LT'
                        : '[Última] dddd [às] LT'
                ),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(
                    m.day() === 0 || m.day() === 6
                        ? '[Último] dddd [às] LT'
                        : '[Última] dddd [às] LT'
                ),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52º',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1º',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1º',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2º',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2º',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ro');

    test('parse', function (assert) {
        var tests = 'ianuarie ian._februarie feb._martie mart._aprilie apr._mai mai_iunie iun._iulie iul._august aug._septembrie sept._octombrie oct._noiembrie nov._decembrie dec.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss A',
                    'duminică, februarie 14 2010, 3:25:50 PM',
                ],
                ['ddd, hA', 'Dum, 3PM'],
                ['M Mo MM MMMM MMM', '2 2 02 februarie feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 duminică Dum Du'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '7 7 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[a] DDDo[a zi a anului]', 'a 45a zi a anului'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 februarie 2010'],
                ['LLL', '14 februarie 2010 15:25'],
                ['LLLL', 'duminică, 14 februarie 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 feb. 2010'],
                ['lll', '14 feb. 2010 15:25'],
                ['llll', 'Dum, 14 feb. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'ianuarie ian._februarie feb._martie mart._aprilie apr._mai mai_iunie iun._iulie iul._august aug._septembrie sept._octombrie oct._noiembrie nov._decembrie dec.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'duminică Dum Du_luni Lun Lu_marți Mar Ma_miercuri Mie Mi_joi Joi Jo_vineri Vin Vi_sâmbătă Sâm Sâ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'câteva secunde',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'un minut',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'un minut',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minute',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 de minute',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'o oră',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'o oră',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ore',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ore',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 de ore',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'o zi',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'o zi',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 zile',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'o zi',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 zile',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 de zile',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'o lună',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'o lună',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'o lună',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 luni',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 luni',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 luni',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'o lună',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 luni',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'un an',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ani',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'un an',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ani',
            '5 years = 5 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 19 }), true),
            '19 ani',
            '19 years = 19 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 20 }), true),
            '20 de ani',
            '20 years = 20 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 100 }), true),
            '100 de ani',
            '100 years = 100 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 101 }), true),
            '101 ani',
            '101 years = 101 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 119 }), true),
            '119 ani',
            '119 years = 119 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 120 }), true),
            '120 de ani',
            '120 years = 120 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 219 }), true),
            '219 ani',
            '219 years = 219 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 220 }), true),
            '220 de ani',
            '220 years = 220 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'peste câteva secunde', 'prefix');
        assert.equal(moment(0).from(30000), 'câteva secunde în urmă', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'câteva secunde în urmă',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'peste câteva secunde',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'peste 5 zile', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'azi la 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'azi la 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'azi la 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'mâine la 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'azi la 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ieri la 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [la] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [la] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [la] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[fosta] dddd [la] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[fosta] dddd [la] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[fosta] dddd [la] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ru');

    test('parse', function (assert) {
        var tests = 'январь янв._февраль февр._март март_апрель апр._май май_июнь июнь_июль июль_август авг._сентябрь сент._октябрь окт._ноябрь нояб._декабрь дек.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }
        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('parse exceptional case', function (assert) {
        assert.equal(
            moment('11 Мая 1989', ['DD MMMM YYYY']).format('DD-MM-YYYY'),
            '11-05-1989'
        );
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, HH:mm:ss',
                    'воскресенье, 14-го февраля 2010, 15:25:50',
                ],
                ['ddd, h A', 'вс, 3 дня'],
                ['M Mo MM MMMM MMM', '2 2-й 02 февраль февр.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14-го 14'],
                ['d do dddd ddd dd', '0 0-й воскресенье вс вс'],
                ['DDD DDDo DDDD', '45 45-й 045'],
                ['w wo ww', '6 6-я 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'дня дня'],
                ['DDDo [день года]', '45-й день года'],
                ['LT', '15:25'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 февраля 2010 г.'],
                ['LLL', '14 февраля 2010 г., 15:25'],
                ['LLLL', 'воскресенье, 14 февраля 2010 г., 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 февр. 2010 г.'],
                ['lll', '14 февр. 2010 г., 15:25'],
                ['llll', 'вс, 14 февр. 2010 г., 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format meridiem', function (assert) {
        assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночи', 'night');
        assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночи', 'night');
        assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'утра', 'morning');
        assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'утра', 'morning');
        assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');
        assert.equal(
            moment([2012, 11, 28, 16, 59]).format('A'),
            'дня',
            'afternoon'
        );
        assert.equal(
            moment([2012, 11, 28, 17, 0]).format('A'),
            'вечера',
            'evening'
        );
        assert.equal(
            moment([2012, 11, 28, 23, 59]).format('A'),
            'вечера',
            'evening'
        );
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-й', '1-й');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-й', '2-й');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-й', '3-й');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-й', '4-й');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-й', '5-й');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-й', '6-й');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-й', '7-й');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-й', '8-й');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-й', '9-й');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-й', '10-й');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-й', '11-й');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-й', '12-й');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-й', '13-й');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-й', '14-й');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-й', '15-й');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-й', '16-й');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-й', '17-й');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-й', '18-й');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-й', '19-й');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-й', '20-й');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-й', '21-й');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-й', '22-й');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-й', '23-й');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-й', '24-й');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-й', '25-й');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-й', '26-й');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-й', '27-й');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-й', '28-й');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-й', '29-й');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-й', '30-й');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-й', '31-й');
    });

    test('format month', function (assert) {
        var expected = 'январь янв._февраль февр._март март_апрель апр._май май_июнь июнь_июль июль_август авг._сентябрь сент._октябрь окт._ноябрь нояб._декабрь дек.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format month case', function (assert) {
        var months = {
                nominative: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split(
                    '_'
                ),
                accusative: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split(
                    '_'
                ),
            },
            i;
        for (i = 0; i < 12; i++) {
            assert.equal(
                moment([2011, i, 1]).format('D MMMM'),
                '1 ' + months.accusative[i],
                '1 ' + months.accusative[i]
            );
            assert.equal(
                moment([2011, i, 1]).format('MMMM'),
                months.nominative[i],
                '1 ' + months.nominative[i]
            );
        }
    });

    test('format month short case', function (assert) {
        var monthsShort = {
                nominative: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split(
                    '_'
                ),
                accusative: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split(
                    '_'
                ),
            },
            i;
        for (i = 0; i < 12; i++) {
            assert.equal(
                moment([2011, i, 1]).format('D MMM'),
                '1 ' + monthsShort.accusative[i],
                '1 ' + monthsShort.accusative[i]
            );
            assert.equal(
                moment([2011, i, 1]).format('MMM'),
                monthsShort.nominative[i],
                '1 ' + monthsShort.nominative[i]
            );
        }
    });

    test('format month case with escaped symbols', function (assert) {
        var months = {
                nominative: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split(
                    '_'
                ),
                accusative: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split(
                    '_'
                ),
            },
            i;
        for (i = 0; i < 12; i++) {
            assert.equal(
                moment([2013, i, 1]).format('D[] MMMM'),
                '1 ' + months.accusative[i],
                '1 ' + months.accusative[i]
            );
            assert.equal(
                moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'),
                '<i>1</i> <b>' + months.accusative[i] + '</b>',
                '1 <b>' + months.accusative[i] + '</b>'
            );
            assert.equal(
                moment([2013, i, 1]).format('D[-й день] MMMM'),
                '1-й день ' + months.accusative[i],
                '1-й день ' + months.accusative[i]
            );
            assert.equal(
                moment([2013, i, 1]).format('D, MMMM'),
                '1, ' + months.nominative[i],
                '1, ' + months.nominative[i]
            );
        }
    });

    test('format month short case with escaped symbols', function (assert) {
        var monthsShort = {
                nominative: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split(
                    '_'
                ),
                accusative: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split(
                    '_'
                ),
            },
            i;
        for (i = 0; i < 12; i++) {
            assert.equal(
                moment([2013, i, 1]).format('D[] MMM'),
                '1 ' + monthsShort.accusative[i],
                '1 ' + monthsShort.accusative[i]
            );
            assert.equal(
                moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMM[</b>]'),
                '<i>1</i> <b>' + monthsShort.accusative[i] + '</b>',
                '1 <b>' + monthsShort.accusative[i] + '</b>'
            );
            assert.equal(
                moment([2013, i, 1]).format('D[-й день] MMM'),
                '1-й день ' + monthsShort.accusative[i],
                '1-й день ' + monthsShort.accusative[i]
            );
            assert.equal(
                moment([2013, i, 1]).format('D, MMM'),
                '1, ' + monthsShort.nominative[i],
                '1, ' + monthsShort.nominative[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'воскресенье вс вс_понедельник пн пн_вторник вт вт_среда ср ср_четверг чт чт_пятница пт пт_суббота сб сб'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'несколько секунд',
            '44 seconds = seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'минута',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'минута',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 минуты',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 31 }), true),
            '31 минута',
            '31 minutes = 31 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 минуты',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'час',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'час',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 часа',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 часов',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 час',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'день',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'день',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 дня',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'день',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 дней',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 11 }), true),
            '11 дней',
            '11 days = 11 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 21 }), true),
            '21 день',
            '21 days = 21 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 дней',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'месяц',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'месяц',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'месяц',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 месяца',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 месяца',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 месяца',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'месяц',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 месяцев',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'год',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 года',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'год',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 лет',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'через несколько секунд', 'prefix');
        assert.equal(moment(0).from(30000), 'несколько секунд назад', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'через несколько секунд',
            'in seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'через 5 дней', 'in 5 days');
        assert.equal(
            moment().add({ m: 31 }).fromNow(),
            'через 31 минуту',
            'in 31 minutes = in 31 minutes'
        );
        assert.equal(
            moment().subtract({ m: 31 }).fromNow(),
            '31 минуту назад',
            '31 minutes ago = 31 minutes ago'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Сегодня, в 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Сегодня, в 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Сегодня, в 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Завтра, в 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Сегодня, в 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ h: 4 }).calendar(),
            'Сегодня, в 8:00',
            'Now minus 4 hours'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Вчера, в 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m, now;

        function makeFormatNext(d) {
            switch (d.day()) {
                case 0:
                    return '[В следующее] dddd, [в] LT';
                case 1:
                case 2:
                case 4:
                    return '[В следующий] dddd, [в] LT';
                case 3:
                case 5:
                case 6:
                    return '[В следующую] dddd, [в] LT';
            }
        }

        function makeFormatThis(d) {
            if (d.day() === 2) {
                return '[Во] dddd, [в] LT';
            } else {
                return '[В] dddd, [в] LT';
            }
        }

        now = moment().startOf('week');
        for (i = 2; i < 7; i++) {
            m = moment(now).add({ d: i });
            assert.equal(
                m.calendar(now),
                m.format(makeFormatThis(m)),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(now),
                m.format(makeFormatThis(m)),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(now),
                m.format(makeFormatThis(m)),
                'Today + ' + i + ' days end of day'
            );
        }

        now = moment().endOf('week');
        for (i = 2; i < 7; i++) {
            m = moment(now).add({ d: i });
            assert.equal(
                m.calendar(now),
                m.format(makeFormatNext(m)),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(now),
                m.format(makeFormatNext(m)),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(now),
                m.format(makeFormatNext(m)),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m, now;

        function makeFormatLast(d) {
            switch (d.day()) {
                case 0:
                    return '[В прошлое] dddd, [в] LT';
                case 1:
                case 2:
                case 4:
                    return '[В прошлый] dddd, [в] LT';
                case 3:
                case 5:
                case 6:
                    return '[В прошлую] dddd, [в] LT';
            }
        }

        function makeFormatThis(d) {
            if (d.day() === 2) {
                return '[Во] dddd, [в] LT';
            } else {
                return '[В] dddd, [в] LT';
            }
        }

        now = moment().startOf('week');
        for (i = 2; i < 7; i++) {
            m = moment(now).subtract({ d: i });
            assert.equal(
                m.calendar(now),
                m.format(makeFormatLast(m)),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(now),
                m.format(makeFormatLast(m)),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(now),
                m.format(makeFormatLast(m)),
                'Today - ' + i + ' days end of day'
            );
        }

        now = moment().endOf('week');
        for (i = 2; i < 7; i++) {
            m = moment(now).subtract({ d: i });
            assert.equal(
                m.calendar(now),
                m.format(makeFormatThis(m)),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(now),
                m.format(makeFormatThis(m)),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(now),
                m.format(makeFormatThis(m)),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting monday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '52 52 52-я',
            'Dec 26 2011 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52-я',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1-я',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1-я',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2-я',
            'Jan  9 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('sd');

    var months = [
            'جنوري',
            'فيبروري',
            'مارچ',
            'اپريل',
            'مئي',
            'جون',
            'جولاءِ',
            'آگسٽ',
            'سيپٽمبر',
            'آڪٽوبر',
            'نومبر',
            'ڊسمبر',
        ],
        days = ['آچر', 'سومر', 'اڱارو', 'اربع', 'خميس', 'جمع', 'ڇنڇر'];

    test('parse', function (assert) {
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (var i = 0; i < 12; i++) {
            equalTest(months[i], 'MMM', i);
            equalTest(months[i], 'MMMM', i);

            equalTestStrict(months[i], 'MMM', i);
            equalTestStrict(months[i], 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'آچر، فيبروري 14 2010، 3:25:50 شام',
                ],
                ['ddd, hA', 'آچر، 3شام'],
                ['M Mo MM MMMM MMM', '2 2 02 فيبروري فيبروري'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 آچر آچر آچر'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '6 6 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'شام شام'],
                ['[سال جو] DDDo[ڏينهن]', 'سال جو 45ڏينهن'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 فيبروري 2010'],
                ['LLL', '14 فيبروري 2010 15:25'],
                ['LLLL', 'آچر، 14 فيبروري 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 فيبروري 2010'],
                ['lll', '14 فيبروري 2010 15:25'],
                ['llll', 'آچر، 14 فيبروري 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        for (var i = 0; i < months.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                months[i] + ' ' + months[i],
                months[i] + ' ' + months[i]
            );
        }
    });

    test('format week', function (assert) {
        for (var i = 0; i < days.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                days[i] + ' ' + days[i] + ' ' + days[i],
                days[i] + ' ' + days[i] + ' ' + days[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'چند سيڪنڊ',
            '44 seconds = چند سيڪنڊ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'هڪ منٽ',
            '45 seconds = هڪ منٽ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'هڪ منٽ',
            '89 seconds = هڪ منٽ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 منٽ',
            '90 seconds = 2 منٽ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 منٽ',
            '44 minutes = 44 منٽ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'هڪ ڪلاڪ',
            '45 minutes = هڪ ڪلاڪ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'هڪ ڪلاڪ',
            '89 minutes = هڪ ڪلاڪ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ڪلاڪ',
            '90 minutes = 2 ڪلاڪ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ڪلاڪ',
            '5 hours = 5 ڪلاڪ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ڪلاڪ',
            '21 hours = 21 ڪلاڪ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'هڪ ڏينهن',
            '22 hours = هڪ ڏينهن'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'هڪ ڏينهن',
            '35 hours = هڪ ڏينهن'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 ڏينهن',
            '36 hours = 2 ڏينهن'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'هڪ ڏينهن',
            '1 day = هڪ ڏينهن'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 ڏينهن',
            '5 days = 5 ڏينهن'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 ڏينهن',
            '25 days = 25 ڏينهن'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'هڪ مهينو',
            '26 days = هڪ مهينو'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'هڪ مهينو',
            '30 days = هڪ مهينو'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'هڪ مهينو',
            '43 days = هڪ مهينو'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 مهينا',
            '46 days = 2 مهينا'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 مهينا',
            '75 days = 2 مهينا'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 مهينا',
            '76 days = 3 مهينا'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'هڪ مهينو',
            '1 month = هڪ مهينو'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 مهينا',
            '5 months = 5 مهينا'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'هڪ سال',
            '345 days = هڪ سال'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 سال',
            '548 days = 2 سال'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'هڪ سال',
            '1 year = هڪ سال'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 سال',
            '5 years = 5 سال'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'چند سيڪنڊ پوء', 'prefix');
        assert.equal(moment(0).from(30000), 'چند سيڪنڊ اڳ', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'چند سيڪنڊ اڳ',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'چند سيڪنڊ پوء',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 ڏينهن پوء', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), 'اڄ 12:00', 'today at the same time');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'اڄ 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'اڄ 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'سڀاڻي 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'اڄ 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ڪالهه 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [اڳين هفتي تي] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [اڳين هفتي تي] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [اڳين هفتي تي] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[گزريل هفتي] dddd [تي] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[گزريل هفتي] dddd [تي] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[گزريل هفتي] dddd [تي] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('se');

    test('parse', function (assert) {
        var i,
            tests = 'ođđajagemánnu ođđj_guovvamánnu guov_njukčamánnu njuk_cuoŋománnu cuo_miessemánnu mies_geassemánnu geas_suoidnemánnu suoi_borgemánnu borg_čakčamánnu čakč_golggotmánnu golg_skábmamánnu skáb_juovlamánnu juov'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'sotnabeaivi, guovvamánnu 14. 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'sotn, 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 guovvamánnu guov'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. sotnabeaivi sotn s'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[jagi] DDDo [beaivi]', 'jagi 45. beaivi'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', 'guovvamánnu 14. b. 2010'],
                ['LLL', 'guovvamánnu 14. b. 2010 ti. 15:25'],
                ['LLLL', 'sotnabeaivi, guovvamánnu 14. b. 2010 ti. 15:25'],
                ['l', '14.2.2010'],
                ['ll', 'guov 14. b. 2010'],
                ['lll', 'guov 14. b. 2010 ti. 15:25'],
                ['llll', 'sotn, guov 14. b. 2010 ti. 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var i,
            expected = 'ođđajagemánnu ođđj_guovvamánnu guov_njukčamánnu njuk_cuoŋománnu cuo_miessemánnu mies_geassemánnu geas_suoidnemánnu suoi_borgemánnu borg_čakčamánnu čakč_golggotmánnu golg_skábmamánnu skáb_juovlamánnu juov'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'sotnabeaivi sotn s_vuossárga vuos v_maŋŋebárga maŋ m_gaskavahkku gask g_duorastat duor d_bearjadat bear b_lávvardat láv L'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'moadde sekunddat',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'okta minuhta',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'okta minuhta',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuhtat',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuhtat',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'okta diimmu',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'okta diimmu',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 diimmut',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 diimmut',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 diimmut',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'okta beaivi',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'okta beaivi',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 beaivvit',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'okta beaivi',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 beaivvit',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 beaivvit',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'okta mánnu',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'okta mánnu',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'okta mánnu',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mánut',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mánut',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mánut',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'okta mánnu',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mánut',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'okta jahki',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 jagit',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'okta jahki',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 jagit',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'moadde sekunddat geažes', 'prefix');
        assert.equal(moment(0).from(30000), 'maŋit moadde sekunddat', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'maŋit moadde sekunddat',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'moadde sekunddat geažes',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            '5 beaivvit geažes',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'otne ti 12:00',
            'Today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'otne ti 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'otne ti 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'ihttin ti 12:00',
            'Tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'otne ti 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ikte ti 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [ti] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [ti] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [ti] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[ovddit] dddd [ti] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[ovddit] dddd [ti] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[ovddit] dddd [ti] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('si');

    test('parse', function (assert) {
        var tests = 'ජනවාරි ජන_පෙබරවාරි පෙබ_මාර්තු මාර්_අප්‍රේල් අප්_මැයි මැයි_ජූනි ජූනි_ජූලි ජූලි_අගෝස්තු අගෝ_සැප්තැම්බර් සැප්_ඔක්තෝබර් ඔක්_නොවැම්බර් නොවැ_දෙසැම්බර් දෙසැ'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'YYYY MMMM Do dddd, a h:mm:ss',
                    '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50',
                ],
                [
                    'YYYY MMMM Do dddd, a h:mm:ss',
                    '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50',
                ],
                ['ddd, A h', 'ඉරි, පස් වරු 3'],
                ['M Mo MM MMMM MMM', '2 2 වැනි 02 පෙබරවාරි පෙබ'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 වැනි 14'],
                ['d do dddd ddd dd', '0 0 වැනි ඉරිදා ඉරි ඉ'],
                ['DDD DDDo DDDD', '45 45 වැනි 045'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'ප.ව. පස් වරු'],
                ['[වසරේ] DDDo [දිනය]', 'වසරේ 45 වැනි දිනය'],
                ['LTS', 'ප.ව. 3:25:50'],
                ['LT', 'ප.ව. 3:25'],
                ['L', '2010/02/14'],
                ['LL', '2010 පෙබරවාරි 14'],
                ['LLL', '2010 පෙබරවාරි 14, ප.ව. 3:25'],
                ['LLLL', '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],
                ['l', '2010/2/14'],
                ['ll', '2010 පෙබ 14'],
                ['lll', '2010 පෙබ 14, ප.ව. 3:25'],
                ['llll', '2010 පෙබ 14 වැනි ඉරි, ප.ව. 3:25:50'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1 වැනි', '1 වැනි');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2 වැනි', '2 වැනි');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3 වැනි', '3 වැනි');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4 වැනි', '4 වැනි');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5 වැනි', '5 වැනි');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6 වැනි', '6 වැනි');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7 වැනි', '7 වැනි');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8 වැනි', '8 වැනි');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9 වැනි', '9 වැනි');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10 වැනි', '10 වැනි');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11 වැනි', '11 වැනි');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12 වැනි', '12 වැනි');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13 වැනි', '13 වැනි');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14 වැනි', '14 වැනි');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15 වැනි', '15 වැනි');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16 වැනි', '16 වැනි');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17 වැනි', '17 වැනි');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18 වැනි', '18 වැනි');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19 වැනි', '19 වැනි');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20 වැනි', '20 වැනි');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21 වැනි', '21 වැනි');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22 වැනි', '22 වැනි');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23 වැනි', '23 වැනි');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24 වැනි', '24 වැනි');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25 වැනි', '25 වැනි');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26 වැනි', '26 වැනි');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27 වැනි', '27 වැනි');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28 වැනි', '28 වැනි');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29 වැනි', '29 වැනි');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30 වැනි', '30 වැනි');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31 වැනි', '31 වැනි');
    });

    test('format month', function (assert) {
        var expected = 'ජනවාරි ජන_පෙබරවාරි පෙබ_මාර්තු මාර්_අප්‍රේල් අප්_මැයි මැයි_ජූනි ජූනි_ජූලි ජූලි_අගෝස්තු අගෝ_සැප්තැම්බර් සැප්_ඔක්තෝබර් ඔක්_නොවැම්බර් නොවැ_දෙසැම්බර් දෙසැ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'ඉරිදා ඉරි ඉ_සඳුදා සඳු ස_අඟහරුවාදා අඟ අ_බදාදා බදා බ_බ්‍රහස්පතින්දා බ්‍රහ බ්‍ර_සිකුරාදා සිකු සි_සෙනසුරාදා සෙන සෙ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'තත්පර කිහිපය',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'මිනිත්තුව',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'මිනිත්තුව',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            'මිනිත්තු 2',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            'මිනිත්තු 44',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'පැය',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'පැය',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            'පැය 2',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            'පැය 5',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            'පැය 21',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'දිනය',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'දිනය',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            'දින 2',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'දිනය',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            'දින 5',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            'දින 25',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'මාසය',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'මාසය',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'මාසය',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            'මාස 2',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            'මාස 2',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            'මාස 3',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'මාසය',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            'මාස 5',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'වසර',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            'වසර 2',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'වසර',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            'වසර 5',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'තත්පර කිහිපයකින්', 'prefix');
        assert.equal(moment(0).from(30000), 'තත්පර කිහිපයකට පෙර', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'තත්පර කිහිපයකට පෙර',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'තත්පර කිහිපයකින්',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'දින 5කින්', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'අද ප.ව. 12:00ට',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'අද ප.ව. 12:25ට',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'අද ප.ව. 1:00ට',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'හෙට ප.ව. 12:00ට',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'අද පෙ.ව. 11:00ට',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ඊයේ ප.ව. 12:00ට',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd LT[ට]'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd LT[ට]'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd LT[ට]'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[පසුගිය] dddd LT[ට]'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[පසුගිය] dddd LT[ට]'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[පසුගිය] dddd LT[ට]'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('sk');

    test('parse', function (assert) {
        var tests = 'január jan._február feb._marec mar._apríl apr._máj máj_jún jún._júl júl._august aug._september sep._október okt._november nov._december dec.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm).month(),
                monthIndex,
                input + ' should be month ' + (monthIndex + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            // Fails for all months
            // equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            // Fails for all months
            // equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            // Fails for all months
            // equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss',
                    'nedeľa, február 14. 2010, 3:25:50',
                ],
                ['ddd, h', 'ne, 3'],
                ['M Mo MM MMMM MMM', '2 2. 02 február feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. nedeľa ne ne'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['DDDo [deň v roku]', '45. deň v roku'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14. február 2010'],
                ['LLL', '14. február 2010 15:25'],
                ['LLLL', 'nedeľa 14. február 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14. feb 2010'],
                ['lll', '14. feb 2010 15:25'],
                ['llll', 'ne 14. feb 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'január jan_február feb_marec mar_apríl apr_máj máj_jún jún_júl júl_august aug_september sep_október okt_november nov_december dec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'nedeľa ne ne_pondelok po po_utorok ut ut_streda st st_štvrtok št št_piatok pi pi_sobota so so'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'pár sekúnd',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'minúta',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'minúta',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minúty',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minút',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'hodina',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'hodina',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 hodiny',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 hodín',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 hodín',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'deň',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'deň',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dni',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'deň',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dní',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dní',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'mesiac',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'mesiac',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'mesiac',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mesiace',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mesiace',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mesiace',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'mesiac',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mesiacov',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'rok',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 roky',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'rok',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 rokov',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'za pár sekúnd', 'prefix');
        assert.equal(moment(0).from(30000), 'pred pár sekundami', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'pred pár sekundami',
            'now from now should display as in the past'
        );
    });

    test('fromNow (future)', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'za pár sekúnd',
            'in a few seconds'
        );
        assert.equal(moment().add({ m: 1 }).fromNow(), 'za minútu', 'in a minute');
        assert.equal(
            moment().add({ m: 3 }).fromNow(),
            'za 3 minúty',
            'in 3 minutes'
        );
        assert.equal(
            moment().add({ m: 10 }).fromNow(),
            'za 10 minút',
            'in 10 minutes'
        );
        assert.equal(moment().add({ h: 1 }).fromNow(), 'za hodinu', 'in an hour');
        assert.equal(moment().add({ h: 3 }).fromNow(), 'za 3 hodiny', 'in 3 hours');
        assert.equal(
            moment().add({ h: 10 }).fromNow(),
            'za 10 hodín',
            'in 10 hours'
        );
        assert.equal(moment().add({ d: 1 }).fromNow(), 'za deň', 'in a day');
        assert.equal(moment().add({ d: 3 }).fromNow(), 'za 3 dni', 'in 3 days');
        assert.equal(moment().add({ d: 10 }).fromNow(), 'za 10 dní', 'in 10 days');
        assert.equal(moment().add({ M: 1 }).fromNow(), 'za mesiac', 'in a month');
        assert.equal(
            moment().add({ M: 3 }).fromNow(),
            'za 3 mesiace',
            'in 3 months'
        );
        assert.equal(
            moment().add({ M: 10 }).fromNow(),
            'za 10 mesiacov',
            'in 10 months'
        );
        assert.equal(moment().add({ y: 1 }).fromNow(), 'za rok', 'in a year');
        assert.equal(moment().add({ y: 3 }).fromNow(), 'za 3 roky', 'in 3 years');
        assert.equal(
            moment().add({ y: 10 }).fromNow(),
            'za 10 rokov',
            'in 10 years'
        );
    });

    test('fromNow (past)', function (assert) {
        assert.equal(
            moment().subtract({ s: 30 }).fromNow(),
            'pred pár sekundami',
            'a few seconds ago'
        );
        assert.equal(
            moment().subtract({ m: 1 }).fromNow(),
            'pred minútou',
            'a minute ago'
        );
        assert.equal(
            moment().subtract({ m: 3 }).fromNow(),
            'pred 3 minútami',
            '3 minutes ago'
        );
        assert.equal(
            moment().subtract({ m: 10 }).fromNow(),
            'pred 10 minútami',
            '10 minutes ago'
        );
        assert.equal(
            moment().subtract({ h: 1 }).fromNow(),
            'pred hodinou',
            'an hour ago'
        );
        assert.equal(
            moment().subtract({ h: 3 }).fromNow(),
            'pred 3 hodinami',
            '3 hours ago'
        );
        assert.equal(
            moment().subtract({ h: 10 }).fromNow(),
            'pred 10 hodinami',
            '10 hours ago'
        );
        assert.equal(
            moment().subtract({ d: 1 }).fromNow(),
            'pred dňom',
            'a day ago'
        );
        assert.equal(
            moment().subtract({ d: 3 }).fromNow(),
            'pred 3 dňami',
            '3 days ago'
        );
        assert.equal(
            moment().subtract({ d: 10 }).fromNow(),
            'pred 10 dňami',
            '10 days ago'
        );
        assert.equal(
            moment().subtract({ M: 1 }).fromNow(),
            'pred mesiacom',
            'a month ago'
        );
        assert.equal(
            moment().subtract({ M: 3 }).fromNow(),
            'pred 3 mesiacmi',
            '3 months ago'
        );
        assert.equal(
            moment().subtract({ M: 10 }).fromNow(),
            'pred 10 mesiacmi',
            '10 months ago'
        );
        assert.equal(
            moment().subtract({ y: 1 }).fromNow(),
            'pred rokom',
            'a year ago'
        );
        assert.equal(
            moment().subtract({ y: 3 }).fromNow(),
            'pred 3 rokmi',
            '3 years ago'
        );
        assert.equal(
            moment().subtract({ y: 10 }).fromNow(),
            'pred 10 rokmi',
            '10 years ago'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'dnes o 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'dnes o 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'dnes o 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'zajtra o 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'dnes o 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'včera o 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m, nextDay;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            nextDay = '';
            switch (m.day()) {
                case 0:
                    nextDay = 'v nedeľu';
                    break;
                case 1:
                    nextDay = 'v pondelok';
                    break;
                case 2:
                    nextDay = 'v utorok';
                    break;
                case 3:
                    nextDay = 'v stredu';
                    break;
                case 4:
                    nextDay = 'vo štvrtok';
                    break;
                case 5:
                    nextDay = 'v piatok';
                    break;
                case 6:
                    nextDay = 'v sobotu';
                    break;
            }
            assert.equal(
                m.calendar(),
                m.format('[' + nextDay + '] [o] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[' + nextDay + '] [o] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[' + nextDay + '] [o] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m, lastDay;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            lastDay = '';
            switch (m.day()) {
                case 0:
                    lastDay = 'minulú nedeľu';
                    break;
                case 1:
                    lastDay = 'minulý pondelok';
                    break;
                case 2:
                    lastDay = 'minulý utorok';
                    break;
                case 3:
                    lastDay = 'minulú stredu';
                    break;
                case 4:
                    lastDay = 'minulý štvrtok';
                    break;
                case 5:
                    lastDay = 'minulý piatok';
                    break;
                case 6:
                    lastDay = 'minulú sobotu';
                    break;
            }
            assert.equal(
                m.calendar(),
                m.format('[' + lastDay + '] [o] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[' + lastDay + '] [o] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[' + lastDay + '] [o] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('humanize duration', function (assert) {
        assert.equal(
            moment.duration(1, 'minutes').humanize(),
            'minúta',
            'a minute (future)'
        );
        assert.equal(
            moment.duration(1, 'minutes').humanize(true),
            'za minútu',
            'in a minute'
        );
        assert.equal(
            moment.duration(-1, 'minutes').humanize(),
            'minúta',
            'a minute (past)'
        );
        assert.equal(
            moment.duration(-1, 'minutes').humanize(true),
            'pred minútou',
            'a minute ago'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('sl');

    test('parse', function (assert) {
        var tests = 'januar jan._februar feb._marec mar._april apr._maj maj_junij jun._julij jul._avgust avg._september sep._oktober okt._november nov._december dec.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            // Fails only for month 5 (index 4)
            // equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            // Fails only for month 5 (index 4)
            // equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            // Fails only for month 5 (index 4)
            // equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'nedelja, 14. februar 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'ned., 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 februar feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. nedelja ned. ne'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '7 7. 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14. 02. 2010'],
                ['LL', '14. februar 2010'],
                ['LLL', '14. februar 2010 15:25'],
                ['LLLL', 'nedelja, 14. februar 2010 15:25'],
                ['l', '14. 2. 2010'],
                ['ll', '14. feb. 2010'],
                ['lll', '14. feb. 2010 15:25'],
                ['llll', 'ned., 14. feb. 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'januar jan._februar feb._marec mar._april apr._maj maj._junij jun._julij jul._avgust avg._september sep._oktober okt._november nov._december dec.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'nedelja ned. ne_ponedeljek pon. po_torek tor. to_sreda sre. sr_četrtek čet. če_petek pet. pe_sobota sob. so'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'nekaj sekund',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ena minuta',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ena minuta',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuti',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minut',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ena ura',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ena ura',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 uri',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ur',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ur',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'en dan',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'en dan',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dni',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'en dan',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dni',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dni',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'en mesec',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'en mesec',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'en mesec',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 meseca',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 meseca',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mesece',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'en mesec',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mesecev',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'eno leto',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 leti',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'eno leto',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 let',
            '5 years = 5 years'
        );

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 1 }), true),
            'ena minuta',
            'a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 2 }), true),
            '2 minuti',
            '2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 3 }), true),
            '3 minute',
            '3 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 4 }), true),
            '4 minute',
            '4 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 5 }), true),
            '5 minut',
            '5 minutes'
        );

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 1 }), true),
            'ena ura',
            'an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 2 }), true),
            '2 uri',
            '2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 3 }), true),
            '3 ure',
            '3 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 4 }), true),
            '4 ure',
            '4 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ur',
            '5 hours'
        );

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'en dan',
            'a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 2 }), true),
            '2 dni',
            '2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 3 }), true),
            '3 dni',
            '3 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 4 }), true),
            '4 dni',
            '4 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dni',
            '5 days'
        );

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'en mesec',
            'a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 2 }), true),
            '2 meseca',
            '2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 3 }), true),
            '3 mesece',
            '3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 4 }), true),
            '4 mesece',
            '4 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mesecev',
            '5 months'
        );

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'eno leto',
            'a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 2 }), true),
            '2 leti',
            '2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 3 }), true),
            '3 leta',
            '3 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 4 }), true),
            '4 leta',
            '4 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 let',
            '5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'čez nekaj sekund', 'prefix');
        assert.equal(moment(0).from(30000), 'pred nekaj sekundami', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'pred nekaj sekundami',
            'now from now should display as in the past'
        );
    });

    test('fromNow (future)', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'čez nekaj sekund',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ m: 1 }).fromNow(),
            'čez eno minuto',
            'in a minute'
        );
        assert.equal(
            moment().add({ m: 2 }).fromNow(),
            'čez 2 minuti',
            'in 2 minutes'
        );
        assert.equal(
            moment().add({ m: 3 }).fromNow(),
            'čez 3 minute',
            'in 3 minutes'
        );
        assert.equal(
            moment().add({ m: 4 }).fromNow(),
            'čez 4 minute',
            'in 4 minutes'
        );
        assert.equal(
            moment().add({ m: 5 }).fromNow(),
            'čez 5 minut',
            'in 5 minutes'
        );

        assert.equal(moment().add({ h: 1 }).fromNow(), 'čez eno uro', 'in an hour');
        assert.equal(moment().add({ h: 2 }).fromNow(), 'čez 2 uri', 'in 2 hours');
        assert.equal(moment().add({ h: 3 }).fromNow(), 'čez 3 ure', 'in 3 hours');
        assert.equal(moment().add({ h: 4 }).fromNow(), 'čez 4 ure', 'in 4 hours');
        assert.equal(moment().add({ h: 5 }).fromNow(), 'čez 5 ur', 'in 5 hours');

        assert.equal(moment().add({ d: 1 }).fromNow(), 'čez en dan', 'in a day');
        assert.equal(moment().add({ d: 2 }).fromNow(), 'čez 2 dni', 'in 2 days');
        assert.equal(moment().add({ d: 3 }).fromNow(), 'čez 3 dni', 'in 3 days');
        assert.equal(moment().add({ d: 4 }).fromNow(), 'čez 4 dni', 'in 4 days');
        assert.equal(moment().add({ d: 5 }).fromNow(), 'čez 5 dni', 'in 5 days');

        assert.equal(
            moment().add({ M: 1 }).fromNow(),
            'čez en mesec',
            'in a month'
        );
        assert.equal(
            moment().add({ M: 2 }).fromNow(),
            'čez 2 meseca',
            'in 2 months'
        );
        assert.equal(
            moment().add({ M: 3 }).fromNow(),
            'čez 3 mesece',
            'in 3 months'
        );
        assert.equal(
            moment().add({ M: 4 }).fromNow(),
            'čez 4 mesece',
            'in 4 months'
        );
        assert.equal(
            moment().add({ M: 5 }).fromNow(),
            'čez 5 mesecev',
            'in 5 months'
        );

        assert.equal(moment().add({ y: 1 }).fromNow(), 'čez eno leto', 'in a year');
        assert.equal(moment().add({ y: 2 }).fromNow(), 'čez 2 leti', 'in 2 years');
        assert.equal(moment().add({ y: 3 }).fromNow(), 'čez 3 leta', 'in 3 years');
        assert.equal(moment().add({ y: 4 }).fromNow(), 'čez 4 leta', 'in 4 years');
        assert.equal(moment().add({ y: 5 }).fromNow(), 'čez 5 let', 'in 5 years');

        assert.equal(
            moment().subtract({ s: 30 }).fromNow(),
            'pred nekaj sekundami',
            'a few seconds ago'
        );

        assert.equal(
            moment().subtract({ m: 1 }).fromNow(),
            'pred eno minuto',
            'a minute ago'
        );
        assert.equal(
            moment().subtract({ m: 2 }).fromNow(),
            'pred 2 minutama',
            '2 minutes ago'
        );
        assert.equal(
            moment().subtract({ m: 3 }).fromNow(),
            'pred 3 minutami',
            '3 minutes ago'
        );
        assert.equal(
            moment().subtract({ m: 4 }).fromNow(),
            'pred 4 minutami',
            '4 minutes ago'
        );
        assert.equal(
            moment().subtract({ m: 5 }).fromNow(),
            'pred 5 minutami',
            '5 minutes ago'
        );

        assert.equal(
            moment().subtract({ h: 1 }).fromNow(),
            'pred eno uro',
            'an hour ago'
        );
        assert.equal(
            moment().subtract({ h: 2 }).fromNow(),
            'pred 2 urama',
            '2 hours ago'
        );
        assert.equal(
            moment().subtract({ h: 3 }).fromNow(),
            'pred 3 urami',
            '3 hours ago'
        );
        assert.equal(
            moment().subtract({ h: 4 }).fromNow(),
            'pred 4 urami',
            '4 hours ago'
        );
        assert.equal(
            moment().subtract({ h: 5 }).fromNow(),
            'pred 5 urami',
            '5 hours ago'
        );

        assert.equal(
            moment().subtract({ d: 1 }).fromNow(),
            'pred enim dnem',
            'a day ago'
        );
        assert.equal(
            moment().subtract({ d: 2 }).fromNow(),
            'pred 2 dnevoma',
            '2 days ago'
        );
        assert.equal(
            moment().subtract({ d: 3 }).fromNow(),
            'pred 3 dnevi',
            '3 days ago'
        );
        assert.equal(
            moment().subtract({ d: 4 }).fromNow(),
            'pred 4 dnevi',
            '4 days ago'
        );
        assert.equal(
            moment().subtract({ d: 5 }).fromNow(),
            'pred 5 dnevi',
            '5 days ago'
        );

        assert.equal(
            moment().subtract({ M: 1 }).fromNow(),
            'pred enim mesecem',
            'a month ago'
        );
        assert.equal(
            moment().subtract({ M: 2 }).fromNow(),
            'pred 2 mesecema',
            '2 months ago'
        );
        assert.equal(
            moment().subtract({ M: 3 }).fromNow(),
            'pred 3 meseci',
            '3 months ago'
        );
        assert.equal(
            moment().subtract({ M: 4 }).fromNow(),
            'pred 4 meseci',
            '4 months ago'
        );
        assert.equal(
            moment().subtract({ M: 5 }).fromNow(),
            'pred 5 meseci',
            '5 months ago'
        );

        assert.equal(
            moment().subtract({ y: 1 }).fromNow(),
            'pred enim letom',
            'a year ago'
        );
        assert.equal(
            moment().subtract({ y: 2 }).fromNow(),
            'pred 2 letoma',
            '2 years ago'
        );
        assert.equal(
            moment().subtract({ y: 3 }).fromNow(),
            'pred 3 leti',
            '3 years ago'
        );
        assert.equal(
            moment().subtract({ y: 4 }).fromNow(),
            'pred 4 leti',
            '4 years ago'
        );
        assert.equal(
            moment().subtract({ y: 5 }).fromNow(),
            'pred 5 leti',
            '5 years ago'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'danes ob 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'danes ob 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'danes ob 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'jutri ob 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'danes ob 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'včeraj ob 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                    return '[v] [nedeljo] [ob] LT';
                case 3:
                    return '[v] [sredo] [ob] LT';
                case 6:
                    return '[v] [soboto] [ob] LT';
                case 1:
                case 2:
                case 4:
                case 5:
                    return '[v] dddd [ob] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                    return '[prejšnjo] [nedeljo] [ob] LT';
                case 3:
                    return '[prejšnjo] [sredo] [ob] LT';
                case 6:
                    return '[prejšnjo] [soboto] [ob] LT';
                case 1:
                case 2:
                case 4:
                case 5:
                    return '[prejšnji] dddd [ob] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1.',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1.',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2.',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2.',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3.',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('sq');

    test('parse', function (assert) {
        var i,
            tests = 'Janar Jan_Shkurt Shk_Mars Mar_Prill Pri_Maj Maj_Qershor Qer_Korrik Kor_Gusht Gus_Shtator Sht_Tetor Tet_Nëntor Nën_Dhjetor Dhj'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, HH:mm:ss',
                    'E Diel, Shkurt 14. 2010, 15:25:50',
                ],
                ['ddd, HH', 'Die, 15'],
                ['M Mo MM MMMM MMM', '2 2. 02 Shkurt Shk'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. E Diel Die D'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'MD MD'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 Shkurt 2010'],
                ['LLL', '14 Shkurt 2010 15:25'],
                ['LLLL', 'E Diel, 14 Shkurt 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Shk 2010'],
                ['lll', '14 Shk 2010 15:25'],
                ['llll', 'Die, 14 Shk 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('meridiem', function (assert) {
        assert.equal(moment([2011, 2, 23, 0, 0]).format('A'), 'PD', 'before dawn');
        assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), 'MD', 'noon');
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var i,
            expected = 'Janar Jan_Shkurt Shk_Mars Mar_Prill Pri_Maj Maj_Qershor Qer_Korrik Kor_Gusht Gus_Shtator Sht_Tetor Tet_Nëntor Nën_Dhjetor Dhj'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'E Diel Die D_E Hënë Hën H_E Martë Mar Ma_E Mërkurë Mër Më_E Enjte Enj E_E Premte Pre P_E Shtunë Sht Sh'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'disa sekonda',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'një minutë',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'një minutë',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuta',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuta',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'një orë',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'një orë',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 orë',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 orë',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 orë',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'një ditë',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'një ditë',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 ditë',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'një ditë',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 ditë',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 ditë',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'një muaj',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'një muaj',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'një muaj',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 muaj',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 muaj',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 muaj',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'një muaj',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 muaj',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'një vit',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 vite',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'një vit',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 vite',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'në disa sekonda', 'prefix');
        assert.equal(moment(0).from(30000), 'disa sekonda më parë', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'disa sekonda më parë',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'në disa sekonda',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'në 5 ditë', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Sot në 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Sot në 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Sot në 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Nesër në 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Sot në 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Dje në 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [në] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [në] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [në] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [e kaluar në] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [e kaluar në] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [e kaluar në] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('sr-cyrl');

    test('parse', function (assert) {
        var tests = 'јануар јан._фебруар феб._март мар._април апр._мај мај_јун јун_јул јул_август авг._септембар сеп._октобар окт._новембар нов._децембар дец.'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'недеља, 14. фебруар 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'нед., 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 фебруар феб.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. недеља нед. не'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '7 7. 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14. 2. 2010.'],
                ['LL', '14. фебруар 2010.'],
                ['LLL', '14. фебруар 2010. 15:25'],
                ['LLLL', 'недеља, 14. фебруар 2010. 15:25'],
                ['l', '14. 2. 2010.'],
                ['ll', '14. феб. 2010.'],
                ['lll', '14. феб. 2010. 15:25'],
                ['llll', 'нед., 14. феб. 2010. 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'јануар јан._фебруар феб._март мар._април апр._мај мај_јун јун_јул јул_август авг._септембар сеп._октобар окт._новембар нов._децембар дец.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'недеља нед. не_понедељак пон. по_уторак уто. ут_среда сре. ср_четвртак чет. че_петак пет. пе_субота суб. су'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'неколико секунди',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'један минут',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'један минут',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 минуте',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 минута',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'један сат',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'један сат',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 сата',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 сати',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 сати',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'дан',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'дан',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 дана',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'дан',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 дана',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 дана',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'месец',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'месец',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'месец',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 месеца',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 месеца',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 месеца',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'месец',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 месеци',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'годину',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 године',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'годину',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 година',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'за неколико секунди', 'prefix');
        assert.equal(moment(0).from(30000), 'пре неколико секунди', 'prefix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'пре неколико секунди',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'за неколико секунди',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'за 5 дана', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'данас у 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'данас у 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'данас у 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'сутра у 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'данас у 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'јуче у 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                    return '[у] [недељу] [у] LT';
                case 3:
                    return '[у] [среду] [у] LT';
                case 6:
                    return '[у] [суботу] [у] LT';
                case 1:
                case 2:
                case 4:
                case 5:
                    return '[у] dddd [у] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        function makeFormat(d) {
            var lastWeekDay = [
                '[прошле] [недеље] [у] LT',
                '[прошлог] [понедељка] [у] LT',
                '[прошлог] [уторка] [у] LT',
                '[прошле] [среде] [у] LT',
                '[прошлог] [четвртка] [у] LT',
                '[прошлог] [петка] [у] LT',
                '[прошле] [суботе] [у] LT',
            ];

            return lastWeekDay[d.day()];
        }

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1.',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1.',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2.',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2.',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3.',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('sr');

    test('parse', function (assert) {
        var tests = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'nedelja, 14. februar 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'ned., 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 februar feb.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. nedelja ned. ne'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '7 7. 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14. 2. 2010.'],
                ['LL', '14. februar 2010.'],
                ['LLL', '14. februar 2010. 15:25'],
                ['LLLL', 'nedelja, 14. februar 2010. 15:25'],
                ['l', '14. 2. 2010.'],
                ['ll', '14. feb. 2010.'],
                ['lll', '14. feb. 2010. 15:25'],
                ['llll', 'ned., 14. feb. 2010. 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'nedelja ned. ne_ponedeljak pon. po_utorak uto. ut_sreda sre. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'nekoliko sekundi',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'jedan minut',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'jedan minut',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minute',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuta',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'jedan sat',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'jedan sat',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 sata',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 sati',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 sati',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'dan',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'dan',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dana',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'dan',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dana',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dana',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'mesec',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'mesec',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'mesec',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 meseca',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 meseca',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 meseca',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'mesec',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 meseci',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'godinu',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 godine',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'godinu',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 godina',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'za nekoliko sekundi', 'prefix');
        assert.equal(moment(0).from(30000), 'pre nekoliko sekundi', 'prefix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'pre nekoliko sekundi',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'za nekoliko sekundi',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'za 5 dana', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'danas u 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'danas u 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'danas u 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'sutra u 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'danas u 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'juče u 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                    return '[u] [nedelju] [u] LT';
                case 3:
                    return '[u] [sredu] [u] LT';
                case 6:
                    return '[u] [subotu] [u] LT';
                case 1:
                case 2:
                case 4:
                case 5:
                    return '[u] dddd [u] LT';
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        function makeFormat(d) {
            var lastWeekDay = [
                '[prošle] [nedelje] [u] LT',
                '[prošlog] [ponedeljka] [u] LT',
                '[prošlog] [utorka] [u] LT',
                '[prošle] [srede] [u] LT',
                '[prošlog] [četvrtka] [u] LT',
                '[prošlog] [petka] [u] LT',
                '[prošle] [subote] [u] LT',
            ];

            return lastWeekDay[d.day()];
        }

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1.',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1.',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2.',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2.',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3.',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ss');

    test('parse', function (assert) {
        var tests = "Bhimbidvwane Bhi_Indlovana Ina_Indlov'lenkhulu Inu_Mabasa Mab_Inkhwekhweti Ink_Inhlaba Inh_Kholwane Kho_Ingci Igc_Inyoni Iny_Imphala Imp_Lweti lwe_Ingongoni Igo".split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('parse meridiem', function (assert) {
        var i,
            b = moment(),
            meridiemTests = [
                // h a patterns, expected hours, isValid
                ['10 ekuseni', 10, true],
                ['11 emini', 11, true],
                ['3 entsambama', 15, true],
                ['4 entsambama', 16, true],
                ['6 entsambama', 18, true],
                ['7 ebusuku', 19, true],
                ['12 ebusuku', 0, true],
                ['10 am', 10, false],
                ['10 pm', 10, false],
            ],
            parsed;

        // test that a formatted moment including meridiem string can be parsed back to the same moment
        assert.ok(
            b.isSame(
                moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true),
                'seconds'
            ),
            b.format('h:mm:ss a') +
                ' should be equal to ' +
                moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true).format(
                    'h:mm:ss a'
                )
        );

        // test that a formatted moment having a meridiem string can be parsed with strict flag
        assert.ok(
            moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true).isValid(),
            b.format('h:mm:ss a') + ' should be parsed as valid'
        );

        for (i = 0; i < meridiemTests.length; i++) {
            parsed = moment(meridiemTests[i][0], 'h a', 'ss', true);
            assert.equal(
                parsed.isValid(),
                meridiemTests[i][2],
                'validity for ' + meridiemTests[i][0]
            );
            if (parsed.isValid()) {
                assert.equal(
                    parsed.hours(),
                    meridiemTests[i][1],
                    'hours for ' + meridiemTests[i][0]
                );
            }
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Lisontfo, Indlovana 14 2010, 3:25:50 entsambama',
                ],
                ['ddd, h A', 'Lis, 3 entsambama'],
                ['M Mo MM MMMM MMM', '2 2 02 Indlovana Ina'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Lisontfo Lis Li'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '6 6 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'entsambama entsambama'],
                [
                    '[Lilanga] DDDo [lilanga lelinyaka]',
                    'Lilanga 45 lilanga lelinyaka',
                ],
                ['LTS', '3:25:50 entsambama'],
                ['L', '14/02/2010'],
                ['LL', '14 Indlovana 2010'],
                ['LLL', '14 Indlovana 2010 3:25 entsambama'],
                ['LLLL', 'Lisontfo, 14 Indlovana 2010 3:25 entsambama'],
                ['l', '14/2/2010'],
                ['ll', '14 Ina 2010'],
                ['lll', '14 Ina 2010 3:25 entsambama'],
                ['llll', 'Lis, 14 Ina 2010 3:25 entsambama'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = "Bhimbidvwane Bhi_Indlovana Ina_Indlov'lenkhulu Inu_Mabasa Mab_Inkhwekhweti Ink_Inhlaba Inh_Kholwane Kho_Ingci Igc_Inyoni Iny_Imphala Imp_Lweti Lwe_Ingongoni Igo".split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Lisontfo Lis Li_Umsombuluko Umb Us_Lesibili Lsb Lb_Lesitsatfu Les Lt_Lesine Lsi Ls_Lesihlanu Lsh Lh_Umgcibelo Umg Ug'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'emizuzwana lomcane',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'umzuzu',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'umzuzu',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 emizuzu',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 emizuzu',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'lihora',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'lihora',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 emahora',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 emahora',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 emahora',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'lilanga',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'lilanga',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 emalanga',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'lilanga',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 emalanga',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 emalanga',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'inyanga',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'inyanga',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'inyanga',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 tinyanga',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 tinyanga',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 tinyanga',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'inyanga',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 tinyanga',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'umnyaka',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 iminyaka',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'umnyaka',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 iminyaka',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'nga emizuzwana lomcane', 'prefix');
        assert.equal(
            moment(0).from(30000),
            'wenteka nga emizuzwana lomcane',
            'suffix'
        );
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'wenteka nga emizuzwana lomcane',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'nga emizuzwana lomcane',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'nga 5 emalanga',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Namuhla nga 12:00 emini',
            'Today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Namuhla nga 12:25 emini',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Namuhla nga 1:00 emini',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Kusasa nga 12:00 emini',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Namuhla nga 11:00 emini',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Itolo nga 12:00 emini',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [nga] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [nga] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [nga] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [leliphelile] [nga] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [leliphelile] [nga] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [leliphelile] [nga] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1',
            'Jan  4 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('sv');

    test('parse', function (assert) {
        var tests = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'söndag, februari 14:e 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'sön, 3PM'],
                ['M Mo MM MMMM MMM', '2 2:a 02 februari feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14:e 14'],
                ['d do dddd ddd dd', '0 0:e söndag sön sö'],
                ['DDD DDDo DDDD', '45 45:e 045'],
                ['w wo ww', '6 6:e 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45:e day of the year'],
                ['LTS', '15:25:50'],
                ['L', '2010-02-14'],
                ['LL', '14 februari 2010'],
                ['LLL', '14 februari 2010 kl. 15:25'],
                ['LLLL', 'söndag 14 februari 2010 kl. 15:25'],
                ['l', '2010-2-14'],
                ['ll', '14 feb 2010'],
                ['lll', '14 feb 2010 15:25'],
                ['llll', 'sön 14 feb 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1:a', '1:a');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2:a', '2:a');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3:e', '3:e');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4:e', '4:e');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5:e', '5:e');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6:e', '6:e');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7:e', '7:e');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8:e', '8:e');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9:e', '9:e');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10:e', '10:e');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11:e', '11:e');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12:e', '12:e');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13:e', '13:e');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14:e', '14:e');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15:e', '15:e');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16:e', '16:e');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17:e', '17:e');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18:e', '18:e');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19:e', '19:e');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20:e', '20:e');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21:a', '21:a');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22:a', '22:a');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23:e', '23:e');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24:e', '24:e');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25:e', '25:e');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26:e', '26:e');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27:e', '27:e');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28:e', '28:e');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29:e', '29:e');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30:e', '30:e');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31:a', '31:a');
    });

    test('format month', function (assert) {
        var expected = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'söndag sön sö_måndag mån må_tisdag tis ti_onsdag ons on_torsdag tor to_fredag fre fr_lördag lör lö'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'några sekunder',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'en minut',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'en minut',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuter',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuter',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'en timme',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'en timme',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 timmar',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 timmar',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 timmar',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'en dag',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'en dag',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 dagar',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'en dag',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 dagar',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 dagar',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'en månad',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'en månad',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'en månad',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 månader',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 månader',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 månader',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'en månad',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 månader',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ett år',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 år',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ett år',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 år',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'om några sekunder', 'prefix');
        assert.equal(moment(0).from(30000), 'för några sekunder sedan', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'för några sekunder sedan',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'om några sekunder',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'om 5 dagar', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), 'Idag 12:00', 'today at the same time');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Idag 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Idag 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Imorgon 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Idag 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Igår 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[På] dddd LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[På] dddd LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[På] dddd LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[I] dddd[s] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[I] dddd[s] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[I] dddd[s] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52:a',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1:a',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1:a',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2:a',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2:a',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('sw');

    test('parse', function (assert) {
        var tests = 'Januari Jan_Februari Feb_Machi Mac_Aprili Apr_Mei Mei_Juni Jun_Julai Jul_Agosti Ago_Septemba Sep_Oktoba Okt_Novemba Nov_Desemba Des'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Jumapili, Februari 14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Jpl, 3PM'],
                ['M Mo MM MMMM MMM', '2 2 02 Februari Feb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Jumapili Jpl J2'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '7 7 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[siku] DDDo [ya mwaka]', 'siku 45 ya mwaka'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 Februari 2010'],
                ['LLL', '14 Februari 2010 15:25'],
                ['LLLL', 'Jumapili, 14 Februari 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 Feb 2010'],
                ['lll', '14 Feb 2010 15:25'],
                ['llll', 'Jpl, 14 Feb 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'Januari Jan_Februari Feb_Machi Mac_Aprili Apr_Mei Mei_Juni Jun_Julai Jul_Agosti Ago_Septemba Sep_Oktoba Okt_Novemba Nov_Desemba Des'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Jumapili Jpl J2_Jumatatu Jtat J3_Jumanne Jnne J4_Jumatano Jtan J5_Alhamisi Alh Al_Ijumaa Ijm Ij_Jumamosi Jmos J1'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'hivi punde',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'dakika moja',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'dakika moja',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            'dakika 2',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            'dakika 44',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'saa limoja',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'saa limoja',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            'masaa 2',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            'masaa 5',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            'masaa 21',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'siku moja',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'siku moja',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            'siku 2',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'siku moja',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            'siku 5',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            'siku 25',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'mwezi mmoja',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'mwezi mmoja',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'mwezi mmoja',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            'miezi 2',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            'miezi 2',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            'miezi 3',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'mwezi mmoja',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            'miezi 5',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'mwaka mmoja',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            'miaka 2',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'mwaka mmoja',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            'miaka 5',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'hivi punde baadaye', 'prefix');
        assert.equal(moment(0).from(30000), 'tokea hivi punde', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'tokea hivi punde',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'hivi punde baadaye',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'siku 5 baadaye',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);
        assert.equal(
            moment(a).calendar(),
            'leo saa 12:00 PM',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'leo saa 12:25 PM',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'leo saa 01:00 PM',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'kesho saa 12:00 PM',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'leo saa 11:00 AM',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'jana 12:00 PM',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[wiki ijayo] dddd [saat] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[wiki ijayo] dddd [saat] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[wiki ijayo] dddd [saat] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[wiki iliyopita] dddd [saat] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[wiki iliyopita] dddd [saat] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[wiki iliyopita] dddd [saat] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ta');

    test('parse', function (assert) {
        var tests = 'ஜனவரி ஜனவரி_பிப்ரவரி பிப்ரவரி_மார்ச் மார்ச்_ஏப்ரல் ஏப்ரல்_மே மே_ஜூன் ஜூன்_ஜூலை ஜூலை_ஆகஸ்ட் ஆகஸ்ட்_செப்டெம்பர் செப்டெம்பர்_அக்டோபர் அக்டோபர்_நவம்பர் நவம்பர்_டிசம்பர் டிசம்பர்'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'ஞாயிற்றுக்கிழமை, பிப்ரவரி ௧௪வது ௨௦௧௦, ௩:௨௫:௫௦  எற்பாடு',
                ],
                ['ddd, hA', 'ஞாயிறு, ௩ எற்பாடு'],
                ['M Mo MM MMMM MMM', '௨ ௨வது ௦௨ பிப்ரவரி பிப்ரவரி'],
                ['YYYY YY', '௨௦௧௦ ௧௦'],
                ['D Do DD', '௧௪ ௧௪வது ௧௪'],
                ['d do dddd ddd dd', '௦ ௦வது ஞாயிற்றுக்கிழமை ஞாயிறு ஞா'],
                ['DDD DDDo DDDD', '௪௫ ௪௫வது ௦௪௫'],
                ['w wo ww', '௮ ௮வது ௦௮'],
                ['h hh', '௩ ௦௩'],
                ['H HH', '௧௫ ௧௫'],
                ['m mm', '௨௫ ௨௫'],
                ['s ss', '௫௦ ௫௦'],
                ['a A', ' எற்பாடு  எற்பாடு'],
                ['[ஆண்டின்] DDDo  [நாள்]', 'ஆண்டின் ௪௫வது  நாள்'],
                ['LTS', '௧௫:௨௫:௫௦'],
                ['L', '௧௪/௦௨/௨௦௧௦'],
                ['LL', '௧௪ பிப்ரவரி ௨௦௧௦'],
                ['LLL', '௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],
                ['LLLL', 'ஞாயிற்றுக்கிழமை, ௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],
                ['l', '௧௪/௨/௨௦௧௦'],
                ['ll', '௧௪ பிப்ரவரி ௨௦௧௦'],
                ['lll', '௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],
                ['llll', 'ஞாயிறு, ௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '௧வது', '௧வது');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '௨வது', '௨வது');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '௩வது', '௩வது');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '௪வது', '௪வது');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '௫வது', '௫வது');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '௬வது', '௬வது');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '௭வது', '௭வது');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '௮வது', '௮வது');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '௯வது', '௯வது');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '௧௦வது', '௧௦வது');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '௧௧வது', '௧௧வது');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '௧௨வது', '௧௨வது');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '௧௩வது', '௧௩வது');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '௧௪வது', '௧௪வது');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '௧௫வது', '௧௫வது');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '௧௬வது', '௧௬வது');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '௧௭வது', '௧௭வது');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '௧௮வது', '௧௮வது');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '௧௯வது', '௧௯வது');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '௨௦வது', '௨௦வது');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '௨௧வது', '௨௧வது');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '௨௨வது', '௨௨வது');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '௨௩வது', '௨௩வது');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '௨௪வது', '௨௪வது');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '௨௫வது', '௨௫வது');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '௨௬வது', '௨௬வது');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '௨௭வது', '௨௭வது');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '௨௮வது', '௨௮வது');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '௨௯வது', '௨௯வது');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '௩௦வது', '௩௦வது');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '௩௧வது', '௩௧வது');
    });

    test('format month', function (assert) {
        var expected = 'ஜனவரி ஜனவரி_பிப்ரவரி பிப்ரவரி_மார்ச் மார்ச்_ஏப்ரல் ஏப்ரல்_மே மே_ஜூன் ஜூன்_ஜூலை ஜூலை_ஆகஸ்ட் ஆகஸ்ட்_செப்டெம்பர் செப்டெம்பர்_அக்டோபர் அக்டோபர்_நவம்பர் நவம்பர்_டிசம்பர் டிசம்பர்'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'ஞாயிற்றுக்கிழமை ஞாயிறு ஞா_திங்கட்கிழமை திங்கள் தி_செவ்வாய்கிழமை செவ்வாய் செ_புதன்கிழமை புதன் பு_வியாழக்கிழமை வியாழன் வி_வெள்ளிக்கிழமை வெள்ளி வெ_சனிக்கிழமை சனி ச'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ஒரு சில விநாடிகள்',
            '44 விநாடிகள் = ஒரு சில விநாடிகள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ஒரு நிமிடம்',
            '45 விநாடிகள் = ஒரு நிமிடம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ஒரு நிமிடம்',
            '89 விநாடிகள் = ஒரு நிமிடம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '௨ நிமிடங்கள்',
            '90 விநாடிகள் = ௨ நிமிடங்கள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '௪௪ நிமிடங்கள்',
            '44 நிமிடங்கள் = 44 நிமிடங்கள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ஒரு மணி நேரம்',
            '45 நிமிடங்கள் = ஒரு மணி நேரம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ஒரு மணி நேரம்',
            '89 நிமிடங்கள் = ஒரு மணி நேரம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '௨ மணி நேரம்',
            '90 நிமிடங்கள் = ௨ மணி நேரம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '௫ மணி நேரம்',
            '5 மணி நேரம் = 5 மணி நேரம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '௨௧ மணி நேரம்',
            '௨௧ மணி நேரம் = ௨௧ மணி நேரம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ஒரு நாள்',
            '௨௨ மணி நேரம் = ஒரு நாள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ஒரு நாள்',
            '௩5 மணி நேரம் = ஒரு நாள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '௨ நாட்கள்',
            '௩6 மணி நேரம் = ௨ days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ஒரு நாள்',
            '௧ நாள் = ஒரு நாள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '௫ நாட்கள்',
            '5 நாட்கள் = 5 நாட்கள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '௨௫ நாட்கள்',
            '௨5 நாட்கள் = ௨5 நாட்கள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ஒரு மாதம்',
            '௨6 நாட்கள் = ஒரு மாதம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ஒரு மாதம்',
            '௩0 நாட்கள் = ஒரு மாதம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ஒரு மாதம்',
            '45 நாட்கள் = ஒரு மாதம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '௨ மாதங்கள்',
            '46 நாட்கள் = ௨ மாதங்கள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '௨ மாதங்கள்',
            '75 நாட்கள் = ௨ மாதங்கள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '௩ மாதங்கள்',
            '76 நாட்கள் = ௩ மாதங்கள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ஒரு மாதம்',
            '௧ மாதம் = ஒரு மாதம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '௫ மாதங்கள்',
            '5 மாதங்கள் = 5 மாதங்கள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ஒரு வருடம்',
            '௩45 நாட்கள் = ஒரு வருடம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '௨ ஆண்டுகள்',
            '548 நாட்கள் = ௨ ஆண்டுகள்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ஒரு வருடம்',
            '௧ வருடம் = ஒரு வருடம்'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '௫ ஆண்டுகள்',
            '5 ஆண்டுகள் = 5 ஆண்டுகள்'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'ஒரு சில விநாடிகள் இல்', 'prefix');
        assert.equal(moment(0).from(30000), 'ஒரு சில விநாடிகள் முன்', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'ஒரு சில விநாடிகள் முன்',
            'இப்போது இருந்து கடந்த காலத்தில் காட்ட வேண்டும்'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'ஒரு சில விநாடிகள் இல்',
            'ஒரு சில விநாடிகள் இல்'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            '௫ நாட்கள் இல்',
            '5 நாட்கள் இல்'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), 'இன்று ௧௨:௦௦', 'இன்று  12:00');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'இன்று ௧௨:௨௫',
            'இன்று  12:25'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'இன்று ௧௩:௦௦',
            'இன்று  13:00'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'நாளை ௧௨:௦௦',
            'நாளை  12:00'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'இன்று ௧௧:௦௦',
            'இன்று  11:00'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'நேற்று ௧௨:௦௦',
            'நேற்று  12:00'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd, LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd, LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd, LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[கடந்த வாரம்] dddd, LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[கடந்த வாரம்] dddd, LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[கடந்த வாரம்] dddd, LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 0, 30]).format('a'),
            ' யாமம்',
            '(after) midnight'
        );
        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('a'),
            ' வைகறை',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('a'), ' காலை', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('a'),
            ' எற்பாடு',
            'during day'
        );
        assert.equal(
            moment([2011, 2, 23, 17, 30]).format('a'),
            ' எற்பாடு',
            'evening'
        );
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('a'),
            ' மாலை',
            'late evening'
        );
        assert.equal(
            moment([2011, 2, 23, 23, 30]).format('a'),
            ' யாமம்',
            '(before) midnight'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('te');

    test('parse', function (assert) {
        var tests = 'జనవరి జన._ఫిబ్రవరి ఫిబ్ర._మార్చి మార్చి_ఏప్రిల్ ఏప్రి._మే మే_జూన్ జూన్_జులై జులై_ఆగస్టు ఆగ._సెప్టెంబర్ సెప్._అక్టోబర్ అక్టో._నవంబర్ నవ._డిసెంబర్ డిసె.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do తేదీ MMMM YYYY, a h:mm:ss',
                    'ఆదివారం, 14వ తేదీ ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25:50',
                ],
                ['ddd, a h గంటలు', 'ఆది, మధ్యాహ్నం 3 గంటలు'],
                ['M Mo నెల MM MMMM MMM', '2 2వ నెల 02 ఫిబ్రవరి ఫిబ్ర.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14వ 14'],
                ['d do dddd ddd dd', '0 0వ ఆదివారం ఆది ఆ'],
                ['DDD DDDo DDDD', '45 45వ 045'],
                ['w wo ww', '8 8వ 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'మధ్యాహ్నం మధ్యాహ్నం'],
                ['LTS', 'మధ్యాహ్నం 3:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 ఫిబ్రవరి 2010'],
                ['LLL', '14 ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25'],
                ['LLLL', 'ఆదివారం, 14 ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25'],
                ['l', '14/2/2010'],
                ['ll', '14 ఫిబ్ర. 2010'],
                ['lll', '14 ఫిబ్ర. 2010, మధ్యాహ్నం 3:25'],
                ['llll', 'ఆది, 14 ఫిబ్ర. 2010, మధ్యాహ్నం 3:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1వ', '1వ');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2వ', '2వ');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3వ', '3వ');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4వ', '4వ');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5వ', '5వ');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6వ', '6వ');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7వ', '7వ');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8వ', '8వ');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9వ', '9వ');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10వ', '10వ');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11వ', '11వ');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12వ', '12వ');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13వ', '13వ');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14వ', '14వ');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15వ', '15వ');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16వ', '16వ');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17వ', '17వ');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18వ', '18వ');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19వ', '19వ');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20వ', '20వ');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21వ', '21వ');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22వ', '22వ');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23వ', '23వ');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24వ', '24వ');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25వ', '25వ');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26వ', '26వ');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27వ', '27వ');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28వ', '28వ');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29వ', '29వ');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30వ', '30వ');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31వ', '31వ');
    });

    test('format month', function (assert) {
        var expected = 'జనవరి జన._ఫిబ్రవరి ఫిబ్ర._మార్చి మార్చి_ఏప్రిల్ ఏప్రి._మే మే_జూన్ జూన్_జులై జులై_ఆగస్టు ఆగ._సెప్టెంబర్ సెప్._అక్టోబర్ అక్టో._నవంబర్ నవ._డిసెంబర్ డిసె.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'ఆదివారం ఆది ఆ_సోమవారం సోమ సో_మంగళవారం మంగళ మం_బుధవారం బుధ బు_గురువారం గురు గు_శుక్రవారం శుక్ర శు_శనివారం శని శ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'కొన్ని క్షణాలు',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ఒక నిమిషం',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ఒక నిమిషం',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 నిమిషాలు',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 నిమిషాలు',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ఒక గంట',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ఒక గంట',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 గంటలు',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 గంటలు',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 గంటలు',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ఒక రోజు',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ఒక రోజు',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 రోజులు',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ఒక రోజు',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 రోజులు',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 రోజులు',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ఒక నెల',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ఒక నెల',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ఒక నెల',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 నెలలు',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 నెలలు',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 నెలలు',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ఒక నెల',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 నెలలు',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ఒక సంవత్సరం',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 సంవత్సరాలు',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ఒక సంవత్సరం',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 సంవత్సరాలు',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'కొన్ని క్షణాలు లో', 'prefix');
        assert.equal(moment(0).from(30000), 'కొన్ని క్షణాలు క్రితం', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'కొన్ని క్షణాలు క్రితం',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'కొన్ని క్షణాలు లో',
            'కొన్ని క్షణాలు లో'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            '5 రోజులు లో',
            '5 రోజులు లో'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'నేడు మధ్యాహ్నం 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'నేడు మధ్యాహ్నం 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 3 }).calendar(),
            'నేడు మధ్యాహ్నం 3:00',
            'Now plus 3 hours'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'రేపు మధ్యాహ్నం 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'నేడు మధ్యాహ్నం 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'నిన్న మధ్యాహ్నం 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd[,] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[గత] dddd[,] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[గత] dddd[,] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[గత] dddd[,] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('a'),
            'రాత్రి',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('a'), 'ఉదయం', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('a'),
            'మధ్యాహ్నం',
            'during day'
        );
        assert.equal(
            moment([2011, 2, 23, 17, 30]).format('a'),
            'సాయంత్రం',
            'evening'
        );
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('a'),
            'సాయంత్రం',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'రాత్రి', 'night');

        assert.equal(
            moment([2011, 2, 23, 2, 30]).format('A'),
            'రాత్రి',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 9, 30]).format('A'), 'ఉదయం', 'morning');
        assert.equal(
            moment([2011, 2, 23, 14, 30]).format('A'),
            'మధ్యాహ్నం',
            ' during day'
        );
        assert.equal(
            moment([2011, 2, 23, 17, 30]).format('A'),
            'సాయంత్రం',
            'evening'
        );
        assert.equal(
            moment([2011, 2, 23, 19, 30]).format('A'),
            'సాయంత్రం',
            'late evening'
        );
        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'రాత్రి', 'night');
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1వ',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1వ',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2వ',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2వ',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3వ',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('tet');

    test('parse', function (assert) {
        var tests = 'Janeiru Jan_Fevereiru Fev_Marsu Mar_Abril Abr_Maiu Mai_Juñu Jun_Jullu Jul_Agustu Ago_Setembru Set_Outubru Out_Novembru Nov_Dezembru Dez'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Domingu, Fevereiru 14th 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Dom, 3PM'],
                ['M Mo MM MMMM MMM', '2 2nd 02 Fevereiru Fev'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14th 14'],
                ['d do dddd ddd dd', '0 0th Domingu Dom Do'],
                ['DDD DDDo DDDD', '45 45th 045'],
                ['w wo ww', '6 6th 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45th day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 Fevereiru 2010'],
                ['LLL', '14 Fevereiru 2010 15:25'],
                ['LLLL', 'Domingu, 14 Fevereiru 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Fev 2010'],
                ['lll', '14 Fev 2010 15:25'],
                ['llll', 'Dom, 14 Fev 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');
    });

    test('format month', function (assert) {
        var expected = 'Janeiru Jan_Fevereiru Fev_Marsu Mar_Abril Abr_Maiu Mai_Juñu Jun_Jullu Jul_Agustu Ago_Setembru Set_Outubru Out_Novembru Nov_Dezembru Dez'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Domingu Dom Do_Segunda Seg Seg_Tersa Ters Te_Kuarta Kua Ku_Kinta Kint Ki_Sesta Sest Ses_Sabadu Sab Sa'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'segundu balun',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'minutu ida',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'minutu ida',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            'minutu 2',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            'minutu 44',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'oras ida',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'oras ida',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            'oras 2',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            'oras 5',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            'oras 21',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'loron ida',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'loron ida',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            'loron 2',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'loron ida',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            'loron 5',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            'loron 25',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'fulan ida',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'fulan ida',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'fulan ida',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            'fulan 2',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            'fulan 2',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            'fulan 3',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'fulan ida',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            'fulan 5',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'tinan ida',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            'tinan 2',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'tinan ida',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            'tinan 5',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'iha segundu balun', 'prefix');
        assert.equal(moment(0).from(30000), 'segundu balun liuba', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'segundu balun liuba',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'iha segundu balun',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'iha loron 5', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Ohin iha 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Ohin iha 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Ohin iha 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Aban iha 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Ohin iha 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Horiseik iha 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [iha] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [iha] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [iha] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [semana kotuk] [iha] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [semana kotuk] [iha] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [semana kotuk] [iha] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52nd',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1st',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1st',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2nd',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2nd',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('tg');

    test('parse', function (assert) {
        var tests = 'январ янв_феврал фев_март мар_апрел апр_май май_июн июн_июл июл_август авг_сентябр сен_октябр окт_ноябр ноя_декабр дек'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss',
                    'якшанбе, 14-ум феврали 2010, 3:25:50',
                ],
                ['ddd, h A', 'яшб, 3 рӯз'],
                ['M Mo MM MMMM MMM', '2 2-юм 02 феврал фев'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14-ум 14'],
                ['d do dddd ddd dd', '0 0-ум якшанбе яшб яш'],
                ['DDD DDDo DDDD', '45 45-ум 045'],
                ['w wo ww', '7 7-ум 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'рӯз рӯз'],
                ['DDDo [рӯзи сол]', '45-ум рӯзи сол'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 феврали 2010'],
                ['LLL', '14 феврали 2010 15:25'],
                ['LLLL', 'якшанбе, 14 феврали 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 фев 2010'],
                ['lll', '14 фев 2010 15:25'],
                ['llll', 'яшб, 14 фев 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format meridiem', function (assert) {
        assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'шаб', 'night');
        assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'шаб', 'night');
        assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'субҳ', 'morning');
        assert.equal(moment([2012, 11, 28, 10, 59]).format('A'), 'субҳ', 'morning');
        assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'рӯз', 'afternoon');
        assert.equal(
            moment([2012, 11, 28, 15, 59]).format('A'),
            'рӯз',
            'afternoon'
        );
        assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'бегоҳ', 'evening');
        assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'шаб', 'evening');
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ум', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-юм', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-юм', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ум', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ум', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ум', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ум', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ум', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ум', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ум', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ум', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ум', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ум', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ум', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ум', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ум', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ум', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ум', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ум', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ум', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ум', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-юм', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-юм', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ум', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ум', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ум', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ум', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ум', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ум', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-юм', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ум', '31st');
    });

    test('format month', function (assert) {
        var expected = 'январ янв_феврал фев_март мар_апрел апр_май май_июн июн_июл июл_август авг_сентябр сен_октябр окт_ноябр ноя_декабр дек'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'якшанбе яшб яш_душанбе дшб дш_сешанбе сшб сш_чоршанбе чшб чш_панҷшанбе пшб пш_ҷумъа ҷум ҷм_шанбе шнб шб'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'якчанд сония',
            '44 сония = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'як дақиқа',
            '45 сония = як дақиқа'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'як дақиқа',
            '89 сония = як дақиқа'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 дақиқа',
            '90 сония = 2 дақиқа'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 дақиқа',
            '44 дақиқа = 44 дақиқа'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'як соат',
            '45 дақиқа = як соат'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'як соат',
            '89 дақиқа = як соат'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 соат',
            '90 дақиқа = 2 соат'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 соат',
            '5 соат = 5 соат'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 соат',
            '21 соат = 21 соат'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'як рӯз',
            '22 соат = як рӯз'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'як рӯз',
            '35 соат = як рӯз'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 рӯз',
            '36 соат = 2 рӯз'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'як рӯз',
            '1 рӯз = як рӯз'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 рӯз',
            '5 рӯз = 5 рӯз'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 рӯз',
            '25 рӯз = 25 рӯз'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'як моҳ',
            '26 рӯз = як моҳ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'як моҳ',
            '30 рӯз = як моҳ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'як моҳ',
            '43 рӯз = як моҳ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 моҳ',
            '46 рӯз = 2 моҳ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 моҳ',
            '74 рӯз = 2 моҳ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 моҳ',
            '76 рӯз = 3 моҳ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'як моҳ',
            'як моҳ = як моҳ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 моҳ',
            '5 моҳ = 5 моҳ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'як сол',
            '345 рӯз = як сол'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 сол',
            '548 рӯз = 2 сол'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'як сол',
            '1 сол = як сол'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 сол',
            '5 сол = 5 сол'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'баъди якчанд сония', 'prefix');
        assert.equal(moment(0).from(30000), 'якчанд сония пеш', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'якчанд сония пеш',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'баъди якчанд сония',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'баъди 5 рӯз', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Имрӯз соати 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Имрӯз соати 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Имрӯз соати 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Фардо соати 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Имрӯз соати 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Дирӯз соати 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd[и] [ҳафтаи оянда соати] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd[и] [ҳафтаи оянда соати] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd[и] [ҳафтаи оянда соати] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd[и] [ҳафтаи гузашта соати] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd[и] [ҳафтаи гузашта соати] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd[и] [ҳафтаи гузашта соати] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1-ум',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2-юм',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2-юм',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3-юм',
            'Jan  9 2012 should be week 3'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3-юм',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('th');

    test('parse', function (assert) {
        var tests = 'มกราคม ม.ค._กุมภาพันธ์ ก.พ._มีนาคม มี.ค._เมษายน เม.ย._พฤษภาคม พ.ค._มิถุนายน มิ.ย._กรกฎาคม ก.ค._สิงหาคม ส.ค._กันยายน ก.ย._ตุลาคม ต.ค._พฤศจิกายน พ.ย._ธันวาคม ธ.ค.'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, h:mm:ss a',
                    'อาทิตย์, 14 กุมภาพันธ์ 2010, 3:25:50 หลังเที่ยง',
                ],
                ['ddd, h A', 'อาทิตย์, 3 หลังเที่ยง'],
                ['M Mo MM MMMM MMM', '2 2 02 กุมภาพันธ์ ก.พ.'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 อาทิตย์ อาทิตย์ อา.'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '8 8 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'หลังเที่ยง หลังเที่ยง'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 กุมภาพันธ์ 2010'],
                ['LLL', '14 กุมภาพันธ์ 2010 เวลา 15:25'],
                ['LLLL', 'วันอาทิตย์ที่ 14 กุมภาพันธ์ 2010 เวลา 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 ก.พ. 2010'],
                ['lll', '14 ก.พ. 2010 เวลา 15:25'],
                ['llll', 'วันอาทิตย์ที่ 14 ก.พ. 2010 เวลา 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format month', function (assert) {
        var expected = 'มกราคม ม.ค._กุมภาพันธ์ ก.พ._มีนาคม มี.ค._เมษายน เม.ย._พฤษภาคม พ.ค._มิถุนายน มิ.ย._กรกฎาคม ก.ค._สิงหาคม ส.ค._กันยายน ก.ย._ตุลาคม ต.ค._พฤศจิกายน พ.ย._ธันวาคม ธ.ค.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'อาทิตย์ อาทิตย์ อา._จันทร์ จันทร์ จ._อังคาร อังคาร อ._พุธ พุธ พ._พฤหัสบดี พฤหัส พฤ._ศุกร์ ศุกร์ ศ._เสาร์ เสาร์ ส.'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ไม่กี่วินาที',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            '1 นาที',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            '1 นาที',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 นาที',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 นาที',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            '1 ชั่วโมง',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            '1 ชั่วโมง',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ชั่วโมง',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ชั่วโมง',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ชั่วโมง',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            '1 วัน',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            '1 วัน',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 วัน',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            '1 วัน',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 วัน',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 วัน',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            '1 เดือน',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            '1 เดือน',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            '1 เดือน',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 เดือน',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 เดือน',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 เดือน',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            '1 เดือน',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 เดือน',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            '1 ปี',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ปี',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            '1 ปี',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ปี',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'อีก ไม่กี่วินาที', 'prefix');
        assert.equal(moment(0).from(30000), 'ไม่กี่วินาทีที่แล้ว', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'ไม่กี่วินาทีที่แล้ว',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'อีก ไม่กี่วินาที',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'อีก 5 วัน', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'วันนี้ เวลา 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'วันนี้ เวลา 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'วันนี้ เวลา 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'พรุ่งนี้ เวลา 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'วันนี้ เวลา 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'เมื่อวานนี้ เวลา 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd[หน้า เวลา] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd[หน้า เวลา] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd[หน้า เวลา] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1',
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2',
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3',
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('tk');

    test('parse', function (assert) {
        var tests = 'Ýanwar Ýan_Fewral Few_Mart Mar_Aprel Apr_Maý Maý_Iýun Iýn_Iýul Iýl_Awgust Awg_Sentýabr Sen_Oktýabr Okt_Noýabr Noý_Dekabr Dek'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Ýekşenbe, Fewral 14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Ýek, 3PM'],
                ['M Mo MM MMMM MMM', "2 2'nji 02 Fewral Few"],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Ýekşenbe Ýek Ýk'],
                ['DDD DDDo DDDD', "45 45'inji 045"],
                ['w wo ww', "7 7'nji 07"],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[ýylynyň] DDDo [güni]', "ýylynyň 45'inji güni"],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 Fewral 2010'],
                ['LLL', '14 Fewral 2010 15:25'],
                ['LLLL', 'Ýekşenbe, 14 Fewral 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 Few 2010'],
                ['lll', '14 Few 2010 15:25'],
                ['llll', 'Ýek, 14 Few 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), "1'inji", '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), "2'nji", '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), "3'ünji", '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), "4'ünji", '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), "5'inji", '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), "6'njy", '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), "7'nji", '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), "8'inji", '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), "9'unjy", '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), "10'unjy", '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), "11'inji", '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), "12'nji", '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), "13'ünji", '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), "14'ünji", '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), "15'inji", '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), "16'njy", '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), "17'nji", '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), "18'inji", '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), "19'unjy", '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), "20'nji", '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), "21'inji", '21th');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), "22'nji", '22th');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), "23'ünji", '23th');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), "24'ünji", '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), "25'inji", '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), "26'njy", '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), "27'nji", '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), "28'inji", '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), "29'unjy", '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), "30'unjy", '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), "31'inji", '31st');
    });

    test('format month', function (assert) {
        var expected = 'Ýanwar Ýan_Fewral Few_Mart Mar_Aprel Apr_Maý Maý_Iýun Iýn_Iýul Iýl_Awgust Awg_Sentýabr Sen_Oktýabr Okt_Noýabr Noý_Dekabr Dek'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Ýekşenbe Ýek Ýk_Duşenbe Duş Dş_Sişenbe Siş Sş_Çarşenbe Çar Çr_Penşenbe Pen Pn_Anna Ann An_Şenbe Şen Şn'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'birnäçe sekunt',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'bir minut',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'bir minut',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minut',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minut',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'bir sagat',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'bir sagat',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 sagat',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 sagat',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 sagat',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'bir gün',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'bir gün',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 gün',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'bir gün',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 gün',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 gün',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'bir aý',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'bir aý',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'bir aý',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 aý',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 aý',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 aý',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'bir aý',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 aý',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'bir ýyl',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ýyl',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'bir ýyl',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ýyl',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'birnäçe sekunt soň', 'prefix');
        assert.equal(moment(0).from(30000), 'birnäçe sekunt öň', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'birnäçe sekunt öň',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'birnäçe sekunt soň',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 gün soň', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'bugün sagat 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'bugün sagat 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'bugün sagat 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'ertir sagat 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'bugün sagat 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'düýn 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[indiki] dddd [sagat] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[indiki] dddd [sagat] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[indiki] dddd [sagat] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[geçen] dddd [sagat] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[geçen] dddd [sagat] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[geçen] dddd [sagat] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            "1 01 1'inji",
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            "2 02 2'nji",
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            "2 02 2'nji",
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            "3 03 3'ünji",
            'Jan  9 2012 should be week 3'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            "3 03 3'ünji",
            'Jan 15 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('tl-ph');

    test('parse', function (assert) {
        var tests = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Linggo, Pebrero 14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Lin, 3PM'],
                ['M Mo MM MMMM MMM', '2 2 02 Pebrero Peb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Linggo Lin Li'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '6 6 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LTS', '15:25:50'],
                ['L', '02/14/2010'],
                ['LL', 'Pebrero 14, 2010'],
                ['LLL', 'Pebrero 14, 2010 15:25'],
                ['LLLL', 'Linggo, Pebrero 14, 2010 15:25'],
                ['l', '2/14/2010'],
                ['ll', 'Peb 14, 2010'],
                ['lll', 'Peb 14, 2010 15:25'],
                ['llll', 'Lin, Peb 14, 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Linggo Lin Li_Lunes Lun Lu_Martes Mar Ma_Miyerkules Miy Mi_Huwebes Huw Hu_Biyernes Biy Bi_Sabado Sab Sab'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ilang segundo',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'isang minuto',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'isang minuto',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuto',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuto',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'isang oras',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'isang oras',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 oras',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 oras',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 oras',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'isang araw',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'isang araw',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 araw',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'isang araw',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 araw',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 araw',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'isang buwan',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'isang buwan',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'isang buwan',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 buwan',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 buwan',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 buwan',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'isang buwan',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 buwan',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'isang taon',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 taon',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'isang taon',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 taon',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'sa loob ng ilang segundo', 'prefix');
        assert.equal(
            moment(0).from(30000),
            'ilang segundo ang nakalipas',
            'suffix'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'sa loob ng ilang segundo',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'sa loob ng 5 araw',
            'in 5 days'
        );
    });

    test('same day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            '12:00 ngayong araw',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            '12:25 ngayong araw',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            '13:00 ngayong araw',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Bukas ng 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            '11:00 ngayong araw',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            '12:00 kahapon',
            'yesterday at the same time'
        );
    });

    test('same next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('LT [sa susunod na] dddd'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('LT [sa susunod na] dddd'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('LT [sa susunod na] dddd'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('same last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('LT [noong nakaraang] dddd'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('LT [noong nakaraang] dddd'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('LT [noong nakaraang] dddd'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('same all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('tlh');

    test('parse', function (assert) {
        var tests = 'tera’ jar wa’.jar wa’_tera’ jar cha’.jar cha’_tera’ jar wej.jar wej_tera’ jar loS.jar loS_tera’ jar vagh.jar vagh_tera’ jar jav.jar jav_tera’ jar Soch.jar Soch_tera’ jar chorgh.jar chorgh_tera’ jar Hut.jar Hut_tera’ jar wa’maH.jar wa’maH_tera’ jar wa’maH wa’.jar wa’maH wa’_tera’ jar wa’maH cha’.jar wa’maH cha’'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split('.');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'lojmItjaj, tera’ jar cha’ 14. 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'lojmItjaj, 3PM'],
                ['M Mo MM MMMM MMM', '2 2. 02 tera’ jar cha’ jar cha’'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. lojmItjaj lojmItjaj lojmItjaj'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[DIS jaj] DDDo', 'DIS jaj 45.'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 tera’ jar cha’ 2010'],
                ['LLL', '14 tera’ jar cha’ 2010 15:25'],
                ['LLLL', 'lojmItjaj, 14 tera’ jar cha’ 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 jar cha’ 2010'],
                ['lll', '14 jar cha’ 2010 15:25'],
                ['llll', 'lojmItjaj, 14 jar cha’ 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'tera’ jar wa’ jar wa’_tera’ jar cha’ jar cha’_tera’ jar wej jar wej_tera’ jar loS jar loS_tera’ jar vagh jar vagh_tera’ jar jav jar jav_tera’ jar Soch jar Soch_tera’ jar chorgh jar chorgh_tera’ jar Hut jar Hut_tera’ jar wa’maH jar wa’maH_tera’ jar wa’maH wa’ jar wa’maH wa’_tera’ jar wa’maH cha’ jar wa’maH cha’'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'lojmItjaj lojmItjaj lojmItjaj_DaSjaj DaSjaj DaSjaj_povjaj povjaj povjaj_ghItlhjaj ghItlhjaj ghItlhjaj_loghjaj loghjaj loghjaj_buqjaj buqjaj buqjaj_ghInjaj ghInjaj ghInjaj'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'puS lup',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'wa’ tup',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'wa’ tup',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            'cha’ tup',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            'loSmaH loS tup',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'wa’ rep',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'wa’ rep',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            'cha’ rep',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            'vagh rep',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            'cha’maH wa’ rep',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'wa’ jaj',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'wa’ jaj',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            'cha’ jaj',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'wa’ jaj',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            'vagh jaj',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            'cha’maH vagh jaj',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'wa’ jar',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'wa’ jar',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'wa’ jar',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            'cha’ jar',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            'cha’ jar',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            'wej jar',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'wa’ jar',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            'vagh jar',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'wa’ DIS',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            'cha’ DIS',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'wa’ DIS',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            'vagh DIS',
            '5 years = 5 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 112 }), true),
            'wa’vatlh wa’maH cha’ DIS',
            '112 years = 112 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 122 }), true),
            'wa’vatlh cha’maH cha’ DIS',
            '122 years = 122 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 213 }), true),
            'cha’vatlh wa’maH wej DIS',
            '213 years = 213 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 223 }), true),
            'cha’vatlh cha’maH wej DIS',
            '223 years = 223 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'puS lup pIq', 'suffix');
        assert.equal(moment(0).from(30000), 'puS lup ret', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'puS lup ret',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'puS lup pIq',
            'in a few seconds'
        );
        assert.equal(moment().add({ h: 1 }).fromNow(), 'wa’ rep pIq', 'in an hour');
        assert.equal(moment().add({ d: 5 }).fromNow(), 'vagh leS', 'in 5 days');
        assert.equal(moment().add({ M: 2 }).fromNow(), 'cha’ waQ', 'in 2 months');
        assert.equal(moment().add({ y: 1 }).fromNow(), 'wa’ nem', 'in a year');
        assert.equal(
            moment().add({ s: -30 }).fromNow(),
            'puS lup ret',
            'a few seconds ago'
        );
        assert.equal(
            moment().add({ h: -1 }).fromNow(),
            'wa’ rep ret',
            'an hour ago'
        );
        assert.equal(moment().add({ d: -5 }).fromNow(), 'vagh Hu’', '5 days ago');
        assert.equal(moment().add({ M: -2 }).fromNow(), 'cha’ wen', '2 months ago');
        assert.equal(moment().add({ y: -1 }).fromNow(), 'wa’ ben', 'a year ago');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'DaHjaj 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'DaHjaj 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'DaHjaj 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'wa’leS 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'DaHjaj 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'wa’Hu’ 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('LLL'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('LLL'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('LLL'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('LLL'),
                'Today - ' + i + ' days current time'
            );

            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('LLL'),
                'Today - ' + i + ' days beginning of day'
            );

            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('LLL'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('tr');

    test('parse', function (assert) {
        var tests = 'Ocak Oca_Şubat Şub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_Ağustos Ağu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            // Fails for months 5 (index 4), 11 (index 10) and 12 (index 11)
            //equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Pazar, Şubat 14 2010, 3:25:50 ös',
                ],
                ['ddd, hA', 'Paz, 3ÖS'],
                ['M Mo MM MMMM MMM', "2 2'nci 02 Şubat Şub"],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Pazar Paz Pz'],
                ['DDD DDDo DDDD', "45 45'inci 045"],
                ['w wo ww', "7 7'nci 07"],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'ös ÖS'],
                ['[yılın] DDDo [günü]', "yılın 45'inci günü"],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 Şubat 2010'],
                ['LLL', '14 Şubat 2010 15:25'],
                ['LLLL', 'Pazar, 14 Şubat 2010 15:25'],
                ['l', '14.2.2010'],
                ['ll', '14 Şub 2010'],
                ['lll', '14 Şub 2010 15:25'],
                ['llll', 'Paz, 14 Şub 2010 15:25'],
            ],
            DDDo = [
                [359, "360'ıncı"],
                [199, "200'üncü"],
                [149, "150'nci"],
            ],
            dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            DDDoDt,
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
        for (i = 0; i < DDDo.length; i++) {
            DDDoDt = moment([2010]);
            assert.equal(
                DDDoDt.add(DDDo[i][0], 'days').format('DDDo'),
                DDDo[i][1],
                DDDo[i][0] + ' ---> ' + DDDo[i][1]
            );
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), "1'inci", '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), "2'nci", '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), "3'üncü", '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), "4'üncü", '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), "5'inci", '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), "6'ncı", '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), "7'nci", '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), "8'inci", '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), "9'uncu", '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), "10'uncu", '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), "11'inci", '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), "12'nci", '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), "13'üncü", '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), "14'üncü", '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), "15'inci", '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), "16'ncı", '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), "17'nci", '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), "18'inci", '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), "19'uncu", '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), "20'nci", '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), "21'inci", '21th');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), "22'nci", '22th');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), "23'üncü", '23th');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), "24'üncü", '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), "25'inci", '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), "26'ncı", '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), "27'nci", '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), "28'inci", '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), "29'uncu", '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), "30'uncu", '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), "31'inci", '31st');
    });

    test('format month', function (assert) {
        var expected = 'Ocak Oca_Şubat Şub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_Ağustos Ağu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Pazar Paz Pz_Pazartesi Pts Pt_Salı Sal Sa_Çarşamba Çar Ça_Perşembe Per Pe_Cuma Cum Cu_Cumartesi Cts Ct'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'birkaç saniye',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'bir dakika',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'bir dakika',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 dakika',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 dakika',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'bir saat',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'bir saat',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 saat',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 saat',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 saat',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'bir gün',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'bir gün',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 gün',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'bir gün',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 gün',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 gün',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'bir ay',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'bir ay',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'bir ay',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 ay',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 ay',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 ay',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'bir ay',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 ay',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'bir yıl',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 yıl',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'bir yıl',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 yıl',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'birkaç saniye sonra', 'prefix');
        assert.equal(moment(0).from(30000), 'birkaç saniye önce', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'birkaç saniye önce',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'birkaç saniye sonra',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 gün sonra', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'bugün saat 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'bugün saat 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'bugün saat 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'yarın saat 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'bugün saat 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'dün 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[gelecek] dddd [saat] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[gelecek] dddd [saat] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[gelecek] dddd [saat] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[geçen] dddd [saat] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[geçen] dddd [saat] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[geçen] dddd [saat] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            "1 01 1'inci",
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            "1 01 1'inci",
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            "2 02 2'nci",
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            "2 02 2'nci",
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            "3 03 3'üncü",
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('tzl');

    test('parse', function (assert) {
        var tests = 'Januar Jan_Fevraglh Fev_Març Mar_Avrïu Avr_Mai Mai_Gün Gün_Julia Jul_Guscht Gus_Setemvar Set_Listopäts Lis_Noemvar Noe_Zecemvar Zec'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h.mm.ss a',
                    "Súladi, Fevraglh 14. 2010, 3.25.50 d'o",
                ],
                ['ddd, hA', "Súl, 3D'O"],
                ['M Mo MM MMMM MMM', '2 2. 02 Fevraglh Fev'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14. 14'],
                ['d do dddd ddd dd', '0 0. Súladi Súl Sú'],
                ['DDD DDDo DDDD', '45 45. 045'],
                ['w wo ww', '6 6. 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', "d'o D'O"],
                ['[the] DDDo [day of the year]', 'the 45. day of the year'],
                ['LTS', '15.25.50'],
                ['L', '14.02.2010'],
                ['LL', '14. Fevraglh dallas 2010'],
                ['LLL', '14. Fevraglh dallas 2010 15.25'],
                ['LLLL', 'Súladi, li 14. Fevraglh dallas 2010 15.25'],
                ['l', '14.2.2010'],
                ['ll', '14. Fev dallas 2010'],
                ['lll', '14. Fev dallas 2010 15.25'],
                ['llll', 'Súl, li 14. Fev dallas 2010 15.25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
    });

    test('format month', function (assert) {
        var expected = 'Januar Jan_Fevraglh Fev_Març Mar_Avrïu Avr_Mai Mai_Gün Gün_Julia Jul_Guscht Gus_Setemvar Set_Listopäts Lis_Noemvar Noe_Zecemvar Zec'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Súladi Súl Sú_Lúneçi Lún Lú_Maitzi Mai Ma_Márcuri Már Má_Xhúadi Xhú Xh_Viénerçi Vié Vi_Sáturi Sát Sá'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'viensas secunds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            "'n míut",
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            "'n míut",
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 míuts',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 míuts',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            "'n þora",
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            "'n þora",
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 þoras',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 þoras',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 þoras',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            "'n ziua",
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            "'n ziua",
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 ziuas',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            "'n ziua",
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 ziuas',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 ziuas',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            "'n mes",
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            "'n mes",
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            "'n mes",
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 mesen',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 mesen',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 mesen',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            "'n mes",
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 mesen',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            "'n ar",
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ars',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            "'n ar",
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ars',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'osprei viensas secunds', 'prefix');
        assert.equal(moment(0).from(30000), "ja'iensas secunds", 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            "ja'iensas secunds",
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'osprei viensas secunds',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'osprei 5 ziuas',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'oxhi à 12.00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'oxhi à 12.25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'oxhi à 13.00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'demà à 12.00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'oxhi à 11.00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ieiri à 12.00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [à] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [à] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [à] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[sür el] dddd [lasteu à] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[sür el] dddd [lasteu à] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[sür el] dddd [lasteu à] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    // Monday is the first day of the week.
    // The week that contains Jan 4th is the first week of the year.

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52.',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1.',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1.',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2.',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2.',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('tzm-latn');

    test('parse', function (assert) {
        var tests = 'innayr innayr_brˤayrˤ brˤayrˤ_marˤsˤ marˤsˤ_ibrir ibrir_mayyw mayyw_ywnyw ywnyw_ywlywz ywlywz_ɣwšt ɣwšt_šwtanbir šwtanbir_ktˤwbrˤ ktˤwbrˤ_nwwanbir nwwanbir_dwjnbir dwjnbir'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'asamas, brˤayrˤ 14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'asamas, 3PM'],
                ['M Mo MM MMMM MMM', '2 2 02 brˤayrˤ brˤayrˤ'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 asamas asamas asamas'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '8 8 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 brˤayrˤ 2010'],
                ['LLL', '14 brˤayrˤ 2010 15:25'],
                ['LLLL', 'asamas 14 brˤayrˤ 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 brˤayrˤ 2010'],
                ['lll', '14 brˤayrˤ 2010 15:25'],
                ['llll', 'asamas 14 brˤayrˤ 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'innayr innayr_brˤayrˤ brˤayrˤ_marˤsˤ marˤsˤ_ibrir ibrir_mayyw mayyw_ywnyw ywnyw_ywlywz ywlywz_ɣwšt ɣwšt_šwtanbir šwtanbir_ktˤwbrˤ ktˤwbrˤ_nwwanbir nwwanbir_dwjnbir dwjnbir'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'asamas asamas asamas_aynas aynas aynas_asinas asinas asinas_akras akras akras_akwas akwas akwas_asimwas asimwas asimwas_asiḍyas asiḍyas asiḍyas'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'imik',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'minuḍ',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'minuḍ',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 minuḍ',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 minuḍ',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'saɛa',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'saɛa',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 tassaɛin',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 tassaɛin',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 tassaɛin',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ass',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ass',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 ossan',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ass',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 ossan',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 ossan',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ayowr',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ayowr',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ayowr',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 iyyirn',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 iyyirn',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 iyyirn',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ayowr',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 iyyirn',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'asgas',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 isgasn',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'asgas',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 isgasn',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'dadkh s yan imik', 'prefix');
        assert.equal(moment(0).from(30000), 'yan imik', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'yan imik',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'dadkh s yan imik',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'dadkh s yan 5 ossan',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'asdkh g 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'asdkh g 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'asdkh g 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'aska g 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'asdkh g 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'assant g 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [g] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [g] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [g] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [g] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [g] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [g] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 31]).format('w ww wo'),
            '1 01 1',
            'Dec 31 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 6]).format('w ww wo'),
            '1 01 1',
            'Jan  6 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '2 02 2',
            'Jan  7 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 13]).format('w ww wo'),
            '2 02 2',
            'Jan 13 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '3 03 3',
            'Jan 14 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('tzm');

    test('parse', function (assert) {
        var tests = 'ⵉⵏⵏⴰⵢⵔ ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ ⴷⵓⵊⵏⴱⵉⵔ'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'ⴰⵙⴰⵎⴰⵙ, ⴱⵕⴰⵢⵕ 14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'ⴰⵙⴰⵎⴰⵙ, 3PM'],
                ['M Mo MM MMMM MMM', '2 2 02 ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '8 8 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45 day of the year'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 ⴱⵕⴰⵢⵕ 2010'],
                ['LLL', '14 ⴱⵕⴰⵢⵕ 2010 15:25'],
                ['LLLL', 'ⴰⵙⴰⵎⴰⵙ 14 ⴱⵕⴰⵢⵕ 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 ⴱⵕⴰⵢⵕ 2010'],
                ['lll', '14 ⴱⵕⴰⵢⵕ 2010 15:25'],
                ['llll', 'ⴰⵙⴰⵎⴰⵙ 14 ⴱⵕⴰⵢⵕ 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'ⵉⵏⵏⴰⵢⵔ ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ ⴷⵓⵊⵏⴱⵉⵔ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ ⴰⵢⵏⴰⵙ ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ ⴰⵙⵉⵏⴰⵙ ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ ⴰⴽⵔⴰⵙ ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ ⴰⴽⵡⴰⵙ ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ ⴰⵙⵉⵎⵡⴰⵙ ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ ⴰⵙⵉⴹⵢⴰⵙ ⴰⵙⵉⴹⵢⴰⵙ'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ⵉⵎⵉⴽ',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ⵎⵉⵏⵓⴺ',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ⵎⵉⵏⵓⴺ',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 ⵎⵉⵏⵓⴺ',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 ⵎⵉⵏⵓⴺ',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ⵙⴰⵄⴰ',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ⵙⴰⵄⴰ',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 ⵜⴰⵙⵙⴰⵄⵉⵏ',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 ⵜⴰⵙⵙⴰⵄⵉⵏ',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 ⵜⴰⵙⵙⴰⵄⵉⵏ',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ⴰⵙⵙ',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ⴰⵙⵙ',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 oⵙⵙⴰⵏ',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ⴰⵙⵙ',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 oⵙⵙⴰⵏ',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 oⵙⵙⴰⵏ',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ⴰⵢoⵓⵔ',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ⴰⵢoⵓⵔ',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ⴰⵢoⵓⵔ',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 ⵉⵢⵢⵉⵔⵏ',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 ⵉⵢⵢⵉⵔⵏ',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 ⵉⵢⵢⵉⵔⵏ',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ⴰⵢoⵓⵔ',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 ⵉⵢⵢⵉⵔⵏ',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ⴰⵙⴳⴰⵙ',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ⵉⵙⴳⴰⵙⵏ',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ⴰⵙⴳⴰⵙ',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ⵉⵙⴳⴰⵙⵏ',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ ⵉⵎⵉⴽ', 'prefix');
        assert.equal(moment(0).from(30000), 'ⵢⴰⵏ ⵉⵎⵉⴽ', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'ⵢⴰⵏ ⵉⵎⵉⴽ',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ ⵉⵎⵉⴽ',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ 5 oⵙⵙⴰⵏ',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'ⴰⵙⴷⵅ ⴴ 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'ⴰⵙⴷⵅ ⴴ 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'ⴰⵙⴷⵅ ⴴ 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'ⴰⵙⴽⴰ ⴴ 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'ⴰⵙⴷⵅ ⴴ 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'ⴰⵚⴰⵏⵜ ⴴ 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [ⴴ] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [ⴴ] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [ⴴ] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [ⴴ] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [ⴴ] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [ⴴ] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 31]).format('w ww wo'),
            '1 01 1',
            'Dec 31 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 6]).format('w ww wo'),
            '1 01 1',
            'Jan  6 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '2 02 2',
            'Jan  7 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 13]).format('w ww wo'),
            '2 02 2',
            'Jan 13 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '3 03 3',
            'Jan 14 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ug-cn');

    test('parse', function (assert) {
        var tests = 'يانۋار يانۋار_فېۋرال فېۋرال_مارت مارت_ئاپرېل ئاپرېل_ماي ماي_ئىيۇن ئىيۇن_ئىيۇل ئىيۇل_ئاۋغۇست ئاۋغۇست_سېنتەبىر سېنتەبىر_ئۆكتەبىر ئۆكتەبىر_نويابىر نويابىر_دېكابىر دېكابىر'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, YYYY MMMM Do, a h:mm:ss',
                    'يەكشەنبە، 2010 فېۋرال 14-كۈنى، چۈشتىن كېيىن 3:25:50',
                ],
                ['dddd, A h', 'يەكشەنبە، چۈشتىن كېيىن 3'],
                ['M Mo MM MMMM MMM', '2 2 02 فېۋرال فېۋرال'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14-كۈنى 14'],
                ['d do dddd ddd dd', '0 0-كۈنى يەكشەنبە يە يە'],
                ['DDD DDDo DDDD', '45 45-كۈنى 045'],
                ['w wo ww', '7 7-ھەپتە 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'چۈشتىن كېيىن چۈشتىن كېيىن'],
                ['[يىلنىڭ] DDDo', 'يىلنىڭ 45-كۈنى'],
                ['LTS', '15:25:50'],
                ['L', '2010-02-14'],
                ['LL', '2010-يىلى2-ئاينىڭ14-كۈنى'],
                ['LLL', '2010-يىلى2-ئاينىڭ14-كۈنى، 15:25'],
                ['LLLL', 'يەكشەنبە، 2010-يىلى2-ئاينىڭ14-كۈنى، 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format month', function (assert) {
        var expected = 'يانۋار يانۋار_فېۋرال فېۋرال_مارت مارت_ئاپرېل ئاپرېل_ماي ماي_ئىيۇن ئىيۇن_ئىيۇل ئىيۇل_ئاۋغۇست ئاۋغۇست_سېنتەبىر سېنتەبىر_ئۆكتەبىر ئۆكتەبىر_نويابىر نويابىر_دېكابىر دېكابىر'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'يەكشەنبە يە يە_دۈشەنبە دۈ دۈ_سەيشەنبە سە سە_چارشەنبە چا چا_پەيشەنبە پە پە_جۈمە جۈ جۈ_شەنبە شە شە'.split(
                '_'
            ),
            i;

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'نەچچە سېكونت',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'بىر مىنۇت',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'بىر مىنۇت',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 مىنۇت',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 مىنۇت',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'بىر سائەت',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'بىر سائەت',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 سائەت',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 سائەت',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 سائەت',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'بىر كۈن',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'بىر كۈن',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 كۈن',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'بىر كۈن',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 كۈن',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 كۈن',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'بىر ئاي',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'بىر ئاي',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'بىر ئاي',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 ئاي',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 ئاي',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 ئاي',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'بىر ئاي',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 ئاي',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'بىر يىل',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 يىل',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'بىر يىل',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 يىل',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'نەچچە سېكونت كېيىن', 'prefix');
        assert.equal(moment(0).from(30000), 'نەچچە سېكونت بۇرۇن', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'نەچچە سېكونت بۇرۇن',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'نەچچە سېكونت كېيىن',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 كۈن كېيىن', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'بۈگۈن سائەت 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'بۈگۈن سائەت 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'بۈگۈن سائەت 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'ئەتە سائەت 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'بۈگۈن سائەت 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'تۆنۈگۈن 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[كېلەركى] dddd [سائەت] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[كېلەركى] dddd [سائەت] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[كېلەركى] dddd [سائەت] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[ئالدىنقى] dddd [سائەت] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[ئالدىنقى] dddd [سائەت] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[ئالدىنقى] dddd [سائەت] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 0, 0]).format('A'),
            'يېرىم كېچە',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 6, 0]).format('A'), 'سەھەر', 'morning');
        assert.equal(
            moment([2011, 2, 23, 9, 0]).format('A'),
            'چۈشتىن بۇرۇن',
            'before noon'
        );
        assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), 'چۈش', 'noon');
        assert.equal(
            moment([2011, 2, 23, 13, 0]).format('A'),
            'چۈشتىن كېيىن',
            'afternoon'
        );
        assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), 'كەچ', 'night');
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1-ھەپتە',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1-ھەپتە',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2-ھەپتە',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2-ھەپتە',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3-ھەپتە',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('uk');

    test('parse', function (assert) {
        var tests = 'січень січ_лютий лют_березень бер_квітень квіт_травень трав_червень черв_липень лип_серпень серп_вересень вер_жовтень жовт_листопад лист_грудень груд'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do MMMM YYYY, HH:mm:ss',
                    'неділя, 14-го лютого 2010, 15:25:50',
                ],
                ['ddd, h A', 'нд, 3 дня'],
                ['M Mo MM MMMM MMM', '2 2-й 02 лютий лют'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14-го 14'],
                ['d do dddd ddd dd', '0 0-й неділя нд нд'],
                ['DDD DDDo DDDD', '45 45-й 045'],
                ['w wo ww', '7 7-й 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'дня дня'],
                ['DDDo [день року]', '45-й день року'],
                ['LTS', '15:25:50'],
                ['L', '14.02.2010'],
                ['LL', '14 лютого 2010 р.'],
                ['LLL', '14 лютого 2010 р., 15:25'],
                ['LLLL', 'неділя, 14 лютого 2010 р., 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format meridiem', function (assert) {
        assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночі', 'night');
        assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночі', 'night');
        assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'ранку', 'morning');
        assert.equal(
            moment([2012, 11, 28, 11, 59]).format('A'),
            'ранку',
            'morning'
        );
        assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');
        assert.equal(
            moment([2012, 11, 28, 16, 59]).format('A'),
            'дня',
            'afternoon'
        );
        assert.equal(
            moment([2012, 11, 28, 17, 0]).format('A'),
            'вечора',
            'evening'
        );
        assert.equal(
            moment([2012, 11, 28, 23, 59]).format('A'),
            'вечора',
            'evening'
        );
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-й', '1-й');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-й', '2-й');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-й', '3-й');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-й', '4-й');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-й', '5-й');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-й', '6-й');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-й', '7-й');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-й', '8-й');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-й', '9-й');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-й', '10-й');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-й', '11-й');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-й', '12-й');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-й', '13-й');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-й', '14-й');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-й', '15-й');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-й', '16-й');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-й', '17-й');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-й', '18-й');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-й', '19-й');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-й', '20-й');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-й', '21-й');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-й', '22-й');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-й', '23-й');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-й', '24-й');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-й', '25-й');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-й', '26-й');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-й', '27-й');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-й', '28-й');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-й', '29-й');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-й', '30-й');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-й', '31-й');
    });

    test('format month', function (assert) {
        var expected = 'січень січ_лютий лют_березень бер_квітень квіт_травень трав_червень черв_липень лип_серпень серп_вересень вер_жовтень жовт_листопад лист_грудень груд'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format month case', function (assert) {
        var months = {
                nominative: 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split(
                    '_'
                ),
                accusative: 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split(
                    '_'
                ),
            },
            i;
        for (i = 0; i < 12; i++) {
            assert.equal(
                moment([2011, i, 1]).format('D MMMM'),
                '1 ' + months.accusative[i],
                '1 ' + months.accusative[i]
            );
            assert.equal(
                moment([2011, i, 1]).format('MMMM'),
                months.nominative[i],
                '1 ' + months.nominative[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'неділя нд нд_понеділок пн пн_вівторок вт вт_середа ср ср_четвер чт чт_п’ятниця пт пт_субота сб сб'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'декілька секунд',
            '44 seconds = seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'хвилина',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'хвилина',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 хвилини',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 хвилини',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'годину',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'годину',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 години',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 годин',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 година',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'день',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'день',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 дні',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'день',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 днів',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 11 }), true),
            '11 днів',
            '11 days = 11 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 21 }), true),
            '21 день',
            '21 days = 21 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 днів',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'місяць',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'місяць',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'місяць',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 місяці',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 місяці',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 місяці',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'місяць',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 місяців',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'рік',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 роки',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'рік',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 років',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'за декілька секунд', 'prefix');
        assert.equal(moment(0).from(30000), 'декілька секунд тому', 'suffix');
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'за декілька секунд',
            'in seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'за 5 днів', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Сьогодні о 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Сьогодні о 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Сьогодні о 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Завтра о 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 2 }).calendar(),
            'Сьогодні о 10:00',
            'Now minus 2 hours'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Вчора о 12:00',
            'yesterday at the same time'
        );
        // A special case for Ukrainian since 11 hours have different preposition
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Сьогодні об 11:00',
            "same day at 11 o'clock"
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[У] dddd [о' + (m.hours() === 11 ? 'б' : '') + '] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[У] dddd [о] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[У] dddd [о] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        function makeFormat(d) {
            switch (d.day()) {
                case 0:
                case 3:
                case 5:
                case 6:
                    return (
                        '[Минулої] dddd [о' + (d.hours() === 11 ? 'б' : '') + '] LT'
                    );
                case 1:
                case 2:
                case 4:
                    return (
                        '[Минулого] dddd [о' +
                        (d.hours() === 11 ? 'б' : '') +
                        '] LT'
                    );
            }
        }

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format(makeFormat(m)),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2011, 11, 26]).format('w ww wo'),
            '1 01 1-й',
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1-й',
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2-й',
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2-й',
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3-й',
            'Jan  9 2012 should be week 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('ur');

    var months = [
            'جنوری',
            'فروری',
            'مارچ',
            'اپریل',
            'مئی',
            'جون',
            'جولائی',
            'اگست',
            'ستمبر',
            'اکتوبر',
            'نومبر',
            'دسمبر',
        ],
        days = ['اتوار', 'پیر', 'منگل', 'بدھ', 'جمعرات', 'جمعہ', 'ہفتہ'];

    test('parse', function (assert) {
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (var i = 0; i < 12; i++) {
            equalTest(months[i], 'MMM', i);
            equalTest(months[i], 'MMMM', i);

            equalTestStrict(months[i], 'MMM', i);
            equalTestStrict(months[i], 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'اتوار، فروری 14 2010، 3:25:50 شام',
                ],
                ['ddd, hA', 'اتوار، 3شام'],
                ['M Mo MM MMMM MMM', '2 2 02 فروری فروری'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 اتوار اتوار اتوار'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '6 6 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'شام شام'],
                ['[سال کا] DDDo[واں دن]', 'سال کا 45واں دن'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 فروری 2010'],
                ['LLL', '14 فروری 2010 15:25'],
                ['LLLL', 'اتوار، 14 فروری 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 فروری 2010'],
                ['lll', '14 فروری 2010 15:25'],
                ['llll', 'اتوار، 14 فروری 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        for (var i = 0; i < months.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                months[i] + ' ' + months[i],
                months[i] + ' ' + months[i]
            );
        }
    });

    test('format week', function (assert) {
        for (var i = 0; i < days.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                days[i] + ' ' + days[i] + ' ' + days[i],
                days[i] + ' ' + days[i] + ' ' + days[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'چند سیکنڈ',
            '44 seconds = چند سیکنڈ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ایک منٹ',
            '45 seconds = ایک منٹ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ایک منٹ',
            '89 seconds = ایک منٹ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 منٹ',
            '90 seconds = 2 منٹ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 منٹ',
            '44 minutes = 44 منٹ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'ایک گھنٹہ',
            '45 minutes = ایک گھنٹہ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'ایک گھنٹہ',
            '89 minutes = ایک گھنٹہ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 گھنٹے',
            '90 minutes = 2 گھنٹے'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 گھنٹے',
            '5 hours = 5 گھنٹے'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 گھنٹے',
            '21 hours = 21 گھنٹے'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ایک دن',
            '22 hours = ایک دن'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ایک دن',
            '35 hours = ایک دن'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 دن',
            '36 hours = 2 دن'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ایک دن',
            '1 day = ایک دن'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 دن',
            '5 days = 5 دن'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 دن',
            '25 days = 25 دن'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'ایک ماہ',
            '26 days = ایک ماہ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'ایک ماہ',
            '30 days = ایک ماہ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'ایک ماہ',
            '43 days = ایک ماہ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 ماہ',
            '46 days = 2 ماہ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 ماہ',
            '75 days = 2 ماہ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 ماہ',
            '76 days = 3 ماہ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'ایک ماہ',
            '1 month = ایک ماہ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 ماہ',
            '5 months = 5 ماہ'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ایک سال',
            '345 days = ایک سال'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 سال',
            '548 days = 2 سال'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ایک سال',
            '1 year = ایک سال'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 سال',
            '5 years = 5 سال'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'چند سیکنڈ بعد', 'prefix');
        assert.equal(moment(0).from(30000), 'چند سیکنڈ قبل', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'چند سیکنڈ قبل',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'چند سیکنڈ بعد',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 دن بعد', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'آج بوقت 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'آج بوقت 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'آج بوقت 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'کل بوقت 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'آج بوقت 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'گذشتہ روز بوقت 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [بوقت] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [بوقت] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [بوقت] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[گذشتہ] dddd [بوقت] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[گذشتہ] dddd [بوقت] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[گذشتہ] dddd [بوقت] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('uz-latn');

    test('parse', function (assert) {
        var tests = 'Yanvar Yan_Fevral Fev_Mart Mar_Aprel Apr_May May_Iyun Iyun_Iyul Iyul_Avgust Avg_Sentabr Sen_Oktabr Okt_Noyabr Noy_Dekabr Dek'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, Do-MMMM YYYY, h:mm:ss',
                    'Yakshanba, 14-Fevral 2010, 3:25:50',
                ],
                ['ddd, h:mm', 'Yak, 3:25'],
                ['M Mo MM MMMM MMM', '2 2 02 Fevral Fev'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Yakshanba Yak Ya'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '7 7 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[yilning] DDDo-[kuni]', 'yilning 45-kuni'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 Fevral 2010'],
                ['LLL', '14 Fevral 2010 15:25'],
                ['LLLL', '14 Fevral 2010, Yakshanba 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Fev 2010'],
                ['lll', '14 Fev 2010 15:25'],
                ['llll', '14 Fev 2010, Yak 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2016, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2016, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2016, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2016, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2016, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2016, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2016, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2016, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2016, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2016, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2016, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2016, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2016, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2016, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2016, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2016, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2016, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2016, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2016, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2016, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2016, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2016, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2016, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2016, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2016, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2016, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2016, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2016, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2016, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2016, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2016, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'Yanvar Yan_Fevral Fev_Mart Mar_Aprel Apr_May May_Iyun Iyun_Iyul Iyul_Avgust Avg_Sentabr Sen_Oktabr Okt_Noyabr Noy_Dekabr Dek'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2016, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Yakshanba Yak Ya_Dushanba Dush Du_Seshanba Sesh Se_Chorshanba Chor Cho_Payshanba Pay Pa_Juma Jum Ju_Shanba Shan Sha'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2016, 0, 3 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2017, 1, 28]);
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ s: 44 }), true),
            'soniya',
            '44 soniya = soniya'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ s: 45 }), true),
            'bir daqiqa',
            '45 soniya = bir daqiqa'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ s: 89 }), true),
            'bir daqiqa',
            '89 soniya = bir daqiqa'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ s: 90 }), true),
            '2 daqiqa',
            '90 soniya = 2 daqiqa'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ m: 44 }), true),
            '44 daqiqa',
            '44 daqiqa = 44 daqiqa'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ m: 45 }), true),
            'bir soat',
            '45 minut = bir soat'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ m: 89 }), true),
            'bir soat',
            '89 minut = bir soat'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ m: 90 }), true),
            '2 soat',
            '90 minut = 2 soat'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ h: 5 }), true),
            '5 soat',
            '5 soat = 5 soat'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ h: 21 }), true),
            '21 soat',
            '21 soat = 21 soat'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ h: 22 }), true),
            'bir kun',
            '22 soat = bir kun'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ h: 35 }), true),
            'bir kun',
            '35 soat = bir kun'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ h: 36 }), true),
            '2 kun',
            '36 soat = 2 kun'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ d: 1 }), true),
            'bir kun',
            '1 kun = 1 kun'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ d: 5 }), true),
            '5 kun',
            '5 kun = 5 kun'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ d: 25 }), true),
            '25 kun',
            '25 kun = 25 kun'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ d: 26 }), true),
            'bir oy',
            '26 kun = bir oy'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ d: 30 }), true),
            'bir oy',
            '30 kun = bir oy'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ d: 43 }), true),
            'bir oy',
            '45 kun = bir oy'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ d: 46 }), true),
            '2 oy',
            '46 kun = 2 oy'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ d: 74 }), true),
            '2 oy',
            '75 kun = 2 oy'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ d: 76 }), true),
            '3 oy',
            '76 kun = 3 oy'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ M: 1 }), true),
            'bir oy',
            'bir oy = bir oy'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ M: 5 }), true),
            '5 oy',
            '5 oy = 5 oy'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ d: 345 }), true),
            'bir yil',
            '345 kun = bir yil'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ d: 548 }), true),
            '2 yil',
            '548 kun = 2 yil'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ y: 1 }), true),
            'bir yil',
            '1 yil = bir yil'
        );
        assert.equal(
            start.from(moment([2017, 1, 28]).add({ y: 5 }), true),
            '5 yil',
            '5 yil = 5 yil'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'Yaqin soniya ichida', 'prefix');
        assert.equal(moment(0).from(30000), 'Bir necha soniya oldin', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'Bir necha soniya oldin',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'Yaqin soniya ichida',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'Yaqin 5 kun ichida',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Bugun soat 12:00 da',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Bugun soat 12:25 da',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Bugun soat 13:00 da',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Ertaga 12:00 da',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Bugun soat 11:00 da',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Kecha soat 12:00 da',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [kuni soat] LT [da]'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [kuni soat] LT [da]'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [kuni soat] LT [da]'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format("[O'tgan] dddd [kuni soat] LT [da]"),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format("[O'tgan] dddd [kuni soat] LT [da]"),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format("[O'tgan] dddd [kuni soat] LT [da]"),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('uz');

    test('parse', function (assert) {
        var tests = 'январ янв_феврал фев_март мар_апрел апр_май май_июн июн_июл июл_август авг_сентябр сен_октябр окт_ноябр ноя_декабр дек'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                ['dddd, Do-MMMM YYYY, h:mm:ss', 'Якшанба, 14-феврал 2010, 3:25:50'],
                ['ddd, h:mm', 'Якш, 3:25'],
                ['M Mo MM MMMM MMM', '2 2 02 феврал фев'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 Якшанба Якш Як'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '7 7 07'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[йилнинг] DDDo-[куни]', 'йилнинг 45-куни'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 феврал 2010'],
                ['LLL', '14 феврал 2010 15:25'],
                ['LLLL', '14 феврал 2010, Якшанба 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 фев 2010'],
                ['lll', '14 фев 2010 15:25'],
                ['llll', '14 фев 2010, Якш 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var expected = 'январ янв_феврал фев_март мар_апрел апр_май май_июн июн_июл июл_август авг_сентябр сен_октябр окт_ноябр ноя_декабр дек'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Якшанба Якш Як_Душанба Душ Ду_Сешанба Сеш Се_Чоршанба Чор Чо_Пайшанба Пай Па_Жума Жум Жу_Шанба Шан Ша'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'фурсат',
            '44 секунд = фурсат'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'бир дакика',
            '45 секунд = бир дакика'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'бир дакика',
            '89 секунд = бир дакика'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 дакика',
            '90 секунд = 2 дакика'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 дакика',
            '44 дакика = 44 дакика'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'бир соат',
            '45 минут = бир соат'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'бир соат',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 соат',
            '90 минут = 2 соат'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 соат',
            '5 соат = 5 соат'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 соат',
            '21 соат = 21 соат'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'бир кун',
            '22 соат = бир кун'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'бир кун',
            '35 соат = бир кун'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 кун',
            '36 соат = 2 кун'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'бир кун',
            '1 кун = 1 кун'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 кун',
            '5 кун = 5 кун'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 кун',
            '25 кун = 25 кун'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'бир ой',
            '26 кун = бир ой'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'бир ой',
            '30 кун = бир ой'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'бир ой',
            '45 кун = бир ой'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 ой',
            '46 кун = 2 ой'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 ой',
            '75 кун = 2 ой'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 ой',
            '76 кун = 3 ой'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'бир ой',
            'бир ой = бир ой'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 ой',
            '5 ой = 5 ой'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'бир йил',
            '345 кун = бир йил'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 йил',
            '548 кун = 2 йил'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'бир йил',
            '1 йил = бир йил'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 йил',
            '5 йил = 5 йил'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'Якин фурсат ичида', 'prefix');
        assert.equal(moment(0).from(30000), 'Бир неча фурсат олдин', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'Бир неча фурсат олдин',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'Якин фурсат ичида',
            'in a few seconds'
        );
        assert.equal(
            moment().add({ d: 5 }).fromNow(),
            'Якин 5 кун ичида',
            'in 5 days'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Бугун соат 12:00 да',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Бугун соат 12:25 да',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Бугун соат 13:00 да',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Эртага 12:00 да',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Бугун соат 11:00 да',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Кеча соат 12:00 да',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [куни соат] LT [да]'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [куни соат] LT [да]'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [куни соат] LT [да]'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[Утган] dddd [куни соат] LT [да]'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[Утган] dddd [куни соат] LT [да]'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[Утган] dddd [куни соат] LT [да]'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '2 02 2',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '3 03 3',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('vi');

    test('parse', function (assert) {
        var i,
            tests = 'tháng 1,Thg 01_tháng 2,Thg 02_tháng 3,Thg 03_tháng 4,Thg 04_tháng 5,Thg 05_tháng 6,Thg 06_tháng 7,Thg 07_tháng 8,Thg 08_tháng 9,Thg 09_tháng 10,Thg 10_tháng 11,Thg 11_tháng 12,Thg 12'.split(
                '_'
            );

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + i
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(',');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'chủ nhật, tháng 2 14 2010, 3:25:50 ch',
                ],
                ['ddd, hA', 'CN, 3CH'],
                ['M Mo MM MMMM MMM', '2 2 02 tháng 2 Thg 02'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14 14'],
                ['d do dddd ddd dd', '0 0 chủ nhật CN CN'],
                ['DDD DDDo DDDD', '45 45 045'],
                ['w wo ww', '6 6 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'ch CH'],
                ['[ngày thứ] DDDo [của năm]', 'ngày thứ 45 của năm'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '14 tháng 2 năm 2010'],
                ['LLL', '14 tháng 2 năm 2010 15:25'],
                ['LLLL', 'chủ nhật, 14 tháng 2 năm 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 Thg 02 2010'],
                ['lll', '14 Thg 02 2010 15:25'],
                ['llll', 'CN, 14 Thg 02 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
    });

    test('format month', function (assert) {
        var i,
            expected = 'tháng 1,Thg 01_tháng 2,Thg 02_tháng 3,Thg 03_tháng 4,Thg 04_tháng 5,Thg 05_tháng 6,Thg 06_tháng 7,Thg 07_tháng 8,Thg 08_tháng 9,Thg 09_tháng 10,Thg 10_tháng 11,Thg 11_tháng 12,Thg 12'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM,MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var i,
            expected = 'chủ nhật CN CN_thứ hai T2 T2_thứ ba T3 T3_thứ tư T4 T4_thứ năm T5 T5_thứ sáu T6 T6_thứ bảy T7 T7'.split(
                '_'
            );

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'vài giây',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'một phút',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'một phút',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 phút',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 phút',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'một giờ',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'một giờ',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 giờ',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 giờ',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 giờ',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'một ngày',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'một ngày',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 ngày',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'một ngày',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 ngày',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 ngày',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'một tháng',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'một tháng',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'một tháng',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 tháng',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 tháng',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 tháng',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'một tháng',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 tháng',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'một năm',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 năm',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'một năm',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 năm',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'vài giây tới', 'prefix');
        assert.equal(moment(0).from(30000), 'vài giây trước', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'vài giây trước',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'vài giây tới',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 ngày tới', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Hôm nay lúc 12:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Hôm nay lúc 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Hôm nay lúc 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Ngày mai lúc 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Hôm nay lúc 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Hôm qua lúc 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [tuần tới lúc] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [tuần tới lúc] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [tuần tới lúc] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [tuần trước lúc] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [tuần trước lúc] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [tuần trước lúc] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('x-pseudo');

    test('parse', function (assert) {
        var tests = 'J~áñúá~rý J~áñ_F~ébrú~árý ~Féb_~Márc~h ~Már_Áp~ríl ~Ápr_~Máý ~Máý_~Júñé~ ~Júñ_Júl~ý ~Júl_Áú~gúst~ ~Áúg_Sép~témb~ér ~Sép_Ó~ctób~ér ~Óct_Ñ~óvém~bér ~Ñóv_~Décé~mbér ~Déc'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'S~úñdá~ý, F~ébrú~árý 14th 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'S~úñ, 3PM'],
                ['M Mo MM MMMM MMM', '2 2nd 02 F~ébrú~árý ~Féb'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14th 14'],
                ['d do dddd ddd dd', '0 0th S~úñdá~ý S~úñ S~ú'],
                ['DDD DDDo DDDD', '45 45th 045'],
                ['w wo ww', '6 6th 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the 45th day of the year'],
                ['LT', '15:25'],
                ['L', '14/02/2010'],
                ['LL', '14 F~ébrú~árý 2010'],
                ['LLL', '14 F~ébrú~árý 2010 15:25'],
                ['LLLL', 'S~úñdá~ý, 14 F~ébrú~árý 2010 15:25'],
                ['l', '14/2/2010'],
                ['ll', '14 ~Féb 2010'],
                ['lll', '14 ~Féb 2010 15:25'],
                ['llll', 'S~úñ, 14 ~Féb 2010 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');
    });

    test('format month', function (assert) {
        var expected = 'J~áñúá~rý J~áñ_F~ébrú~árý ~Féb_~Márc~h ~Már_Áp~ríl ~Ápr_~Máý ~Máý_~Júñé~ ~Júñ_Júl~ý ~Júl_Áú~gúst~ ~Áúg_Sép~témb~ér ~Sép_Ó~ctób~ér ~Óct_Ñ~óvém~bér ~Ñóv_~Décé~mbér ~Déc'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'S~úñdá~ý S~úñ S~ú_Mó~ñdáý~ ~Móñ Mó~_Túé~sdáý~ ~Túé Tú_Wéd~ñésd~áý ~Wéd ~Wé_T~húrs~dáý ~Thú T~h_~Fríd~áý ~Frí Fr~_S~átúr~dáý ~Sát Sá'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'á ~féw ~sécó~ñds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'á ~míñ~úté',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'á ~míñ~úté',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 m~íñú~tés',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 m~íñú~tés',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'á~ñ hó~úr',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'á~ñ hó~úr',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 h~óúrs',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 h~óúrs',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 h~óúrs',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'á ~dáý',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'á ~dáý',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 d~áýs',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'á ~dáý',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 d~áýs',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 d~áýs',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'á ~móñ~th',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'á ~móñ~th',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'á ~móñ~th',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 m~óñt~hs',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 m~óñt~hs',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 m~óñt~hs',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'á ~móñ~th',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 m~óñt~hs',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'á ~ýéár',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 ý~éárs',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'á ~ýéár',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 ý~éárs',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'í~ñ á ~féw ~sécó~ñds', 'prefix');
        assert.equal(moment(0).from(30000), 'á ~féw ~sécó~ñds á~gó', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'á ~féw ~sécó~ñds á~gó',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'í~ñ á ~féw ~sécó~ñds',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'í~ñ 5 d~áýs', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(2).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'T~ódá~ý át 02:00',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'T~ódá~ý át 02:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'T~ódá~ý át 03:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'T~ómó~rró~w át 02:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'T~ódá~ý át 01:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Ý~ést~érdá~ý át 02:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [át] LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [át] LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [át] LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[L~ást] dddd [át] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[L~ást] dddd [át] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[L~ást] dddd [át] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52nd',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 1st',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 1st',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 2nd',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 2nd',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('yo');

    test('parse', function (assert) {
        var tests = 'Sẹ́rẹ́ Sẹ́r_Èrèlè Èrl_Ẹrẹ̀nà Ẹrn_Ìgbé Ìgb_Èbibi Èbi_Òkùdu Òkù_Agẹmo Agẹ_Ògún Ògú_Owewe Owe_Ọ̀wàrà Ọ̀wà_Bélú Bél_Ọ̀pẹ̀̀ Ọ̀pẹ̀̀'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, h:mm:ss a',
                    'Àìkú, Èrèlè ọjọ́ 14 2010, 3:25:50 pm',
                ],
                ['ddd, hA', 'Àìk, 3PM'],
                ['M Mo MM MMMM MMM', '2 ọjọ́ 2 02 Èrèlè Èrl'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 ọjọ́ 14 14'],
                ['d do dddd ddd dd', '0 ọjọ́ 0 Àìkú Àìk Àì'],
                ['DDD DDDo DDDD', '45 ọjọ́ 45 045'],
                ['w wo ww', '6 ọjọ́ 6 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', 'pm PM'],
                ['[the] DDDo [day of the year]', 'the ọjọ́ 45 day of the year'],
                ['LTS', '3:25:50 PM'],
                ['L', '14/02/2010'],
                ['LL', '14 Èrèlè 2010'],
                ['LLL', '14 Èrèlè 2010 3:25 PM'],
                ['LLLL', 'Àìkú, 14 Èrèlè 2010 3:25 PM'],
                ['l', '14/2/2010'],
                ['ll', '14 Èrl 2010'],
                ['lll', '14 Èrl 2010 3:25 PM'],
                ['llll', 'Àìk, 14 Èrl 2010 3:25 PM'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;
        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format ordinal', function (assert) {
        assert.equal(moment([2011, 0, 1]).format('DDDo'), 'ọjọ́ 1', 'ọjọ́ 1');
        assert.equal(moment([2011, 0, 2]).format('DDDo'), 'ọjọ́ 2', 'ọjọ́ 2');
        assert.equal(moment([2011, 0, 3]).format('DDDo'), 'ọjọ́ 3', 'ọjọ́ 3');
        assert.equal(moment([2011, 0, 4]).format('DDDo'), 'ọjọ́ 4', 'ọjọ́ 4');
        assert.equal(moment([2011, 0, 5]).format('DDDo'), 'ọjọ́ 5', 'ọjọ́ 5');
        assert.equal(moment([2011, 0, 6]).format('DDDo'), 'ọjọ́ 6', 'ọjọ́ 6');
        assert.equal(moment([2011, 0, 7]).format('DDDo'), 'ọjọ́ 7', 'ọjọ́ 7');
        assert.equal(moment([2011, 0, 8]).format('DDDo'), 'ọjọ́ 8', 'ọjọ́ 8');
        assert.equal(moment([2011, 0, 9]).format('DDDo'), 'ọjọ́ 9', 'ọjọ́ 9');
        assert.equal(moment([2011, 0, 10]).format('DDDo'), 'ọjọ́ 10', 'ọjọ́ 10');

        assert.equal(moment([2011, 0, 11]).format('DDDo'), 'ọjọ́ 11', 'ọjọ́ 11');
        assert.equal(moment([2011, 0, 12]).format('DDDo'), 'ọjọ́ 12', 'ọjọ́ 12');
        assert.equal(moment([2011, 0, 13]).format('DDDo'), 'ọjọ́ 13', 'ọjọ́ 13');
        assert.equal(moment([2011, 0, 14]).format('DDDo'), 'ọjọ́ 14', 'ọjọ́ 14');
        assert.equal(moment([2011, 0, 15]).format('DDDo'), 'ọjọ́ 15', 'ọjọ́ 15');
        assert.equal(moment([2011, 0, 16]).format('DDDo'), 'ọjọ́ 16', 'ọjọ́ 16');
        assert.equal(moment([2011, 0, 17]).format('DDDo'), 'ọjọ́ 17', 'ọjọ́ 17');
        assert.equal(moment([2011, 0, 18]).format('DDDo'), 'ọjọ́ 18', 'ọjọ́ 18');
        assert.equal(moment([2011, 0, 19]).format('DDDo'), 'ọjọ́ 19', 'ọjọ́ 19');
        assert.equal(moment([2011, 0, 20]).format('DDDo'), 'ọjọ́ 20', 'ọjọ́ 20');

        assert.equal(moment([2011, 0, 21]).format('DDDo'), 'ọjọ́ 21', 'ọjọ́ 21');
        assert.equal(moment([2011, 0, 22]).format('DDDo'), 'ọjọ́ 22', 'ọjọ́ 22');
        assert.equal(moment([2011, 0, 23]).format('DDDo'), 'ọjọ́ 23', 'ọjọ́ 23');
        assert.equal(moment([2011, 0, 24]).format('DDDo'), 'ọjọ́ 24', 'ọjọ́ 24');
        assert.equal(moment([2011, 0, 25]).format('DDDo'), 'ọjọ́ 25', 'ọjọ́ 25');
        assert.equal(moment([2011, 0, 26]).format('DDDo'), 'ọjọ́ 26', 'ọjọ́ 26');
        assert.equal(moment([2011, 0, 27]).format('DDDo'), 'ọjọ́ 27', 'ọjọ́ 27');
        assert.equal(moment([2011, 0, 28]).format('DDDo'), 'ọjọ́ 28', 'ọjọ́ 28');
        assert.equal(moment([2011, 0, 29]).format('DDDo'), 'ọjọ́ 29', 'ọjọ́ 29');
        assert.equal(moment([2011, 0, 30]).format('DDDo'), 'ọjọ́ 30', 'ọjọ́ 30');

        assert.equal(moment([2011, 0, 31]).format('DDDo'), 'ọjọ́ 31', 'ọjọ́ 31');
    });

    test('format month', function (assert) {
        var expected = 'Sẹ́rẹ́ Sẹ́r_Èrèlè Èrl_Ẹrẹ̀nà Ẹrn_Ìgbé Ìgb_Èbibi Èbi_Òkùdu Òkù_Agẹmo Agẹ_Ògún Ògú_Owewe Owe_Ọ̀wàrà Ọ̀wà_Bélú Bél_Ọ̀pẹ̀̀ Ọ̀pẹ̀̀'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = 'Àìkú Àìk Àì_Ajé Ajé Aj_Ìsẹ́gun Ìsẹ́ Ìs_Ọjọ́rú Ọjr Ọr_Ọjọ́bọ Ọjb Ọb_Ẹtì Ẹtì Ẹt_Àbámẹ́ta Àbá Àb'.split(
                '_'
            ),
            i;
        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            'ìsẹjú aayá die',
            '44 seconds = ìsẹjú aayá die'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            'ìsẹjú kan',
            '45 seconds = ìsẹjú kan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            'ìsẹjú kan',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            'ìsẹjú 2',
            '90 seconds = ìsẹjú 2'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            'ìsẹjú 44',
            'ìsẹjú 44 = ìsẹjú 44'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            'wákati kan',
            'ìsẹjú 45 = wákati kan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            'wákati kan',
            'ìsẹjú 89 = wákati kan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            'wákati 2',
            'ìsẹjú 90 = wákati 2'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            'wákati 5',
            'wákati 5 = wákati 5'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            'wákati 21',
            'wákati 21 = wákati 21'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            'ọjọ́ kan',
            '22 wákati = ọjọ́ kan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            'ọjọ́ kan',
            '35 wákati = ọjọ́ kan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            'ọjọ́ 2',
            'wákati 36 = ọjọ́ 2'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            'ọjọ́ kan',
            '1  = ọjọ́ kan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            'ọjọ́ 5',
            'ọjọ́ 5 = ọjọ́  5'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            'ọjọ́ 25',
            'ọjọ́ 25 = ọjọ́ 25'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            'osù kan',
            'ọjọ́ 26 = osù kan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            'osù kan',
            'ọjọ́ 30 = osù kan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            'osù kan',
            'ọjọ́ 43 = osù kan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            'osù 2',
            'ọjọ́ 46 = osù 2'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            'osù 2',
            'ọjọ́ 75 = osù 2'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            'osù 3',
            'ọjọ́ 76 = osù 3'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            'osù kan',
            'osù 1 = osù kan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            'osù 5',
            'osù 5 = osù 5'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            'ọdún kan',
            'ọjọ 345 = ọdún kan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            'ọdún 2',
            'ọjọ 548 = ọdún 2'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            'ọdún kan',
            'ọdún 1 = ọdún kan'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            'ọdún 5',
            'ọdún 5 = ọdún 5'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), 'ní ìsẹjú aayá die', 'prefix');
        assert.equal(moment(0).from(30000), 'ìsẹjú aayá die kọjá', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            'ìsẹjú aayá die kọjá',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            'ní ìsẹjú aayá die',
            'ní ìsẹjú aayá die'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), 'ní ọjọ́ 5', 'ní ọjọ́ 5');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Ònì ni 12:00 PM',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Ònì ni 12:25 PM',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Ònì ni 1:00 PM',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Ọ̀la ni 12:00 PM',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Ònì ni 11:00 AM',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Àna ni 12:00 PM',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format("dddd [Ọsẹ̀ tón'bọ] [ni] LT"),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format("dddd [Ọsẹ̀ tón'bọ] [ni] LT"),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format("dddd [Ọsẹ̀ tón'bọ] [ni] LT"),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;

        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 ọjọ́ 52',
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('w ww wo'),
            '1 01 ọjọ́ 1',
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '1 01 ọjọ́ 1',
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('w ww wo'),
            '2 02 ọjọ́ 2',
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '2 02 ọjọ́ 2',
            'Jan 15 2012 should be week 2'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('zh-cn');

    test('parse', function (assert) {
        var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split(
                '_'
            ),
            i;

        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, a h:mm:ss',
                    '星期日, 二月 14日 2010, 下午 3:25:50',
                ],
                ['ddd, Ah', '周日, 下午3'],
                ['M Mo MM MMMM MMM', '2 2月 02 二月 2月'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14日 14'],
                ['d do dddd ddd dd', '0 0日 星期日 周日 日'],
                ['DDD DDDo DDDD', '45 45日 045'],
                ['w wo ww', '6 6周 06'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', '下午 下午'],
                ['[这年的第] DDDo', '这年的第 45日'],
                ['LTS', '15:25:50'],
                ['L', '2010/02/14'],
                ['LL', '2010年2月14日'],
                ['LLL', '2010年2月14日下午3点25分'],
                ['LLLL', '2010年2月14日星期日下午3点25分'],
                ['l', '2010/2/14'],
                ['ll', '2010年2月14日'],
                ['lll', '2010年2月14日 15:25'],
                ['llll', '2010年2月14日星期日 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format month', function (assert) {
        var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split(
                '_'
            ),
            i;

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = '星期日 周日 日_星期一 周一 一_星期二 周二 二_星期三 周三 三_星期四 周四 四_星期五 周五 五_星期六 周六 六'.split(
                '_'
            ),
            i;

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            '几秒',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            '1 分钟',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            '1 分钟',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 分钟',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 分钟',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            '1 小时',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            '1 小时',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 小时',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 小时',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 小时',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            '1 天',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            '1 天',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 天',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            '1 天',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 天',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 天',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            '1 个月',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            '1 个月',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            '1 个月',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 个月',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 个月',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 个月',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            '1 个月',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 个月',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            '1 年',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 年',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            '1 年',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 年',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), '几秒后', 'prefix');
        assert.equal(moment(0).from(30000), '几秒前', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            '几秒前',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            '几秒后',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 天后', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), '今天12:00', 'today at the same time');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            '今天12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            '今天13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            '明天12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            '今天11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            '昨天12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i,
            m,
            week = moment().week();
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            if (week === m.week()) {
                assert.equal(
                    m.calendar(),
                    m.format('[本]dddLT'),
                    'Today + ' + i + ' days current time'
                );
                m.hours(0).minutes(0).seconds(0).milliseconds(0);
                assert.equal(
                    m.calendar(),
                    m.format('[本]dddLT'),
                    'Today + ' + i + ' days beginning of day'
                );
                m.hours(23).minutes(59).seconds(59).milliseconds(999);
                assert.equal(
                    m.calendar(),
                    m.format('[本]dddLT'),
                    'Today + ' + i + ' days end of day'
                );
            } else {
                assert.equal(
                    m.calendar(),
                    m.format('[下]dddLT'),
                    'Today + ' + i + ' days current time'
                );
                m.hours(0).minutes(0).seconds(0).milliseconds(0);
                assert.equal(
                    m.calendar(),
                    m.format('[下]dddLT'),
                    'Today + ' + i + ' days beginning of day'
                );
                m.hours(23).minutes(59).seconds(59).milliseconds(999);
                assert.equal(
                    m.calendar(),
                    m.format('[下]dddLT'),
                    'Today + ' + i + ' days end of day'
                );
            }
        }
    });

    test('calendar last week', function (assert) {
        var i,
            m,
            week = moment().week();
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            if (week !== m.week()) {
                assert.equal(
                    m.calendar(),
                    m.format('[上]dddLT'),
                    'Today - ' + i + ' days current time'
                );
                m.hours(0).minutes(0).seconds(0).milliseconds(0);
                assert.equal(
                    m.calendar(),
                    m.format('[上]dddLT'),
                    'Today - ' + i + ' days beginning of day'
                );
                m.hours(23).minutes(59).seconds(59).milliseconds(999);
                assert.equal(
                    m.calendar(),
                    m.format('[上]dddLT'),
                    'Today - ' + i + ' days end of day'
                );
            } else {
                assert.equal(
                    m.calendar(),
                    m.format('[本]dddLT'),
                    'Today - ' + i + ' days current time'
                );
                m.hours(0).minutes(0).seconds(0).milliseconds(0);
                assert.equal(
                    m.calendar(),
                    m.format('[本]dddLT'),
                    'Today - ' + i + ' days beginning of day'
                );
                m.hours(23).minutes(59).seconds(59).milliseconds(999);
                assert.equal(
                    m.calendar(),
                    m.format('[本]dddLT'),
                    'Today - ' + i + ' days end of day'
                );
            }
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 0, 0]).format('A'),
            '凌晨',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 6, 0]).format('A'), '早上', 'morning');
        assert.equal(
            moment([2011, 2, 23, 9, 0]).format('A'),
            '上午',
            'before noon'
        );
        assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');
        assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');
        assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '52 52 52周',
            'Jan  1 2012 应该是第52周'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1周',
            'Jan  7 2012 应该是第 1周'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2周',
            'Jan 14 2012 应该是第 2周'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('zh-hk');

    test('parse', function (assert) {
        var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, a h:mm:ss',
                    '星期日, 二月 14日 2010, 下午 3:25:50',
                ],
                ['ddd, Ah', '週日, 下午3'],
                ['M Mo MM MMMM MMM', '2 2月 02 二月 2月'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14日 14'],
                ['d do dddd ddd dd', '0 0日 星期日 週日 日'],
                ['DDD DDDo DDDD', '45 45日 045'],
                ['w wo ww', '8 8週 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', '下午 下午'],
                ['[這年的第] DDDo', '這年的第 45日'],
                ['LTS', '15:25:50'],
                ['L', '2010/02/14'],
                ['LL', '2010年2月14日'],
                ['LLL', '2010年2月14日 15:25'],
                ['LLLL', '2010年2月14日星期日 15:25'],
                ['l', '2010/2/14'],
                ['ll', '2010年2月14日'],
                ['lll', '2010年2月14日 15:25'],
                ['llll', '2010年2月14日星期日 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format month', function (assert) {
        var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split(
                '_'
            ),
            i;

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split(
                '_'
            ),
            i;

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            '幾秒',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            '1 分鐘',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            '1 分鐘',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 分鐘',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 分鐘',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            '1 小時',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            '1 小時',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 小時',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 小時',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 小時',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            '1 天',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            '1 天',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 天',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            '1 天',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 天',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 天',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            '1 個月',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            '1 個月',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            '1 個月',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 個月',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 個月',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 個月',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            '1 個月',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 個月',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            '1 年',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 年',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            '1 年',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 年',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), '幾秒後', 'prefix');
        assert.equal(moment(0).from(30000), '幾秒前', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            '幾秒前',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            '幾秒後',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 天後', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), '今天12:00', 'today at the same time');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            '今天12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            '今天13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            '明天12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            '今天11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            '昨天12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[下]ddddLT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[下]ddddLT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[下]ddddLT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[上]ddddLT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[上]ddddLT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[上]ddddLT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 0, 0]).format('a'),
            '凌晨',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 6, 0]).format('a'), '早上', 'morning');
        assert.equal(
            moment([2011, 2, 23, 11, 59]).format('a'),
            '上午',
            'before noon'
        );
        assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), '中午', 'noon');
        assert.equal(
            moment([2011, 2, 23, 12, 1]).format('a'),
            '下午',
            'after noon'
        );
        assert.equal(moment([2011, 2, 23, 18, 0]).format('a'), '晚上', 'night');

        assert.equal(
            moment([2011, 2, 23, 0, 0]).format('A'),
            '凌晨',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 6, 0]).format('A'), '早上', 'morning');
        assert.equal(
            moment([2011, 2, 23, 11, 59]).format('A'),
            '上午',
            'before noon'
        );
        assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');
        assert.equal(moment([2011, 2, 23, 12, 1]).format('A'), '下午', 'afternoon');
        assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1週',
            'Jan  1 2012 應該是第 1週'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1週',
            'Jan  7 2012 應該是第 1週'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2週',
            'Jan  8 2012 應該是第 2週'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2週',
            'Jan 14 2012 應該是第 2週'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3週',
            'Jan 15 2012 應該是第 3週'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('zh-mo');

    test('parse', function (assert) {
        var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }
        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, a h:mm:ss',
                    '星期日, 二月 14日 2010, 下午 3:25:50',
                ],
                ['ddd, Ah', '週日, 下午3'],
                ['M Mo MM MMMM MMM', '2 2月 02 二月 2月'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14日 14'],
                ['d do dddd ddd dd', '0 0日 星期日 週日 日'],
                ['DDD DDDo DDDD', '45 45日 045'],
                ['w wo ww', '8 8週 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', '下午 下午'],
                ['[這年的第] DDDo', '這年的第 45日'],
                ['LTS', '15:25:50'],
                ['L', '14/02/2010'],
                ['LL', '2010年2月14日'],
                ['LLL', '2010年2月14日 15:25'],
                ['LLLL', '2010年2月14日星期日 15:25'],
                ['l', '14/2/2010'],
                ['ll', '2010年2月14日'],
                ['lll', '2010年2月14日 15:25'],
                ['llll', '2010年2月14日星期日 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format month', function (assert) {
        var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split(
                '_'
            ),
            i;

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split(
                '_'
            ),
            i;

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            '幾秒',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            '1 分鐘',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            '1 分鐘',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 分鐘',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 分鐘',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            '1 小時',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            '1 小時',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 小時',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 小時',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 小時',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            '1 天',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            '1 天',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 天',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            '1 天',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 天',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 天',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            '1 個月',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            '1 個月',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            '1 個月',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 個月',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 個月',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 個月',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            '1 個月',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 個月',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            '1 年',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 年',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            '1 年',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 年',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), '幾秒內', 'prefix');
        assert.equal(moment(0).from(30000), '幾秒前', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            '幾秒前',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            '幾秒內',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 天內', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), '今天 12:00', 'today at the same time');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            '今天 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            '今天 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            '明天 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            '今天 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            '昨天 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[下]dddd LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[下]dddd LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[下]dddd LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[上]dddd LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[上]dddd LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[上]dddd LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 0, 0]).format('a'),
            '凌晨',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 6, 0]).format('a'), '早上', 'morning');
        assert.equal(
            moment([2011, 2, 23, 9, 0]).format('a'),
            '上午',
            'before noon'
        );
        assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), '中午', 'noon');
        assert.equal(
            moment([2011, 2, 23, 13, 0]).format('a'),
            '下午',
            'after noon'
        );
        assert.equal(moment([2011, 2, 23, 18, 0]).format('a'), '晚上', 'night');

        assert.equal(
            moment([2011, 2, 23, 0, 0]).format('A'),
            '凌晨',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 6, 0]).format('A'), '早上', 'morning');
        assert.equal(
            moment([2011, 2, 23, 9, 0]).format('A'),
            '上午',
            'before noon'
        );
        assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');
        assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');
        assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1週',
            'Jan  1 2012 應該是第 1週'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1週',
            'Jan  7 2012 應該是第 1週'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2週',
            'Jan  8 2012 應該是第 2週'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2週',
            'Jan 14 2012 應該是第 2週'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3週',
            'Jan 15 2012 應該是第 3週'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    function defineCommonLocaleTests(locale, options) {
        test('lenient day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing ' + i + ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing ' + i + ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing ' + i + ' date check'
                );
            }
        });

        test('lenient day of month ordinal parsing of number', function (assert) {
            var i, testMoment;
            for (i = 1; i <= 31; ++i) {
                testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
                assert.equal(
                    testMoment.year(),
                    2014,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' year check'
                );
                assert.equal(
                    testMoment.month(),
                    0,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' month check'
                );
                assert.equal(
                    testMoment.date(),
                    i,
                    'lenient day of month ordinal parsing of number ' +
                        i +
                        ' date check'
                );
            }
        });

        test('strict day of month ordinal parsing', function (assert) {
            var i, ordinalStr, testMoment;
            for (i = 1; i <= 31; ++i) {
                ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
                testMoment = moment(ordinalStr, 'YYYY MM Do', true);
                assert.ok(
                    testMoment.isValid(),
                    'strict day of month ordinal parsing ' + i
                );
            }
        });

        test('meridiem invariant', function (assert) {
            var h, m, t1, t2;
            for (h = 0; h < 24; ++h) {
                for (m = 0; m < 60; m += 15) {
                    t1 = moment.utc([2000, 0, 1, h, m]);
                    t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');
                    assert.equal(
                        t2.format('HH:mm'),
                        t1.format('HH:mm'),
                        'meridiem at ' + t1.format('HH:mm')
                    );
                }
            }
        });

        test('date format correctness', function (assert) {
            var data = moment.localeData()._longDateFormat;
            eachOwnProp(data, function (srchToken) {
                // Check each format string to make sure it does not contain any
                // tokens that need to be expanded.
                eachOwnProp(data, function (baseToken) {
                    // strip escaped sequences
                    var format = data[baseToken].replace(/(\[[^\]]*\])/g, '');
                    assert.equal(
                        false,
                        !!~format.indexOf(srchToken),
                        'contains ' + srchToken + ' in ' + baseToken
                    );
                });
            });
        });

        test('month parsing correctness', function (assert) {
            var i, m;

            if (locale === 'tr') {
                // I can't fix it :(
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r;
                r = moment(m.format(format), format);
                assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower'
                );

                r = moment(m.format(format), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' strict'
                );
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.month(),
                        m.month(),
                        'month ' + i + ' fmt ' + format + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(
                    r.month(),
                    m.month(),
                    'month ' + i + ' fmt ' + format + ' lower strict'
                );
            }

            for (i = 0; i < 12; ++i) {
                m = moment([2015, i, 15, 18]);
                tester('MMM');
                tester('MMM.');
                tester('MMMM');
                tester('MMMM.');
            }
        });

        test('weekday parsing correctness', function (assert) {
            var i, m;

            if (
                locale === 'tr' ||
                locale === 'az' ||
                locale === 'ro' ||
                locale === 'mt' ||
                locale === 'ga'
            ) {
                // tr, az: There is a lower-case letter (ı), that converted to
                // upper then lower changes to i
                // ro: there is the letter ț which behaves weird under IE8
                // mt: letter Ħ
                // ga: month with spaces
                assert.expect(0);
                return;
            }
            function tester(format) {
                var r,
                    baseMsg =
                        'weekday ' +
                        m.weekday() +
                        ' fmt ' +
                        format +
                        ' ' +
                        m.toISOString();
                r = moment(m.format(format), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg);
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format);
                    assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');
                }
                r = moment(m.format(format).toLocaleLowerCase(), format);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');
                r = moment(m.format(format), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');
                if (locale !== 'ka') {
                    r = moment(m.format(format).toLocaleUpperCase(), format, true);
                    assert.equal(
                        r.weekday(),
                        m.weekday(),
                        baseMsg + ' upper strict'
                    );
                }
                r = moment(m.format(format).toLocaleLowerCase(), format, true);
                assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');
            }

            for (i = 0; i < 7; ++i) {
                m = moment.utc([2015, 0, i + 1, 18]);
                tester('dd');
                tester('ddd');
                tester('dddd');
            }
        });

        test('valid localeData', function (assert) {
            assert.equal(
                moment().localeData().months().length,
                12,
                'months should return 12 months'
            );
            assert.equal(
                moment().localeData().monthsShort().length,
                12,
                'monthsShort should return 12 months'
            );
            assert.equal(
                moment().localeData().weekdays().length,
                7,
                'weekdays should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysShort().length,
                7,
                'weekdaysShort should return 7 days'
            );
            assert.equal(
                moment().localeData().weekdaysMin().length,
                7,
                'monthsShort should return 7 days'
            );
        });

        test('localeData weekdays can localeSort', function (assert) {
            var weekdays = moment().localeData().weekdays(),
                weekdaysShort = moment().localeData().weekdaysShort(),
                weekdaysMin = moment().localeData().weekdaysMin(),
                shift = moment().localeData()._week.dow;
            assert.deepEqual(
                moment().localeData().weekdays(true),
                weekdays.slice(shift, 7).concat(weekdays.slice(0, shift)),
                'weekdays should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysShort(true),
                weekdaysShort.slice(shift, 7).concat(weekdaysShort.slice(0, shift)),
                'weekdaysShort should localeSort'
            );
            assert.deepEqual(
                moment().localeData().weekdaysMin(true),
                weekdaysMin.slice(shift, 7).concat(weekdaysMin.slice(0, shift)),
                'weekdaysMin should localeSort'
            );
        });
    }

    /*global QUnit:false*/

    function localeModule(name, lifecycle) {
        QUnit.module('locale:' + name, {
            beforeEach: function () {
                moment.locale(name);
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                moment.locale('en');
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
        defineCommonLocaleTests(name);
    }

    localeModule('zh-tw');

    test('parse', function (assert) {
        var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split(
                '_'
            ),
            i;
        function equalTest(input, mmm, i) {
            assert.equal(
                moment(input, mmm).month(),
                i,
                input + ' should be month ' + (i + 1)
            );
        }

        function equalTestStrict(input, mmm, monthIndex) {
            assert.equal(
                moment(input, mmm, true).month(),
                monthIndex,
                input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1)
            );
        }

        for (i = 0; i < 12; i++) {
            tests[i] = tests[i].split(' ');
            equalTest(tests[i][0], 'MMM', i);
            equalTest(tests[i][1], 'MMM', i);
            equalTest(tests[i][0], 'MMMM', i);
            equalTest(tests[i][1], 'MMMM', i);
            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);

            equalTestStrict(tests[i][1], 'MMM', i);
            equalTestStrict(tests[i][0], 'MMMM', i);
            equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);
            equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);
            equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
            equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
        }
    });

    test('format', function (assert) {
        var a = [
                [
                    'dddd, MMMM Do YYYY, a h:mm:ss',
                    '星期日, 二月 14日 2010, 下午 3:25:50',
                ],
                ['ddd, Ah', '週日, 下午3'],
                ['M Mo MM MMMM MMM', '2 2月 02 二月 2月'],
                ['YYYY YY', '2010 10'],
                ['D Do DD', '14 14日 14'],
                ['d do dddd ddd dd', '0 0日 星期日 週日 日'],
                ['DDD DDDo DDDD', '45 45日 045'],
                ['w wo ww', '8 8週 08'],
                ['h hh', '3 03'],
                ['H HH', '15 15'],
                ['m mm', '25 25'],
                ['s ss', '50 50'],
                ['a A', '下午 下午'],
                ['[這年的第] DDDo', '這年的第 45日'],
                ['LTS', '15:25:50'],
                ['L', '2010/02/14'],
                ['LL', '2010年2月14日'],
                ['LLL', '2010年2月14日 15:25'],
                ['LLLL', '2010年2月14日星期日 15:25'],
                ['l', '2010/2/14'],
                ['ll', '2010年2月14日'],
                ['lll', '2010年2月14日 15:25'],
                ['llll', '2010年2月14日星期日 15:25'],
            ],
            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('format month', function (assert) {
        var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split(
                '_'
            ),
            i;

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, i, 1]).format('MMMM MMM'),
                expected[i],
                expected[i]
            );
        }
    });

    test('format week', function (assert) {
        var expected = '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split(
                '_'
            ),
            i;

        for (i = 0; i < expected.length; i++) {
            assert.equal(
                moment([2011, 0, 2 + i]).format('dddd ddd dd'),
                expected[i],
                expected[i]
            );
        }
    });

    test('from', function (assert) {
        var start = moment([2007, 1, 28]);
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 }), true),
            '幾秒',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 }), true),
            '1 分鐘',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 }), true),
            '1 分鐘',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '2 分鐘',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 }), true),
            '44 分鐘',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 }), true),
            '1 小時',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 }), true),
            '1 小時',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 }), true),
            '2 小時',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 }), true),
            '5 小時',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 }), true),
            '21 小時',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 }), true),
            '1 天',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 }), true),
            '1 天',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 }), true),
            '2 天',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 }), true),
            '1 天',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 }), true),
            '5 天',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 }), true),
            '25 天',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 }), true),
            '1 個月',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 }), true),
            '1 個月',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 }), true),
            '1 個月',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 }), true),
            '2 個月',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 }), true),
            '2 個月',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 }), true),
            '3 個月',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 }), true),
            '1 個月',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 }), true),
            '5 個月',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 }), true),
            '1 年',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 }), true),
            '2 年',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 }), true),
            '1 年',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 }), true),
            '5 年',
            '5 years = 5 years'
        );
    });

    test('suffix', function (assert) {
        assert.equal(moment(30000).from(0), '幾秒後', 'prefix');
        assert.equal(moment(0).from(30000), '幾秒前', 'suffix');
    });

    test('now from now', function (assert) {
        assert.equal(
            moment().fromNow(),
            '幾秒前',
            'now from now should display as in the past'
        );
    });

    test('fromNow', function (assert) {
        assert.equal(
            moment().add({ s: 30 }).fromNow(),
            '幾秒後',
            'in a few seconds'
        );
        assert.equal(moment().add({ d: 5 }).fromNow(), '5 天後', 'in 5 days');
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(moment(a).calendar(), '今天 12:00', 'today at the same time');
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            '今天 12:25',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            '今天 13:00',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            '明天 12:00',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            '今天 11:00',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            '昨天 12:00',
            'yesterday at the same time'
        );
    });

    test('calendar next week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().add({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[下]dddd LT'),
                'Today + ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[下]dddd LT'),
                'Today + ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[下]dddd LT'),
                'Today + ' + i + ' days end of day'
            );
        }
    });

    test('calendar last week', function (assert) {
        var i, m;
        for (i = 2; i < 7; i++) {
            m = moment().subtract({ d: i });
            assert.equal(
                m.calendar(),
                m.format('[上]dddd LT'),
                'Today - ' + i + ' days current time'
            );
            m.hours(0).minutes(0).seconds(0).milliseconds(0);
            assert.equal(
                m.calendar(),
                m.format('[上]dddd LT'),
                'Today - ' + i + ' days beginning of day'
            );
            m.hours(23).minutes(59).seconds(59).milliseconds(999);
            assert.equal(
                m.calendar(),
                m.format('[上]dddd LT'),
                'Today - ' + i + ' days end of day'
            );
        }
    });

    test('calendar all else', function (assert) {
        var weeksAgo = moment().subtract({ w: 1 }),
            weeksFromNow = moment().add({ w: 1 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 1 week'
        );

        weeksAgo = moment().subtract({ w: 2 });
        weeksFromNow = moment().add({ w: 2 });

        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
        assert.equal(
            weeksFromNow.calendar(),
            weeksFromNow.format('L'),
            'in 2 weeks'
        );
    });

    test('meridiem', function (assert) {
        assert.equal(
            moment([2011, 2, 23, 0, 0]).format('a'),
            '凌晨',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 6, 0]).format('a'), '早上', 'morning');
        assert.equal(
            moment([2011, 2, 23, 9, 0]).format('a'),
            '上午',
            'before noon'
        );
        assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), '中午', 'noon');
        assert.equal(
            moment([2011, 2, 23, 13, 0]).format('a'),
            '下午',
            'after noon'
        );
        assert.equal(moment([2011, 2, 23, 18, 0]).format('a'), '晚上', 'night');

        assert.equal(
            moment([2011, 2, 23, 0, 0]).format('A'),
            '凌晨',
            'before dawn'
        );
        assert.equal(moment([2011, 2, 23, 6, 0]).format('A'), '早上', 'morning');
        assert.equal(
            moment([2011, 2, 23, 9, 0]).format('A'),
            '上午',
            'before noon'
        );
        assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');
        assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');
        assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');
    });

    test('weeks year starting sunday format', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('w ww wo'),
            '1 01 1週',
            'Jan  1 2012 應該是第 1週'
        );
        assert.equal(
            moment([2012, 0, 7]).format('w ww wo'),
            '1 01 1週',
            'Jan  7 2012 應該是第 1週'
        );
        assert.equal(
            moment([2012, 0, 8]).format('w ww wo'),
            '2 02 2週',
            'Jan  8 2012 應該是第 2週'
        );
        assert.equal(
            moment([2012, 0, 14]).format('w ww wo'),
            '2 02 2週',
            'Jan 14 2012 應該是第 2週'
        );
        assert.equal(
            moment([2012, 0, 15]).format('w ww wo'),
            '3 03 3週',
            'Jan 15 2012 應該是第 3週'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('add and subtract');

    test('add short reverse args', function (assert) {
        var a = moment(),
            b,
            c,
            d;
        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        assert.equal(a.add({ ms: 50 }).milliseconds(), 550, 'Add milliseconds');
        assert.equal(a.add({ s: 1 }).seconds(), 9, 'Add seconds');
        assert.equal(a.add({ m: 1 }).minutes(), 8, 'Add minutes');
        assert.equal(a.add({ h: 1 }).hours(), 7, 'Add hours');
        assert.equal(a.add({ d: 1 }).date(), 13, 'Add date');
        assert.equal(a.add({ w: 1 }).date(), 20, 'Add week');
        assert.equal(a.add({ M: 1 }).month(), 10, 'Add month');
        assert.equal(a.add({ y: 1 }).year(), 2012, 'Add year');
        assert.equal(a.add({ Q: 1 }).month(), 1, 'Add quarter');

        b = moment([2010, 0, 31]).add({ M: 1 });
        c = moment([2010, 1, 28]).subtract({ M: 1 });
        d = moment([2010, 1, 28]).subtract({ Q: 1 });

        assert.equal(b.month(), 1, 'add month, jan 31st to feb 28th');
        assert.equal(b.date(), 28, 'add month, jan 31st to feb 28th');
        assert.equal(c.month(), 0, 'subtract month, feb 28th to jan 28th');
        assert.equal(c.date(), 28, 'subtract month, feb 28th to jan 28th');
        assert.equal(
            d.month(),
            10,
            'subtract quarter, feb 28th 2010 to nov 28th 2009'
        );
        assert.equal(
            d.date(),
            28,
            'subtract quarter, feb 28th 2010 to nov 28th 2009'
        );
        assert.equal(
            d.year(),
            2009,
            'subtract quarter, feb 28th 2010 to nov 28th 2009'
        );
    });

    test('add long reverse args', function (assert) {
        var a = moment();
        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        assert.equal(
            a.add({ milliseconds: 50 }).milliseconds(),
            550,
            'Add milliseconds'
        );
        assert.equal(a.add({ seconds: 1 }).seconds(), 9, 'Add seconds');
        assert.equal(a.add({ minutes: 1 }).minutes(), 8, 'Add minutes');
        assert.equal(a.add({ hours: 1 }).hours(), 7, 'Add hours');
        assert.equal(a.add({ days: 1 }).date(), 13, 'Add date');
        assert.equal(a.add({ weeks: 1 }).date(), 20, 'Add week');
        assert.equal(a.add({ months: 1 }).month(), 10, 'Add month');
        assert.equal(a.add({ years: 1 }).year(), 2012, 'Add year');
        assert.equal(a.add({ quarters: 1 }).month(), 1, 'Add quarter');
    });

    test('add long singular reverse args', function (assert) {
        var a = moment();
        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        assert.equal(
            a.add({ millisecond: 50 }).milliseconds(),
            550,
            'Add milliseconds'
        );
        assert.equal(a.add({ second: 1 }).seconds(), 9, 'Add seconds');
        assert.equal(a.add({ minute: 1 }).minutes(), 8, 'Add minutes');
        assert.equal(a.add({ hour: 1 }).hours(), 7, 'Add hours');
        assert.equal(a.add({ day: 1 }).date(), 13, 'Add date');
        assert.equal(a.add({ week: 1 }).date(), 20, 'Add week');
        assert.equal(a.add({ month: 1 }).month(), 10, 'Add month');
        assert.equal(a.add({ year: 1 }).year(), 2012, 'Add year');
        assert.equal(a.add({ quarter: 1 }).month(), 1, 'Add quarter');
    });

    test('add string long reverse args', function (assert) {
        var a = moment(),
            b;

        test.expectedDeprecations('moment().add(period, number)');

        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        b = a.clone();

        assert.equal(
            a.add('millisecond', 50).milliseconds(),
            550,
            'Add milliseconds'
        );
        assert.equal(a.add('second', 1).seconds(), 9, 'Add seconds');
        assert.equal(a.add('minute', 1).minutes(), 8, 'Add minutes');
        assert.equal(a.add('hour', 1).hours(), 7, 'Add hours');
        assert.equal(a.add('day', 1).date(), 13, 'Add date');
        assert.equal(a.add('week', 1).date(), 20, 'Add week');
        assert.equal(a.add('month', 1).month(), 10, 'Add month');
        assert.equal(a.add('year', 1).year(), 2012, 'Add year');
        assert.equal(b.add('day', '01').date(), 13, 'Add date');
        assert.equal(a.add('quarter', 1).month(), 1, 'Add quarter');
    });

    test('add string long singular reverse args', function (assert) {
        var a = moment(),
            b;

        test.expectedDeprecations('moment().add(period, number)');

        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        b = a.clone();

        assert.equal(
            a.add('milliseconds', 50).milliseconds(),
            550,
            'Add milliseconds'
        );
        assert.equal(a.add('seconds', 1).seconds(), 9, 'Add seconds');
        assert.equal(a.add('minutes', 1).minutes(), 8, 'Add minutes');
        assert.equal(a.add('hours', 1).hours(), 7, 'Add hours');
        assert.equal(a.add('days', 1).date(), 13, 'Add date');
        assert.equal(a.add('weeks', 1).date(), 20, 'Add week');
        assert.equal(a.add('months', 1).month(), 10, 'Add month');
        assert.equal(a.add('years', 1).year(), 2012, 'Add year');
        assert.equal(b.add('days', '01').date(), 13, 'Add date');
        assert.equal(a.add('quarters', 1).month(), 1, 'Add quarter');
    });

    test('add string short reverse args', function (assert) {
        var a = moment();
        test.expectedDeprecations('moment().add(period, number)');

        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        assert.equal(a.add('ms', 50).milliseconds(), 550, 'Add milliseconds');
        assert.equal(a.add('s', 1).seconds(), 9, 'Add seconds');
        assert.equal(a.add('m', 1).minutes(), 8, 'Add minutes');
        assert.equal(a.add('h', 1).hours(), 7, 'Add hours');
        assert.equal(a.add('d', 1).date(), 13, 'Add date');
        assert.equal(a.add('w', 1).date(), 20, 'Add week');
        assert.equal(a.add('M', 1).month(), 10, 'Add month');
        assert.equal(a.add('y', 1).year(), 2012, 'Add year');
        assert.equal(a.add('Q', 1).month(), 1, 'Add quarter');
    });

    test('add string long', function (assert) {
        var a = moment();
        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        assert.equal(
            a.add(50, 'millisecond').milliseconds(),
            550,
            'Add milliseconds'
        );
        assert.equal(a.add(1, 'second').seconds(), 9, 'Add seconds');
        assert.equal(a.add(1, 'minute').minutes(), 8, 'Add minutes');
        assert.equal(a.add(1, 'hour').hours(), 7, 'Add hours');
        assert.equal(a.add(1, 'day').date(), 13, 'Add date');
        assert.equal(a.add(1, 'week').date(), 20, 'Add week');
        assert.equal(a.add(1, 'month').month(), 10, 'Add month');
        assert.equal(a.add(1, 'year').year(), 2012, 'Add year');
        assert.equal(a.add(1, 'quarter').month(), 1, 'Add quarter');
    });

    test('add string long singular', function (assert) {
        var a = moment();
        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        assert.equal(
            a.add(50, 'milliseconds').milliseconds(),
            550,
            'Add milliseconds'
        );
        assert.equal(a.add(1, 'seconds').seconds(), 9, 'Add seconds');
        assert.equal(a.add(1, 'minutes').minutes(), 8, 'Add minutes');
        assert.equal(a.add(1, 'hours').hours(), 7, 'Add hours');
        assert.equal(a.add(1, 'days').date(), 13, 'Add date');
        assert.equal(a.add(1, 'weeks').date(), 20, 'Add week');
        assert.equal(a.add(1, 'months').month(), 10, 'Add month');
        assert.equal(a.add(1, 'years').year(), 2012, 'Add year');
        assert.equal(a.add(1, 'quarters').month(), 1, 'Add quarter');
    });

    test('add string short', function (assert) {
        var a = moment();
        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        assert.equal(a.add(50, 'ms').milliseconds(), 550, 'Add milliseconds');
        assert.equal(a.add(1, 's').seconds(), 9, 'Add seconds');
        assert.equal(a.add(1, 'm').minutes(), 8, 'Add minutes');
        assert.equal(a.add(1, 'h').hours(), 7, 'Add hours');
        assert.equal(a.add(1, 'd').date(), 13, 'Add date');
        assert.equal(a.add(1, 'w').date(), 20, 'Add week');
        assert.equal(a.add(1, 'M').month(), 10, 'Add month');
        assert.equal(a.add(1, 'y').year(), 2012, 'Add year');
        assert.equal(a.add(1, 'Q').month(), 1, 'Add quarter');
    });

    test('add strings string short reversed', function (assert) {
        var a = moment();
        test.expectedDeprecations('moment().add(period, number)');

        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        assert.equal(a.add('ms', '50').milliseconds(), 550, 'Add milliseconds');
        assert.equal(a.add('s', '1').seconds(), 9, 'Add seconds');
        assert.equal(a.add('m', '1').minutes(), 8, 'Add minutes');
        assert.equal(a.add('h', '1').hours(), 7, 'Add hours');
        assert.equal(a.add('d', '1').date(), 13, 'Add date');
        assert.equal(a.add('w', '1').date(), 20, 'Add week');
        assert.equal(a.add('M', '1').month(), 10, 'Add month');
        assert.equal(a.add('y', '1').year(), 2012, 'Add year');
        assert.equal(a.add('Q', '1').month(), 1, 'Add quarter');
    });

    test('subtract strings string short reversed', function (assert) {
        var a = moment();
        test.expectedDeprecations('moment().subtract(period, number)');

        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        assert.equal(
            a.subtract('ms', '50').milliseconds(),
            450,
            'Subtract milliseconds'
        );
        assert.equal(a.subtract('s', '1').seconds(), 7, 'Subtract seconds');
        assert.equal(a.subtract('m', '1').minutes(), 6, 'Subtract minutes');
        assert.equal(a.subtract('h', '1').hours(), 5, 'Subtract hours');
        assert.equal(a.subtract('d', '1').date(), 11, 'Subtract date');
        assert.equal(a.subtract('w', '1').date(), 4, 'Subtract week');
        assert.equal(a.subtract('M', '1').month(), 8, 'Subtract month');
        assert.equal(a.subtract('y', '1').year(), 2010, 'Subtract year');
        assert.equal(a.subtract('Q', '1').month(), 5, 'Subtract quarter');
    });

    test('add strings string short', function (assert) {
        var a = moment();
        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        assert.equal(a.add('50', 'ms').milliseconds(), 550, 'Add milliseconds');
        assert.equal(a.add('1', 's').seconds(), 9, 'Add seconds');
        assert.equal(a.add('1', 'm').minutes(), 8, 'Add minutes');
        assert.equal(a.add('1', 'h').hours(), 7, 'Add hours');
        assert.equal(a.add('1', 'd').date(), 13, 'Add date');
        assert.equal(a.add('1', 'w').date(), 20, 'Add week');
        assert.equal(a.add('1', 'M').month(), 10, 'Add month');
        assert.equal(a.add('1', 'y').year(), 2012, 'Add year');
        assert.equal(a.add('1', 'Q').month(), 1, 'Add quarter');
    });

    test('add no string with milliseconds default', function (assert) {
        var a = moment();
        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        assert.equal(a.add(50).milliseconds(), 550, 'Add milliseconds');
    });

    test('subtract strings string short', function (assert) {
        var a = moment();
        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(500);

        assert.equal(
            a.subtract('50', 'ms').milliseconds(),
            450,
            'Subtract milliseconds'
        );
        assert.equal(a.subtract('1', 's').seconds(), 7, 'Subtract seconds');
        assert.equal(a.subtract('1', 'm').minutes(), 6, 'Subtract minutes');
        assert.equal(a.subtract('1', 'h').hours(), 5, 'Subtract hours');
        assert.equal(a.subtract('1', 'd').date(), 11, 'Subtract date');
        assert.equal(a.subtract('1', 'w').date(), 4, 'Subtract week');
        assert.equal(a.subtract('1', 'M').month(), 8, 'Subtract month');
        assert.equal(a.subtract('1', 'y').year(), 2010, 'Subtract year');
        assert.equal(a.subtract('1', 'Q').month(), 5, 'Subtract quarter');
    });

    test('add across DST', function (assert) {
        // Detect Safari bug and bail. Hours on 13th March 2011 are shifted
        // with 1 ahead.
        if (new Date(2011, 2, 13, 5, 0, 0).getHours() !== 5) {
            assert.expect(0);
            return;
        }

        var a = moment(new Date(2011, 2, 12, 5, 0, 0)),
            b = moment(new Date(2011, 2, 12, 5, 0, 0)),
            c = moment(new Date(2011, 2, 12, 5, 0, 0)),
            d = moment(new Date(2011, 2, 12, 5, 0, 0)),
            e = moment(new Date(2011, 2, 12, 5, 0, 0));
        a.add(1, 'days');
        b.add(24, 'hours');
        c.add(1, 'months');
        e.add(1, 'quarter');

        assert.equal(
            a.hours(),
            5,
            'adding days over DST difference should result in the same hour'
        );
        if (b.isDST() && !d.isDST()) {
            assert.equal(
                b.hours(),
                6,
                'adding hours over DST difference should result in a different hour'
            );
        } else if (!b.isDST() && d.isDST()) {
            assert.equal(
                b.hours(),
                4,
                'adding hours over DST difference should result in a different hour'
            );
        } else {
            assert.equal(
                b.hours(),
                5,
                'adding hours over DST difference should result in a same hour if the timezone does not have daylight savings time'
            );
        }
        assert.equal(
            c.hours(),
            5,
            'adding months over DST difference should result in the same hour'
        );
        assert.equal(
            e.hours(),
            5,
            'adding quarters over DST difference should result in the same hour'
        );
    });

    test('add decimal values of days and months', function (assert) {
        assert.equal(
            moment([2016, 3, 3]).add(1.5, 'days').date(),
            5,
            'adding 1.5 days is rounded to adding 2 day'
        );
        assert.equal(
            moment([2016, 3, 3]).add(-1.5, 'days').date(),
            1,
            'adding -1.5 days is rounded to adding -2 day'
        );
        assert.equal(
            moment([2016, 3, 1]).add(-1.5, 'days').date(),
            30,
            'adding -1.5 days on first of month wraps around'
        );
        assert.equal(
            moment([2016, 3, 3]).add(1.5, 'months').month(),
            5,
            'adding 1.5 months adds 2 months'
        );
        assert.equal(
            moment([2016, 3, 3]).add(-1.5, 'months').month(),
            1,
            'adding -1.5 months adds -2 months'
        );
        assert.equal(
            moment([2016, 0, 3]).add(-1.5, 'months').month(),
            10,
            'adding -1.5 months at start of year wraps back'
        );
        assert.equal(
            moment([2016, 3, 3]).subtract(1.5, 'days').date(),
            1,
            'subtract 1.5 days is rounded to subtract 2 day'
        );
        assert.equal(
            moment([2016, 3, 2]).subtract(1.5, 'days').date(),
            31,
            'subtract 1.5 days subtracts 2 days'
        );
        assert.equal(
            moment([2016, 1, 1]).subtract(1.1, 'days').date(),
            31,
            'subtract 1.1 days wraps to previous month'
        );
        assert.equal(
            moment([2016, 3, 3]).subtract(-1.5, 'days').date(),
            5,
            'subtract -1.5 days is rounded to subtract -2 day'
        );
        assert.equal(
            moment([2016, 3, 30]).subtract(-1.5, 'days').date(),
            2,
            'subtract -1.5 days on last of month wraps around'
        );
        assert.equal(
            moment([2016, 3, 3]).subtract(1.5, 'months').month(),
            1,
            'subtract 1.5 months subtract 2 months'
        );
        assert.equal(
            moment([2016, 3, 3]).subtract(-1.5, 'months').month(),
            5,
            'subtract -1.5 months subtract -2 month'
        );
        assert.equal(
            moment([2016, 11, 31]).subtract(-1.5, 'months').month(),
            1,
            'subtract -1.5 months at end of year wraps back'
        );
        assert.equal(
            moment([2016, 0, 1]).add(1.5, 'years').format('YYYY-MM-DD'),
            '2017-07-01',
            'add 1.5 years adds 1 year six months'
        );
        assert.equal(
            moment([2016, 0, 1]).add(1.6, 'years').format('YYYY-MM-DD'),
            '2017-08-01',
            'add 1.6 years becomes 1.6*12 = 19.2, round, 19 months'
        );
        assert.equal(
            moment([2016, 0, 1]).add(1.1, 'quarters').format('YYYY-MM-DD'),
            '2016-04-01',
            'add 1.1 quarters 1.1*3=3.3, round, 3 months'
        );
    });

    test('add/subtract ISO week', function (assert) {
        assert.equal(
            moment([2016, 3, 15]).subtract(1, 'W').date(),
            8,
            'subtract 1 iso week short'
        );
        assert.equal(
            moment([2016, 3, 15]).subtract(1, 'isoweek').date(),
            8,
            'subtract 1 iso week long singular'
        );
        assert.equal(
            moment([2016, 3, 15]).subtract(1, 'isoweeks').date(),
            8,
            'subtract 1 iso weeks long'
        );

        assert.equal(
            moment([2016, 3, 15]).add(1, 'W').date(),
            22,
            'add 1 iso week short'
        );
        assert.equal(
            moment([2016, 3, 15]).add(1, 'isoweek').date(),
            22,
            'add 1 week long singular'
        );
        assert.equal(
            moment([2016, 3, 15]).add(1, 'isoweeks').date(),
            22,
            'add 1 weeks long'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    // These tests are for locale independent features

    module('calendar');

    test('passing a function', function (assert) {
        var a = moment().hours(13).minutes(0).seconds(0);
        assert.equal(
            moment(a).calendar(null, {
                sameDay: function () {
                    return 'h:mmA';
                },
            }),
            '1:00PM',
            'should equate'
        );
    });

    test('extending calendar options', function (assert) {
        var calendarFormat = moment.calendarFormat,
            a,
            b;

        moment.calendarFormat = function (myMoment, now) {
            var diff = myMoment.diff(now, 'days', true),
                nextMonth = now.clone().add(1, 'month'),
                retVal =
                    diff < -6
                        ? 'sameElse'
                        : diff < -1
                        ? 'lastWeek'
                        : diff < 0
                        ? 'lastDay'
                        : diff < 1
                        ? 'sameDay'
                        : diff < 2
                        ? 'nextDay'
                        : diff < 7
                        ? 'nextWeek'
                        : myMoment.month() === now.month() &&
                          myMoment.year() === now.year()
                        ? 'thisMonth'
                        : nextMonth.month() === myMoment.month() &&
                          nextMonth.year() === myMoment.year()
                        ? 'nextMonth'
                        : 'sameElse';
            return retVal;
        };

        moment.updateLocale('en', {
            calendar: {
                sameDay: '[Today at] LT',
                nextDay: '[Tomorrow at] LT',
                nextWeek: 'dddd [at] LT',
                lastDay: '[Yesterday at] LT',
                lastWeek: '[Last] dddd [at] LT',
                thisMonth: '[This month on the] Do',
                nextMonth: '[Next month on the] Do',
                sameElse: 'L',
            },
        });

        a = moment('2016-01-01').add(28, 'days');
        b = moment('2016-01-01').add(1, 'month');

        try {
            assert.equal(
                a.calendar('2016-01-01'),
                'This month on the 29th',
                'Ad hoc calendar format for this month'
            );
            assert.equal(
                b.calendar('2016-01-01'),
                'Next month on the 1st',
                'Ad hoc calendar format for next month'
            );
            assert.equal(
                a.locale('fr').calendar('2016-01-01'),
                a.locale('fr').format('L'),
                'French falls back to default because thisMonth is not defined in that locale'
            );
        } finally {
            moment.calendarFormat = calendarFormat;
            moment.updateLocale('en', null);
        }
    });

    test('calendar overload time - passing one parameter - a Moment', function (assert) {
        var a = moment().hours(13).minutes(23).seconds(45),
            b = moment().add(1, 'd');
        assert.equal(a.calendar(b), 'Yesterday at 1:23 PM', 'should equate');
    });

    test('calendar overload time - passing one parameter - a Date', function (assert) {
        var a = moment().hours(13).minutes(23).seconds(45).subtract(1, 'd'),
            d = new Date();
        assert.equal(a.calendar(d), 'Yesterday at 1:23 PM', 'should equate');
    });

    test('calendar overload time - passing one parameter - a string', function (assert) {
        var a = moment([2808, 11, 1]);
        assert.equal(a.calendar('1999-12-31'), '12/01/2808', 'should equate');
    });

    test('calendar overload time - passing one parameter - a number', function (assert) {
        var a = moment([2808, 11, 1]);
        assert.equal(a.calendar(Date.now()), '12/01/2808', 'should equate');
    });

    test('calendar overload time - passing one parameter - an array of numbers', function (assert) {
        var a = moment()
            .year(2808)
            .month(11)
            .date(1)
            .hours(13)
            .minutes(23)
            .seconds(45);
        assert.equal(
            a.calendar([2808, 11, 1, 13, 23, 45]),
            'Today at 1:23 PM',
            'should equate'
        );
    });

    test('calendar overload time - passing one parameter - an array of strings', function (assert) {
        var a = moment()
            .year(2808)
            .month(11)
            .date(1)
            .hours(13)
            .minutes(23)
            .seconds(45);
        assert.equal(
            a.calendar(['2808', '11', '1', '13', '23', '45']),
            'Today at 1:23 PM',
            'should equate'
        );
    });

    test('calendar overload time - passing one parameter - a moment input object', function (assert) {
        var a = moment(),
            todayTime = new Date(),
            month = todayTime.getMonth() + 1,
            day = todayTime.getDate(),
            year = todayTime.getFullYear(),
            expectedString;

        month = month < 10 ? '0' + month.toString() : month;
        day = day < 10 ? '0' + day.toString() : day;

        expectedString = month + '/' + day + '/' + year;

        assert.equal(
            a.calendar({
                month: 12,
                day: 1,
                year: 2808,
            }),
            expectedString,
            'should equate'
        );
    });

    test('calendar overload format - passing one parameter - object w/ sameDay as a string', function (assert) {
        var a = moment().hours(13).minutes(23).seconds(45);
        assert.equal(
            a.calendar({ sameDay: 'h:mm:ssA' }),
            '1:23:45PM',
            'should equate'
        );
    });

    test('calendar overload format - passing one parameter - object w/ sameDay as function returning a string', function (assert) {
        var a = moment().hours(13).minutes(23).seconds(45);
        assert.equal(
            a.calendar({
                sameDay: function () {
                    return 'h:mm:ssA';
                },
            }),
            '1:23:45PM',
            'should equate'
        );
    });

    test('defaulting to current date', function (assert) {
        var a = moment().hours(13).minutes(23).seconds(45);
        assert.equal(moment(a).calendar(), 'Today at 1:23 PM', 'should equate');
    });

    test('calendar overload time - passing one parameter - a falsy value', function (assert) {
        var a = moment().hours(13).minutes(23).seconds(45),
            tests = [
                '',
                0,
                -0,
                // 0n,
                false,
                NaN,
                null,
                undefined,
            ],
            i;

        for (i = 0; i < tests.length; ++i) {
            assert.equal(
                moment(a).calendar(tests[i]),
                'Today at 1:23 PM',
                'should equate'
            );
        }
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    module('create');

    test('array', function (assert) {
        assert.ok(moment([2010]).toDate() instanceof Date, '[2010]');
        assert.ok(moment([2010, 1]).toDate() instanceof Date, '[2010, 1]');
        assert.ok(moment([2010, 1, 12]).toDate() instanceof Date, '[2010, 1, 12]');
        assert.ok(
            moment([2010, 1, 12, 1]).toDate() instanceof Date,
            '[2010, 1, 12, 1]'
        );
        assert.ok(
            moment([2010, 1, 12, 1, 1]).toDate() instanceof Date,
            '[2010, 1, 12, 1, 1]'
        );
        assert.ok(
            moment([2010, 1, 12, 1, 1, 1]).toDate() instanceof Date,
            '[2010, 1, 12, 1, 1, 1]'
        );
        assert.ok(
            moment([2010, 1, 12, 1, 1, 1, 1]).toDate() instanceof Date,
            '[2010, 1, 12, 1, 1, 1, 1]'
        );
        assert.equal(
            +moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
            +moment([2010, 1, 14, 15, 25, 50, 125]),
            'constructing with array === constructing with new Date()'
        );
    });

    test('array with invalid arguments', function (assert) {
        assert.ok(!moment([2010, null, null]).isValid(), '[2010, null, null]');
        assert.ok(
            !moment([1945, null, null]).isValid(),
            '[1945, null, null] (pre-1970)'
        );
    });

    test('array copying', function (assert) {
        var importantArray = [2009, 11];
        moment(importantArray);
        assert.deepEqual(
            importantArray,
            [2009, 11],
            'initializer should not mutate the original array'
        );
    });

    test('object', function (assert) {
        var fmt = 'YYYY-MM-DD HH:mm:ss.SSS',
            tests = [
                [{ year: 2010 }, '2010-01-01 00:00:00.000'],
                [{ year: 2010, month: 1 }, '2010-02-01 00:00:00.000'],
                [{ year: 2010, month: 1, day: 12 }, '2010-02-12 00:00:00.000'],
                [{ year: 2010, month: 1, date: 12 }, '2010-02-12 00:00:00.000'],
                [
                    { year: 2010, month: 1, day: 12, hours: 1 },
                    '2010-02-12 01:00:00.000',
                ],
                [
                    { year: 2010, month: 1, date: 12, hours: 1 },
                    '2010-02-12 01:00:00.000',
                ],
                [
                    { year: 2010, month: 1, day: 12, hours: 1, minutes: 1 },
                    '2010-02-12 01:01:00.000',
                ],
                [
                    { year: 2010, month: 1, date: 12, hours: 1, minutes: 1 },
                    '2010-02-12 01:01:00.000',
                ],
                [
                    {
                        year: 2010,
                        month: 1,
                        day: 12,
                        hours: 1,
                        minutes: 1,
                        seconds: 1,
                    },
                    '2010-02-12 01:01:01.000',
                ],
                [
                    {
                        year: 2010,
                        month: 1,
                        day: 12,
                        hours: 1,
                        minutes: 1,
                        seconds: 1,
                        milliseconds: 1,
                    },
                    '2010-02-12 01:01:01.001',
                ],
                [
                    {
                        years: 2010,
                        months: 1,
                        days: 14,
                        hours: 15,
                        minutes: 25,
                        seconds: 50,
                        milliseconds: 125,
                    },
                    '2010-02-14 15:25:50.125',
                ],
                [
                    {
                        year: 2010,
                        month: 1,
                        day: 14,
                        hour: 15,
                        minute: 25,
                        second: 50,
                        millisecond: 125,
                    },
                    '2010-02-14 15:25:50.125',
                ],
                [
                    { y: 2010, M: 1, d: 14, h: 15, m: 25, s: 50, ms: 125 },
                    '2010-02-14 15:25:50.125',
                ],
            ],
            i;
        for (i = 0; i < tests.length; ++i) {
            assert.equal(moment(tests[i][0]).format(fmt), tests[i][1]);
        }
    });

    test('invalid date for object with zero value date or day keys', function (assert) {
        assert.equal(moment({ date: '0' }).format(), 'Invalid date');
        assert.equal(moment({ date: 0 }).format(), 'Invalid date');
        assert.equal(moment({ day: '0' }).format(), 'Invalid date');
        assert.equal(moment({ day: 0 }).format(), 'Invalid date');
    });

    test('multi format array copying', function (assert) {
        var importantArray = ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'];
        moment('1999-02-13', importantArray);
        assert.deepEqual(
            importantArray,
            ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'],
            'initializer should not mutate the original array'
        );
    });

    test('number', function (assert) {
        assert.ok(moment(1000).toDate() instanceof Date, '1000');
        assert.equal(moment(1000).valueOf(), 1000, 'asserting valueOf');
        assert.equal(moment.utc(1000).valueOf(), 1000, 'asserting valueOf');
    });

    test('unix', function (assert) {
        assert.equal(
            moment.unix(1).valueOf(),
            1000,
            '1 unix timestamp == 1000 Date.valueOf'
        );
        assert.equal(
            moment(1000).unix(),
            1,
            '1000 Date.valueOf == 1 unix timestamp'
        );
        assert.equal(
            moment.unix(1000).valueOf(),
            1000000,
            '1000 unix timestamp == 1000000 Date.valueOf'
        );
        assert.equal(
            moment(1500).unix(),
            1,
            '1500 Date.valueOf == 1 unix timestamp'
        );
        assert.equal(
            moment(1900).unix(),
            1,
            '1900 Date.valueOf == 1 unix timestamp'
        );
        assert.equal(
            moment(2100).unix(),
            2,
            '2100 Date.valueOf == 2 unix timestamp'
        );
        assert.equal(
            moment(1333129333524).unix(),
            1333129333,
            '1333129333524 Date.valueOf == 1333129333 unix timestamp'
        );
        assert.equal(
            moment(1333129333524000).unix(),
            1333129333524,
            '1333129333524000 Date.valueOf == 1333129333524 unix timestamp'
        );
    });

    test('date', function (assert) {
        assert.ok(moment(new Date()).toDate() instanceof Date, 'new Date()');
        assert.equal(
            moment(new Date(2016, 0, 1), 'YYYY-MM-DD').format('YYYY-MM-DD'),
            '2016-01-01',
            'If date is provided, format string is ignored'
        );
    });

    test('date with a format as an array', function (assert) {
        var tests = [
                new Date(2016, 9, 27),
                new Date(2016, 9, 28),
                new Date(2016, 9, 29),
                new Date(2016, 9, 30),
                new Date(2016, 9, 31),
            ],
            i;

        for (i = 0; i < tests.length; i++) {
            assert.equal(
                moment(tests[i]).format(),
                moment(tests[i], ['MM/DD/YYYY'], false).format(),
                'Passing date with a format array should still return the correct date'
            );
        }
    });

    test('date mutation', function (assert) {
        var a = new Date();
        assert.ok(
            moment(a).toDate() !== a,
            'the date moment uses should not be the date passed in'
        );
    });

    test('moment', function (assert) {
        assert.ok(moment(moment()).toDate() instanceof Date, 'moment(moment())');
        assert.ok(
            moment(moment(moment())).toDate() instanceof Date,
            'moment(moment(moment()))'
        );
    });

    test('cloning moment should only copy own properties', function (assert) {
        assert.ok(
            !hasOwnProp(moment().clone(), 'month'),
            'Should not clone prototype methods'
        );
    });

    test('cloning moment works with weird clones', function (assert) {
        var extend = function (a, b) {
                var i;
                for (i in b) {
                    a[i] = b[i];
                }
                return a;
            },
            now = moment(),
            nowu = moment.utc();

        assert.equal(
            +extend({}, now).clone(),
            +now,
            'cloning extend-ed now is now'
        );
        assert.equal(
            +extend({}, nowu).clone(),
            +nowu,
            'cloning extend-ed utc now is utc now'
        );
    });

    test('cloning respects moment.momentProperties', function (assert) {
        var m = moment();

        assert.equal(
            m.clone()._special,
            undefined,
            'cloning ignores extra properties'
        );
        m._special = 'bacon';
        moment.momentProperties.push('_special');
        assert.equal(
            m.clone()._special,
            'bacon',
            'cloning respects momentProperties'
        );
        moment.momentProperties.pop();
    });

    test('undefined', function (assert) {
        assert.ok(moment().toDate() instanceof Date, 'undefined');
    });

    test('iso with bad input', function (assert) {
        assert.ok(
            !moment('a', moment.ISO_8601).isValid(),
            'iso parsing with invalid string'
        );
        assert.ok(
            !moment('a', moment.ISO_8601, true).isValid(),
            'iso parsing with invalid string, strict'
        );
    });

    test('iso format 24hrs', function (assert) {
        assert.equal(
            moment('2014-01-01T24:00:00.000').format('YYYY-MM-DD[T]HH:mm:ss.SSS'),
            '2014-01-02T00:00:00.000',
            'iso format with 24:00 localtime'
        );
        assert.equal(
            moment
                .utc('2014-01-01T24:00:00.000')
                .format('YYYY-MM-DD[T]HH:mm:ss.SSS'),
            '2014-01-02T00:00:00.000',
            'iso format with 24:00 utc'
        );
    });

    test('string without format - json', function (assert) {
        assert.equal(
            moment('Date(1325132654000)').valueOf(),
            1325132654000,
            'Date(1325132654000)'
        );
        assert.equal(
            moment('Date(-1325132654000)').valueOf(),
            -1325132654000,
            'Date(-1325132654000)'
        );
        assert.equal(
            moment('/Date(1325132654000)/').valueOf(),
            1325132654000,
            '/Date(1325132654000)/'
        );
        assert.equal(
            moment('/Date(1325132654000+0700)/').valueOf(),
            1325132654000,
            '/Date(1325132654000+0700)/'
        );
        assert.equal(
            moment('/Date(1325132654000-0700)/').valueOf(),
            1325132654000,
            '/Date(1325132654000-0700)/'
        );
    });

    test('string without format - strict parsing', function (assert) {
        assert.equal(
            moment('Date(1325132654000)', false).valueOf(),
            1325132654000,
            'Date(1325132654000)'
        );
        assert.equal(
            moment('Date(1325132654000)', true).valueOf(),
            1325132654000,
            'Date(1325132654000)'
        );
        assert.equal(
            moment('/Date(1325132654000)/', true).valueOf(),
            1325132654000,
            '/Date(1325132654000)/'
        );
        assert.equal(moment('1/1/2001', true).isValid(), false, '1/1/2001');
        assert.equal(moment.utc('1/1/2001', true).isValid(), false, '1/1/2001 utc');
    });

    test('string with format dropped am/pm bug', function (assert) {
        moment.locale('en');

        assert.equal(
            moment('05/1/2012 12:25:00', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'),
            '05/01/2012',
            'should not break if am/pm is left off from the parsing tokens'
        );
        assert.equal(
            moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').format(
                'MM/DD/YYYY'
            ),
            '05/01/2012',
            'should not break if am/pm is left off from the parsing tokens'
        );
        assert.equal(
            moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').format(
                'MM/DD/YYYY'
            ),
            '05/01/2012',
            'should not break if am/pm is left off from the parsing tokens'
        );

        assert.ok(moment('05/1/2012 12:25:00', 'MM/DD/YYYY h:m:s a').isValid());
        assert.ok(moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').isValid());
        assert.ok(moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').isValid());
    });

    test('empty string with formats', function (assert) {
        assert.equal(
            moment('', 'MM').format('YYYY-MM-DD HH:mm:ss'),
            'Invalid date'
        );
        assert.equal(
            moment(' ', 'MM').format('YYYY-MM-DD HH:mm:ss'),
            'Invalid date'
        );
        assert.equal(
            moment(' ', 'DD').format('YYYY-MM-DD HH:mm:ss'),
            'Invalid date'
        );
        assert.equal(
            moment(' ', ['MM', 'DD']).format('YYYY-MM-DD HH:mm:ss'),
            'Invalid date'
        );

        assert.ok(!moment('', 'MM').isValid());
        assert.ok(!moment(' ', 'MM').isValid());
        assert.ok(!moment(' ', 'DD').isValid());
        assert.ok(!moment(' ', ['MM', 'DD']).isValid());
    });

    test('undefined argument with formats', function (assert) {
        assert.equal(
            moment(undefined, 'MM').format('YYYY-MM-DD HH:mm:ss'),
            'Invalid date'
        );
        assert.equal(
            moment(undefined, 'DD').format('YYYY-MM-DD HH:mm:ss'),
            'Invalid date'
        );
        assert.equal(
            moment(undefined, ['MM', 'DD']).format('YYYY-MM-DD HH:mm:ss'),
            'Invalid date'
        );

        assert.ok(!moment(undefined, 'MM').isValid());
        assert.ok(!moment(undefined, 'MM').isValid());
        assert.ok(!moment(undefined, 'DD').isValid());
        assert.ok(!moment(undefined, ['MM', 'DD']).isValid());
    });

    test('defaulting to current date', function (assert) {
        var now = moment();
        assert.equal(
            moment('12:13:14', 'hh:mm:ss').format('YYYY-MM-DD hh:mm:ss'),
            now
                .clone()
                .hour(12)
                .minute(13)
                .second(14)
                .format('YYYY-MM-DD hh:mm:ss'),
            'given only time default to current date'
        );
        assert.equal(
            moment('05', 'DD').format('YYYY-MM-DD'),
            now.clone().date(5).format('YYYY-MM-DD'),
            'given day of month default to current month, year'
        );
        assert.equal(
            moment('05', 'MM').format('YYYY-MM-DD'),
            now.clone().month(4).date(1).format('YYYY-MM-DD'),
            'given month default to current year'
        );
        assert.equal(
            moment('1996', 'YYYY').format('YYYY-MM-DD'),
            now.clone().year(1996).month(0).date(1).format('YYYY-MM-DD'),
            'given year do not default'
        );
    });

    test('matching am/pm', function (assert) {
        assert.equal(
            moment('2012-09-03T03:00PM', 'YYYY-MM-DDThh:mmA').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-09-03T03:00PM',
            'am/pm should parse correctly for PM'
        );
        assert.equal(
            moment('2012-09-03T03:00P.M.', 'YYYY-MM-DDThh:mmA').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-09-03T03:00PM',
            'am/pm should parse correctly for P.M.'
        );
        assert.equal(
            moment('2012-09-03T03:00P', 'YYYY-MM-DDThh:mmA').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-09-03T03:00PM',
            'am/pm should parse correctly for P'
        );
        assert.equal(
            moment('2012-09-03T03:00pm', 'YYYY-MM-DDThh:mmA').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-09-03T03:00PM',
            'am/pm should parse correctly for pm'
        );
        assert.equal(
            moment('2012-09-03T03:00p.m.', 'YYYY-MM-DDThh:mmA').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-09-03T03:00PM',
            'am/pm should parse correctly for p.m.'
        );
        assert.equal(
            moment('2012-09-03T03:00p', 'YYYY-MM-DDThh:mmA').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-09-03T03:00PM',
            'am/pm should parse correctly for p'
        );

        assert.equal(
            moment('2012-09-03T03:00AM', 'YYYY-MM-DDThh:mmA').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-09-03T03:00AM',
            'am/pm should parse correctly for AM'
        );
        assert.equal(
            moment('2012-09-03T03:00A.M.', 'YYYY-MM-DDThh:mmA').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-09-03T03:00AM',
            'am/pm should parse correctly for A.M.'
        );
        assert.equal(
            moment('2012-09-03T03:00A', 'YYYY-MM-DDThh:mmA').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-09-03T03:00AM',
            'am/pm should parse correctly for A'
        );
        assert.equal(
            moment('2012-09-03T03:00am', 'YYYY-MM-DDThh:mmA').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-09-03T03:00AM',
            'am/pm should parse correctly for am'
        );
        assert.equal(
            moment('2012-09-03T03:00a.m.', 'YYYY-MM-DDThh:mmA').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-09-03T03:00AM',
            'am/pm should parse correctly for a.m.'
        );
        assert.equal(
            moment('2012-09-03T03:00a', 'YYYY-MM-DDThh:mmA').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-09-03T03:00AM',
            'am/pm should parse correctly for a'
        );

        assert.equal(
            moment('5:00p.m.March 4 2012', 'h:mmAMMMM D YYYY').format(
                'YYYY-MM-DDThh:mmA'
            ),
            '2012-03-04T05:00PM',
            'am/pm should parse correctly before month names'
        );
    });

    test('string with format', function (assert) {
        moment.locale('en');
        var a = [
                ['YYYY-Q', '2014-4'],
                ['MM-DD-YYYY', '12-02-1999'],
                ['DD-MM-YYYY', '12-02-1999'],
                ['DD/MM/YYYY', '12/02/1999'],
                ['DD_MM_YYYY', '12_02_1999'],
                ['DD:MM:YYYY', '12:02:1999'],
                ['D-M-YY', '2-2-99'],
                ['YY', '99'],
                ['DDD-YYYY', '300-1999'],
                ['DD-MM-YYYY h:m:s', '12-02-1999 2:45:10'],
                ['DD-MM-YYYY h:m:s a', '12-02-1999 2:45:10 am'],
                ['DD-MM-YYYY h:m:s a', '12-02-1999 2:45:10 pm'],
                ['h:mm a', '12:00 pm'],
                ['h:mm a', '12:30 pm'],
                ['h:mm a', '12:00 am'],
                ['h:mm a', '12:30 am'],
                ['HH:mm', '12:00'],
                ['kk:mm', '12:00'],
                ['YYYY-MM-DDTHH:mm:ss', '2011-11-11T11:11:11'],
                ['MM-DD-YYYY [M]', '12-02-1999 M'],
                ['ddd MMM DD HH:mm:ss YYYY', 'Tue Apr 07 22:52:51 2009'],
                ['HH:mm:ss', '12:00:00'],
                ['HH:mm:ss', '12:30:00'],
                ['HH:mm:ss', '00:00:00'],
                ['HH:mm:ss S', '00:30:00 1'],
                ['HH:mm:ss SS', '00:30:00 12'],
                ['HH:mm:ss SSS', '00:30:00 123'],
                ['HH:mm:ss S', '00:30:00 7'],
                ['HH:mm:ss SS', '00:30:00 78'],
                ['HH:mm:ss SSS', '00:30:00 789'],
                ['kk:mm:ss', '12:00:00'],
                ['kk:mm:ss', '12:30:00'],
                ['kk:mm:ss', '24:00:00'],
                ['kk:mm:ss S', '24:30:00 1'],
                ['kk:mm:ss SS', '24:30:00 12'],
                ['kk:mm:ss SSS', '24:30:00 123'],
                ['kk:mm:ss S', '24:30:00 7'],
                ['kk:mm:ss SS', '24:30:00 78'],
                ['kk:mm:ss SSS', '24:30:00 789'],
                ['X', '1234567890'],
                ['x', '1234567890123'],
                ['LT', '12:30 AM'],
                ['LTS', '12:30:29 AM'],
                ['L', '09/02/1999'],
                ['l', '9/2/1999'],
                ['LL', 'September 2, 1999'],
                ['ll', 'Sep 2, 1999'],
                ['LLL', 'September 2, 1999 12:30 AM'],
                ['lll', 'Sep 2, 1999 12:30 AM'],
                ['LLLL', 'Thursday, September 2, 1999 12:30 AM'],
                ['llll', 'Thu, Sep 2, 1999 12:30 AM'],
            ],
            m,
            i;

        for (i = 0; i < a.length; i++) {
            m = moment(a[i][1], a[i][0]);
            assert.ok(m.isValid());
            assert.equal(m.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
        }
    });

    test('2 digit year with YYYY format', function (assert) {
        assert.equal(
            moment('9/2/99', 'D/M/YYYY').format('DD/MM/YYYY'),
            '09/02/1999',
            'D/M/YYYY ---> 9/2/99'
        );
        assert.equal(
            moment('9/2/1999', 'D/M/YYYY').format('DD/MM/YYYY'),
            '09/02/1999',
            'D/M/YYYY ---> 9/2/1999'
        );
        assert.equal(
            moment('9/2/68', 'D/M/YYYY').format('DD/MM/YYYY'),
            '09/02/2068',
            'D/M/YYYY ---> 9/2/68'
        );
        assert.equal(
            moment('9/2/69', 'D/M/YYYY').format('DD/MM/YYYY'),
            '09/02/1969',
            'D/M/YYYY ---> 9/2/69'
        );
    });

    test('unix timestamp format', function (assert) {
        var formats = ['X', 'X.S', 'X.SS', 'X.SSS'],
            i,
            format;

        for (i = 0; i < formats.length; i++) {
            format = formats[i];
            assert.equal(
                moment('1234567890', format).valueOf(),
                1234567890 * 1000,
                format + ' matches timestamp without milliseconds'
            );
            assert.equal(
                moment('1234567890.1', format).valueOf(),
                1234567890 * 1000 + 100,
                format + ' matches timestamp with deciseconds'
            );
            assert.equal(
                moment('1234567890.12', format).valueOf(),
                1234567890 * 1000 + 120,
                format + ' matches timestamp with centiseconds'
            );
            assert.equal(
                moment('1234567890.123', format).valueOf(),
                1234567890 * 1000 + 123,
                format + ' matches timestamp with milliseconds'
            );
        }
    });

    test('unix offset milliseconds', function (assert) {
        assert.equal(
            moment('1234567890123', 'x').valueOf(),
            1234567890123,
            'x matches unix offset in milliseconds'
        );
    });

    test('milliseconds format', function (assert) {
        assert.equal(moment('1', 'S').get('ms'), 100, 'deciseconds');
        // assert.equal(moment('10', 'S', true).isValid(), false, 'deciseconds with two digits');
        // assert.equal(moment('1', 'SS', true).isValid(), false, 'centiseconds with one digits');
        assert.equal(moment('12', 'SS').get('ms'), 120, 'centiseconds');
        // assert.equal(moment('123', 'SS', true).isValid(), false, 'centiseconds with three digits');
        assert.equal(moment('123', 'SSS').get('ms'), 123, 'milliseconds');
        assert.equal(
            moment('1234', 'SSSS').get('ms'),
            123,
            'milliseconds with SSSS'
        );
        assert.equal(
            moment('123456789101112', 'SSSS').get('ms'),
            123,
            'milliseconds with SSSS'
        );
    });

    test('string with format no separators', function (assert) {
        moment.locale('en');
        var a = [
                ['MMDDYYYY', '12021999'],
                ['DDMMYYYY', '12021999'],
                ['YYYYMMDD', '19991202'],
                ['DDMMMYYYY', '10Sep2001'],
            ],
            i;

        for (i = 0; i < a.length; i++) {
            assert.equal(
                moment(a[i][1], a[i][0]).format(a[i][0]),
                a[i][1],
                a[i][0] + ' ---> ' + a[i][1]
            );
        }
    });

    test('string with format (timezone)', function (assert) {
        assert.equal(
            moment('5 -0700', 'H ZZ').toDate().getUTCHours(),
            12,
            "parse hours '5 -0700' ---> 'H ZZ'"
        );
        assert.equal(
            moment('5 -07:00', 'H Z').toDate().getUTCHours(),
            12,
            "parse hours '5 -07:00' ---> 'H Z'"
        );
        assert.equal(
            moment('5 -0730', 'H ZZ').toDate().getUTCMinutes(),
            30,
            "parse hours '5 -0730' ---> 'H ZZ'"
        );
        assert.equal(
            moment('5 -07:30', 'H Z').toDate().getUTCMinutes(),
            30,
            "parse hours '5 -07:0' ---> 'H Z'"
        );
        assert.equal(
            moment('5 +0100', 'H ZZ').toDate().getUTCHours(),
            4,
            "parse hours '5 +0100' ---> 'H ZZ'"
        );
        assert.equal(
            moment('5 +01:00', 'H Z').toDate().getUTCHours(),
            4,
            "parse hours '5 +01:00' ---> 'H Z'"
        );
        assert.equal(
            moment('5 +0130', 'H ZZ').toDate().getUTCMinutes(),
            30,
            "parse hours '5 +0130' ---> 'H ZZ'"
        );
        assert.equal(
            moment('5 +01:30', 'H Z').toDate().getUTCMinutes(),
            30,
            "parse hours '5 +01:30' ---> 'H Z'"
        );
    });

    test('string with format (timezone offset)', function (assert) {
        var a, b, c, d, e, f;
        a = new Date(Date.UTC(2011, 0, 1, 1));
        b = moment('2011 1 1 0 -01:00', 'YYYY MM DD HH Z');
        assert.equal(
            a.getHours(),
            b.hours(),
            'date created with utc == parsed string with timezone offset'
        );
        assert.equal(
            +a,
            +b,
            'date created with utc == parsed string with timezone offset'
        );
        c = moment('2011 2 1 10 -05:00', 'YYYY MM DD HH Z');
        d = moment('2011 2 1 8 -07:00', 'YYYY MM DD HH Z');
        assert.equal(
            c.hours(),
            d.hours(),
            '10 am central time == 8 am pacific time'
        );
        e = moment.utc('20 07 2012 17:15:00', 'DD MM YYYY HH:mm:ss');
        f = moment.utc('20 07 2012 10:15:00 -0700', 'DD MM YYYY HH:mm:ss ZZ');
        assert.equal(e.hours(), f.hours(), 'parse timezone offset in utc');
    });

    test('string with timezone around start of year', function (assert) {
        assert.equal(
            moment('2000-01-01T00:00:00.000+01:00').toISOString(),
            '1999-12-31T23:00:00.000Z',
            '+1:00 around 2000'
        );
        assert.equal(
            moment('2000-01-01T00:00:00.000-01:00').toISOString(),
            '2000-01-01T01:00:00.000Z',
            '-1:00 around 2000'
        );
        assert.equal(
            moment('1970-01-01T00:00:00.000+01:00').toISOString(),
            '1969-12-31T23:00:00.000Z',
            '+1:00 around 1970'
        );
        assert.equal(
            moment('1970-01-01T00:00:00.000-01:00').toISOString(),
            '1970-01-01T01:00:00.000Z',
            '-1:00 around 1970'
        );
        assert.equal(
            moment('1200-01-01T00:00:00.000+01:00').toISOString(),
            '1199-12-31T23:00:00.000Z',
            '+1:00 around 1200'
        );
        assert.equal(
            moment('1200-01-01T00:00:00.000-01:00').toISOString(),
            '1200-01-01T01:00:00.000Z',
            '-1:00 around 1200'
        );
    });

    test('string with array of formats', function (assert) {
        var thursdayForCurrentWeek = moment().day(4).format('YYYY MM DD');

        assert.equal(
            moment('11-02-1999', ['MM-DD-YYYY', 'DD-MM-YYYY']).format('MM DD YYYY'),
            '11 02 1999',
            'switching month and day'
        );
        assert.equal(
            moment('02-11-1999', ['MM/DD/YYYY', 'YYYY MM DD', 'MM-DD-YYYY']).format(
                'MM DD YYYY'
            ),
            '02 11 1999',
            'year last'
        );
        assert.equal(
            moment('1999-02-11', ['MM/DD/YYYY', 'YYYY MM DD', 'MM-DD-YYYY']).format(
                'MM DD YYYY'
            ),
            '02 11 1999',
            'year first'
        );

        assert.equal(
            moment('02-11-1999', ['MM/DD/YYYY', 'YYYY MM DD']).format('MM DD YYYY'),
            '02 11 1999',
            'year last'
        );
        assert.equal(
            moment('1999-02-11', ['MM/DD/YYYY', 'YYYY MM DD']).format('MM DD YYYY'),
            '02 11 1999',
            'year first'
        );
        assert.equal(
            moment('02-11-1999', ['YYYY MM DD', 'MM/DD/YYYY']).format('MM DD YYYY'),
            '02 11 1999',
            'year last'
        );
        assert.equal(
            moment('1999-02-11', ['YYYY MM DD', 'MM/DD/YYYY']).format('MM DD YYYY'),
            '02 11 1999',
            'year first'
        );

        assert.equal(
            moment('13-11-1999', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'),
            '11 13 1999',
            'second must be month'
        );
        assert.equal(
            moment('11-13-1999', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'),
            '11 13 1999',
            'first must be month'
        );
        assert.equal(
            moment('01-02-2000', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'),
            '01 02 2000',
            'either can be a month, month first format'
        );
        assert.equal(
            moment('02-01-2000', ['DD/MM/YYYY', 'MM/DD/YYYY']).format('MM DD YYYY'),
            '01 02 2000',
            'either can be a month, day first format'
        );

        assert.equal(
            moment('11-02-10', ['MM/DD/YY', 'YY MM DD', 'DD-MM-YY']).format(
                'MM DD YYYY'
            ),
            '02 11 2010',
            'all unparsed substrings have influence on format penalty'
        );
        assert.equal(
            moment('11-02-10', ['MM-DD-YY HH:mm', 'YY MM DD']).format('MM DD YYYY'),
            '02 10 2011',
            'prefer formats without extra tokens'
        );
        assert.equal(
            moment('11-02-10 junk', ['MM-DD-YY', 'YY.MM.DD [junk]']).format(
                'MM DD YYYY'
            ),
            '02 10 2011',
            'prefer formats that dont result in extra characters'
        );
        assert.equal(
            moment('11-22-10', ['YY-MM-DD', 'YY-DD-MM']).format('MM DD YYYY'),
            '10 22 2011',
            'prefer valid results'
        );

        assert.equal(
            moment('gibberish', ['YY-MM-DD', 'YY-DD-MM']).format('MM DD YYYY'),
            'Invalid date',
            'doest throw for invalid strings'
        );
        assert.equal(
            moment('gibberish', []).format('MM DD YYYY'),
            'Invalid date',
            'doest throw for an empty array'
        );

        // https://github.com/moment/moment/issues/1143
        assert.equal(
            moment(
                'System Administrator and Database Assistant (7/1/2011), System Administrator and Database Assistant (7/1/2011), Database Coordinator (7/1/2011), Vice President (7/1/2011), System Administrator and Database Assistant (5/31/2012), Database Coordinator (7/1/2012), System Administrator and Database Assistant (7/1/2013)',
                ['MM/DD/YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD', 'YYYY-MM-DDTHH:mm:ssZ']
            ).format('YYYY-MM-DD'),
            '2011-07-01',
            'Works for long strings'
        );

        assert.equal(
            moment('11-02-10', ['MM.DD.YY', 'DD-MM-YY']).format('MM DD YYYY'),
            '02 11 2010',
            'escape RegExp special characters on comparing'
        );

        assert.equal(
            moment('13-10-98', ['DD MM YY', 'DD MM YYYY'])._f,
            'DD MM YY',
            'use two digit year'
        );
        assert.equal(
            moment('13-10-1998', ['DD MM YY', 'DD MM YYYY'])._f,
            'DD MM YYYY',
            'use four digit year'
        );

        assert.equal(
            moment('01', ['MM', 'DD'])._f,
            'MM',
            'Should use first valid format'
        );

        assert.equal(
            moment('Thursday 8:30pm', ['dddd h:mma']).format(
                'YYYY MM DD dddd h:mma'
            ),
            thursdayForCurrentWeek + ' Thursday 8:30pm',
            'Default to current week'
        );
    });

    test('string with array of formats + ISO', function (assert) {
        assert.equal(
            moment('1994', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).year(),
            1994,
            'iso: assert parse YYYY'
        );
        assert.equal(
            moment('17:15', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).hour(),
            17,
            'iso: assert parse HH:mm (1)'
        );
        assert.equal(
            moment('24:15', [moment.ISO_8601, 'MM', 'kk:mm', 'YYYY']).hour(),
            0,
            'iso: assert parse kk:mm'
        );
        assert.equal(
            moment('17:15', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).minutes(),
            15,
            'iso: assert parse HH:mm (2)'
        );
        assert.equal(
            moment('06', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).month(),
            6 - 1,
            'iso: assert parse MM'
        );
        assert.equal(
            moment('2012-06-01', [
                moment.ISO_8601,
                'MM',
                'HH:mm',
                'YYYY',
            ]).parsingFlags().iso,
            true,
            'iso: assert parse iso'
        );
        assert.equal(
            moment('2014-05-05', [moment.ISO_8601, 'YYYY-MM-DD']).parsingFlags()
                .iso,
            true,
            'iso: edge case array precedence iso'
        );
        assert.equal(
            moment('2014-05-05', ['YYYY-MM-DD', moment.ISO_8601]).parsingFlags()
                .iso,
            false,
            'iso: edge case array precedence not iso'
        );
    });

    test('strict parsing invalid date against array of formats', function (assert) {
        var b = moment(
            '2/30/2019 7:00pm',
            [
                'M/DD/YYYY h:mma", "MM/DD/YYYY h:mma", "M-D-YYYY h:mma", "MM-D-YYYY h:mma',
            ],
            true
        );
        assert.deepEqual(
            b.parsingFlags().parsedDateParts,
            [2019, 1, 30, 7, 0],
            'strict parsing multiple formats should still select the best format even if the date is invalid'
        );
    });

    test('string with format - years', function (assert) {
        assert.equal(moment('67', 'YY').format('YYYY'), '2067', '67 > 2067');
        assert.equal(moment('68', 'YY').format('YYYY'), '2068', '68 > 2068');
        assert.equal(moment('69', 'YY').format('YYYY'), '1969', '69 > 1969');
        assert.equal(moment('70', 'YY').format('YYYY'), '1970', '70 > 1970');
    });

    test('implicit cloning', function (assert) {
        var momentA = moment([2011, 10, 10]),
            momentB = moment(momentA);
        momentA.month(5);
        assert.notEqual(
            momentA.month(),
            momentB.month(),
            'Calling moment() on a moment will create a clone'
        );
    });

    test('explicit cloning', function (assert) {
        var momentA = moment([2011, 10, 10]),
            momentB = momentA.clone();
        momentA.month(5);
        assert.notEqual(
            momentA.month(),
            momentB.month(),
            'Calling clone() on a moment will create a clone'
        );
    });

    test('cloning carrying over utc mode', function (assert) {
        assert.equal(
            moment().local().clone()._isUTC,
            false,
            'An explicit cloned local moment should have _isUTC == false'
        );
        assert.equal(
            moment().utc().clone()._isUTC,
            true,
            'An cloned utc moment should have _isUTC == true'
        );
        assert.equal(
            moment().clone()._isUTC,
            false,
            'An explicit cloned local moment should have _isUTC == false'
        );
        assert.equal(
            moment.utc().clone()._isUTC,
            true,
            'An explicit cloned utc moment should have _isUTC == true'
        );
        assert.equal(
            moment(moment().local())._isUTC,
            false,
            'An implicit cloned local moment should have _isUTC == false'
        );
        assert.equal(
            moment(moment().utc())._isUTC,
            true,
            'An implicit cloned utc moment should have _isUTC == true'
        );
        assert.equal(
            moment(moment())._isUTC,
            false,
            'An implicit cloned local moment should have _isUTC == false'
        );
        assert.equal(
            moment(moment.utc())._isUTC,
            true,
            'An implicit cloned utc moment should have _isUTC == true'
        );
    });

    test('parsing RFC 2822', function (assert) {
        var testCases = {
            'Tue, 01 Nov 2016 01:23:45 UT': [2016, 10, 1, 1, 23, 45, 0],
            'Sun, 12 Apr 2015 05:06:07 GMT': [2015, 3, 12, 5, 6, 7, 0],
            'Tue, 01 Nov 2016 01:23:45 +0000': [2016, 10, 1, 1, 23, 45, 0],
            'Tue, 01 Nov 16 04:23:45 Z': [2016, 10, 1, 4, 23, 45, 0],
            '01 Nov 2016 05:23:45 z': [2016, 10, 1, 5, 23, 45, 0],
            '(Init Comment) Tue,\n 1 Nov              2016 (Split\n Comment)  07:23:45 +0000 (GMT)': [
                2016,
                10,
                1,
                7,
                23,
                45,
                0,
            ],
            'Mon, 02 Jan 2017 06:00:00 -0800': [2017, 0, 2, 6, 0, 0, -8 * 60],
            'Mon, 02 Jan 2017 06:00:00 +0800': [2017, 0, 2, 6, 0, 0, +8 * 60],
            'Mon, 02 Jan 2017 06:00:00 +0330': [
                2017,
                0,
                2,
                6,
                0,
                0,
                +(3 * 60 + 30),
            ],
            'Mon, 02 Jan 2017 06:00:00 -0330': [
                2017,
                0,
                2,
                6,
                0,
                0,
                -(3 * 60 + 30),
            ],
            'Mon, 02 Jan 2017 06:00:00 PST': [2017, 0, 2, 6, 0, 0, -8 * 60],
            'Mon, 02 Jan 2017 06:00:00 PDT': [2017, 0, 2, 6, 0, 0, -7 * 60],
            'Mon, 02 Jan 2017 06:00:00 MST': [2017, 0, 2, 6, 0, 0, -7 * 60],
            'Mon, 02 Jan 2017 06:00:00 MDT': [2017, 0, 2, 6, 0, 0, -6 * 60],
            'Mon, 02 Jan 2017 06:00:00 CST': [2017, 0, 2, 6, 0, 0, -6 * 60],
            'Mon, 02 Jan 2017 06:00:00 CDT': [2017, 0, 2, 6, 0, 0, -5 * 60],
            'Mon, 02 Jan 2017 06:00:00 EST': [2017, 0, 2, 6, 0, 0, -5 * 60],
            'Mon, 02 Jan 2017 06:00:00 EDT': [2017, 0, 2, 6, 0, 0, -4 * 60],
        };

        eachOwnProp(testCases, function (inp) {
            var tokens = testCases[inp],
                parseResult = moment(inp, moment.RFC_2822, true).parseZone(),
                expResult = moment
                    .utc(tokens.slice(0, 6))
                    .utcOffset(tokens[6], true);
            assert.ok(parseResult.isValid(), inp);
            assert.ok(
                parseResult.parsingFlags().rfc2822,
                inp + ' - rfc2822 parsingFlag'
            );
            assert.equal(
                parseResult.utcOffset(),
                expResult.utcOffset(),
                inp + ' - zone'
            );
            assert.equal(
                parseResult.valueOf(),
                expResult.valueOf(),
                inp + ' - correctness'
            );
        });
    });

    test('non RFC 2822 strings', function (assert) {
        var testCases = {
            'RFC2822 datetime with all options but invalid day delimiter':
                'Tue. 01 Nov 2016 01:23:45 GMT',
            'RFC2822 datetime with mismatching Day (weekday v date)':
                'Mon, 01 Nov 2016 01:23:45 GMT',
        };

        eachOwnProp(testCases, function (testCase) {
            var testResult = moment(testCases[testCase], moment.RFC_2822, true);
            assert.ok(
                !testResult.isValid(),
                testCase + ': ' + testResult + ' - is invalid rfc2822'
            );
            assert.ok(
                !testResult.parsingFlags().rfc2822,
                testCase + ': ' + testResult + ' - rfc2822 parsingFlag'
            );
        });
    });

    test('parsing RFC 2822 in a different locale', function (assert) {
        var testCases = {
            'clean RFC2822 datetime with all options':
                'Tue, 01 Nov 2016 01:23:45 UT',
            'clean RFC2822 datetime without comma': 'Tue 01 Nov 2016 02:23:45 GMT',
            'clean RFC2822 datetime without seconds':
                'Tue, 01 Nov 2016 03:23 +0000',
            'clean RFC2822 datetime without century': 'Tue, 01 Nov 16 04:23:45 Z',
            'clean RFC2822 datetime without day': '01 Nov 2016 05:23:45 z',
            'clean RFC2822 datetime with single-digit day-of-month':
                'Tue, 1 Nov 2016 06:23:45 GMT',
            'RFC2822 datetime with CFWSs':
                '(Init Comment) Tue,\n 1 Nov              2016 (Split\n Comment)  07:23:45 +0000 (GMT)',
        };

        try {
            moment.locale('ru');
            eachOwnProp(testCases, function (testCase) {
                var testResult = moment(testCases[testCase], moment.RFC_2822, true);
                assert.ok(testResult.isValid(), testResult);
                assert.ok(
                    testResult.parsingFlags().rfc2822,
                    testResult + ' - rfc2822 parsingFlag'
                );
            });
        } finally {
            moment.locale('en');
        }
    });

    test('non RFC 2822 strings in a different locale', function (assert) {
        var testCases = {
            'RFC2822 datetime with all options but invalid day delimiter':
                'Tue. 01 Nov 2016 01:23:45 GMT',
            'RFC2822 datetime with mismatching Day (week v date)':
                'Mon, 01 Nov 2016 01:23:45 GMT',
        };

        try {
            moment.locale('ru');
            eachOwnProp(testCases, function (testCase) {
                var testResult = moment(testCases[testCase], moment.RFC_2822, true);
                assert.ok(!testResult.isValid(), testResult);
                assert.ok(
                    !testResult.parsingFlags().rfc2822,
                    testResult + ' - rfc2822 parsingFlag'
                );
            });
        } finally {
            moment.locale('en');
        }
    });

    test('parsing iso', function (assert) {
        var offset = moment([2011, 9, 8]).utcOffset(),
            pad = function (input) {
                if (input < 10) {
                    return '0' + input;
                }
                return '' + input;
            },
            offStr = function (offset) {
                var hourOffset =
                        offset > 0
                            ? Math.floor(offset / 60)
                            : Math.ceil(offset / 60),
                    minOffset = offset - hourOffset * 60;
                return offset >= 0
                    ? '+' + pad(hourOffset) + ':' + pad(minOffset)
                    : '-' + pad(-hourOffset) + ':' + pad(-minOffset);
            },
            tz = offStr(offset),
            tz0 = offStr(moment([2011, 0, 1]).utcOffset()),
            tz2 = tz.replace(':', ''),
            tz3 = tz2.slice(0, 3),
            //Tz3 removes minutes digit so will break the tests when parsed if they all use the same minutes digit
            hourOffset =
                offset > 0 ? Math.floor(offset / 60) : Math.ceil(offset / 60),
            minOffset = offset - hourOffset * 60,
            minutesForTz3 = pad((4 + minOffset) % 60),
            // minute = pad(4 + minOffset),

            formats = [
                ['2011', '2011-01-01T00:00:00.000' + tz0],
                ['2011-10', '2011-10-01T00:00:00.000' + tz],
                ['2011-10-08', '2011-10-08T00:00:00.000' + tz],
                ['2011-10-08T18', '2011-10-08T18:00:00.000' + tz],
                ['2011-10-08T18:04', '2011-10-08T18:04:00.000' + tz],
                ['2011-10-08T18:04:20', '2011-10-08T18:04:20.000' + tz],
                ['2011-10-08T18:04' + tz, '2011-10-08T18:04:00.000' + tz],
                ['2011-10-08T18:04:20' + tz, '2011-10-08T18:04:20.000' + tz],
                ['2011-10-08T18:04' + tz2, '2011-10-08T18:04:00.000' + tz],
                ['2011-10-08T18:04:20' + tz2, '2011-10-08T18:04:20.000' + tz],
                [
                    '2011-10-08T18:04' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz,
                ],
                [
                    '2011-10-08T18:04:20' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz,
                ],
                ['2011-10-08T18:04:20.1' + tz2, '2011-10-08T18:04:20.100' + tz],
                ['2011-10-08T18:04:20.11' + tz2, '2011-10-08T18:04:20.110' + tz],
                ['2011-10-08T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],
                ['2011-10-08 18', '2011-10-08T18:00:00.000' + tz],
                ['2011-10-08 18:04', '2011-10-08T18:04:00.000' + tz],
                ['2011-10-08 18:04:20', '2011-10-08T18:04:20.000' + tz],
                ['2011-10-08 18:04' + tz, '2011-10-08T18:04:00.000' + tz],
                ['2011-10-08 18:04:20' + tz, '2011-10-08T18:04:20.000' + tz],
                ['2011-10-08 18:04' + tz2, '2011-10-08T18:04:00.000' + tz],
                ['2011-10-08 18:04:20' + tz2, '2011-10-08T18:04:20.000' + tz],
                [
                    '2011-10-08 18:04' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz,
                ],
                [
                    '2011-10-08 18:04:20' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz,
                ],
                ['2011-10-08 18:04:20.1' + tz2, '2011-10-08T18:04:20.100' + tz],
                ['2011-10-08 18:04:20.11' + tz2, '2011-10-08T18:04:20.110' + tz],
                ['2011-10-08 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],
                ['2011-W40', '2011-10-03T00:00:00.000' + tz],
                ['2011-W40-6', '2011-10-08T00:00:00.000' + tz],
                ['2011-W40-6T18', '2011-10-08T18:00:00.000' + tz],
                ['2011-W40-6T18:04', '2011-10-08T18:04:00.000' + tz],
                ['2011-W40-6T18:04:20', '2011-10-08T18:04:20.000' + tz],
                ['2011-W40-6T18:04' + tz, '2011-10-08T18:04:00.000' + tz],
                ['2011-W40-6T18:04:20' + tz, '2011-10-08T18:04:20.000' + tz],
                ['2011-W40-6T18:04' + tz2, '2011-10-08T18:04:00.000' + tz],
                ['2011-W40-6T18:04:20' + tz2, '2011-10-08T18:04:20.000' + tz],
                [
                    '2011-W40-6T18:04' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz,
                ],
                [
                    '2011-W40-6T18:04:20' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz,
                ],
                ['2011-W40-6T18:04:20.1' + tz2, '2011-10-08T18:04:20.100' + tz],
                ['2011-W40-6T18:04:20.11' + tz2, '2011-10-08T18:04:20.110' + tz],
                ['2011-W40-6T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],
                ['2011-W40-6 18', '2011-10-08T18:00:00.000' + tz],
                ['2011-W40-6 18:04', '2011-10-08T18:04:00.000' + tz],
                ['2011-W40-6 18:04:20', '2011-10-08T18:04:20.000' + tz],
                ['2011-W40-6 18:04' + tz, '2011-10-08T18:04:00.000' + tz],
                ['2011-W40-6 18:04:20' + tz, '2011-10-08T18:04:20.000' + tz],
                ['2011-W40-6 18:04' + tz2, '2011-10-08T18:04:00.000' + tz],
                ['2011-W40-6 18:04:20' + tz2, '2011-10-08T18:04:20.000' + tz],
                [
                    '2011-W40-6 18:04' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz,
                ],
                [
                    '2011-W40-6 18:04:20' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz,
                ],
                ['2011-W40-6 18:04:20.1' + tz2, '2011-10-08T18:04:20.100' + tz],
                ['2011-W40-6 18:04:20.11' + tz2, '2011-10-08T18:04:20.110' + tz],
                ['2011-W40-6 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],
                ['2011-281', '2011-10-08T00:00:00.000' + tz],
                ['2011-281T18', '2011-10-08T18:00:00.000' + tz],
                ['2011-281T18:04', '2011-10-08T18:04:00.000' + tz],
                ['2011-281T18:04:20', '2011-10-08T18:04:20.000' + tz],
                ['2011-281T18:04' + tz, '2011-10-08T18:04:00.000' + tz],
                ['2011-281T18:04:20' + tz, '2011-10-08T18:04:20.000' + tz],
                ['2011-281T18:04' + tz2, '2011-10-08T18:04:00.000' + tz],
                ['2011-281T18:04:20' + tz2, '2011-10-08T18:04:20.000' + tz],
                [
                    '2011-281T18:04' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz,
                ],
                [
                    '2011-281T18:04:20' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz,
                ],
                ['2011-281T18:04:20.1' + tz2, '2011-10-08T18:04:20.100' + tz],
                ['2011-281T18:04:20.11' + tz2, '2011-10-08T18:04:20.110' + tz],
                ['2011-281T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],
                ['2011-281 18', '2011-10-08T18:00:00.000' + tz],
                ['2011-281 18:04', '2011-10-08T18:04:00.000' + tz],
                ['2011-281 18:04:20', '2011-10-08T18:04:20.000' + tz],
                ['2011-281 18:04' + tz, '2011-10-08T18:04:00.000' + tz],
                ['2011-281 18:04:20' + tz, '2011-10-08T18:04:20.000' + tz],
                ['2011-281 18:04' + tz2, '2011-10-08T18:04:00.000' + tz],
                ['2011-281 18:04:20' + tz2, '2011-10-08T18:04:20.000' + tz],
                [
                    '2011-281 18:04' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz,
                ],
                [
                    '2011-281 18:04:20' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz,
                ],
                ['2011-281 18:04:20.1' + tz2, '2011-10-08T18:04:20.100' + tz],
                ['2011-281 18:04:20.11' + tz2, '2011-10-08T18:04:20.110' + tz],
                ['2011-281 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],
                ['20111008T18', '2011-10-08T18:00:00.000' + tz],
                ['20111008T1804', '2011-10-08T18:04:00.000' + tz],
                ['20111008T180420', '2011-10-08T18:04:20.000' + tz],
                ['20111008T1804' + tz, '2011-10-08T18:04:00.000' + tz],
                ['20111008T180420' + tz, '2011-10-08T18:04:20.000' + tz],
                ['20111008T1804' + tz2, '2011-10-08T18:04:00.000' + tz],
                ['20111008T180420' + tz2, '2011-10-08T18:04:20.000' + tz],
                [
                    '20111008T1804' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz,
                ],
                [
                    '20111008T180420' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz,
                ],
                ['20111008T180420,1' + tz2, '2011-10-08T18:04:20.100' + tz],
                ['20111008T180420,11' + tz2, '2011-10-08T18:04:20.110' + tz],
                ['20111008T180420,111' + tz2, '2011-10-08T18:04:20.111' + tz],
                ['20111008 18', '2011-10-08T18:00:00.000' + tz],
                ['20111008 1804', '2011-10-08T18:04:00.000' + tz],
                ['20111008 180420', '2011-10-08T18:04:20.000' + tz],
                ['20111008 1804' + tz, '2011-10-08T18:04:00.000' + tz],
                ['20111008 180420' + tz, '2011-10-08T18:04:20.000' + tz],
                ['20111008 1804' + tz2, '2011-10-08T18:04:00.000' + tz],
                ['20111008 180420' + tz2, '2011-10-08T18:04:20.000' + tz],
                [
                    '20111008 1804' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz,
                ],
                [
                    '20111008 180420' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz,
                ],
                ['20111008 180420,1' + tz2, '2011-10-08T18:04:20.100' + tz],
                ['20111008 180420,11' + tz2, '2011-10-08T18:04:20.110' + tz],
                ['20111008 180420,111' + tz2, '2011-10-08T18:04:20.111' + tz],
                ['2011W40', '2011-10-03T00:00:00.000' + tz],
                ['2011W406', '2011-10-08T00:00:00.000' + tz],
                ['2011W406T18', '2011-10-08T18:00:00.000' + tz],
                ['2011W406T1804', '2011-10-08T18:04:00.000' + tz],
                ['2011W406T180420', '2011-10-08T18:04:20.000' + tz],
                ['2011W406 1804' + tz2, '2011-10-08T18:04:00.000' + tz],
                ['2011W406T1804' + tz, '2011-10-08T18:04:00.000' + tz],
                ['2011W406T180420' + tz, '2011-10-08T18:04:20.000' + tz],
                ['2011W406T1804' + tz2, '2011-10-08T18:04:00.000' + tz],
                ['2011W406T180420' + tz2, '2011-10-08T18:04:20.000' + tz],
                [
                    '2011W406T1804' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz,
                ],
                [
                    '2011W406T180420' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz,
                ],
                ['2011W406T180420,1' + tz2, '2011-10-08T18:04:20.100' + tz],
                ['2011W406T180420,11' + tz2, '2011-10-08T18:04:20.110' + tz],
                ['2011W406T180420,111' + tz2, '2011-10-08T18:04:20.111' + tz],
                ['2011W406 18', '2011-10-08T18:00:00.000' + tz],
                ['2011W406 1804', '2011-10-08T18:04:00.000' + tz],
                ['2011W406 180420', '2011-10-08T18:04:20.000' + tz],
                ['2011W406 1804' + tz, '2011-10-08T18:04:00.000' + tz],
                ['2011W406 180420' + tz, '2011-10-08T18:04:20.000' + tz],
                ['2011W406 180420' + tz2, '2011-10-08T18:04:20.000' + tz],
                [
                    '2011W406 1804' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz,
                ],
                [
                    '2011W406 180420' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz,
                ],
                ['2011W406 180420,1' + tz2, '2011-10-08T18:04:20.100' + tz],
                ['2011W406 180420,11' + tz2, '2011-10-08T18:04:20.110' + tz],
                ['2011W406 180420,111' + tz2, '2011-10-08T18:04:20.111' + tz],
                ['2011281', '2011-10-08T00:00:00.000' + tz],
                ['2011281T18', '2011-10-08T18:00:00.000' + tz],
                ['2011281T1804', '2011-10-08T18:04:00.000' + tz],
                ['2011281T180420', '2011-10-08T18:04:20.000' + tz],
                ['2011281T1804' + tz, '2011-10-08T18:04:00.000' + tz],
                ['2011281T180420' + tz, '2011-10-08T18:04:20.000' + tz],
                ['2011281T1804' + tz2, '2011-10-08T18:04:00.000' + tz],
                ['2011281T180420' + tz2, '2011-10-08T18:04:20.000' + tz],
                [
                    '2011281T1804' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz,
                ],
                [
                    '2011281T180420' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz,
                ],
                ['2011281T180420,1' + tz2, '2011-10-08T18:04:20.100' + tz],
                ['2011281T180420,11' + tz2, '2011-10-08T18:04:20.110' + tz],
                ['2011281T180420,111' + tz2, '2011-10-08T18:04:20.111' + tz],
                ['2011281 18', '2011-10-08T18:00:00.000' + tz],
                ['2011281 1804', '2011-10-08T18:04:00.000' + tz],
                ['2011281 180420', '2011-10-08T18:04:20.000' + tz],
                ['2011281 1804' + tz, '2011-10-08T18:04:00.000' + tz],
                ['2011281 180420' + tz, '2011-10-08T18:04:20.000' + tz],
                ['2011281 1804' + tz2, '2011-10-08T18:04:00.000' + tz],
                ['2011281 180420' + tz2, '2011-10-08T18:04:20.000' + tz],
                [
                    '2011281 1804' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz,
                ],
                [
                    '2011281 180420' + tz3,
                    '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz,
                ],
                ['2011281 180420,1' + tz2, '2011-10-08T18:04:20.100' + tz],
                ['2011281 180420,11' + tz2, '2011-10-08T18:04:20.110' + tz],
                ['2011281 180420,111' + tz2, '2011-10-08T18:04:20.111' + tz],
            ],
            i;
        for (i = 0; i < formats.length; i++) {
            assert.equal(
                moment(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),
                formats[i][1],
                'moment should be able to parse ISO ' + formats[i][0]
            );
            assert.equal(
                moment(formats[i][0], moment.ISO_8601).format(
                    'YYYY-MM-DDTHH:mm:ss.SSSZ'
                ),
                formats[i][1],
                'moment should be able to parse specified ISO ' + formats[i][0]
            );
            assert.equal(
                moment(formats[i][0], moment.ISO_8601, true).format(
                    'YYYY-MM-DDTHH:mm:ss.SSSZ'
                ),
                formats[i][1],
                'moment should be able to parse specified strict ISO ' +
                    formats[i][0]
            );
        }
    });

    test('non iso 8601 strings', function (assert) {
        assert.ok(
            !moment('2015-10T10:15', moment.ISO_8601, true).isValid(),
            'incomplete date with time'
        );
        assert.ok(
            !moment('2015-W10T10:15', moment.ISO_8601, true).isValid(),
            'incomplete week date with time'
        );
        assert.ok(
            !moment('2015W10T1015', moment.ISO_8601, true).isValid(),
            'incomplete week date with time (basic)'
        );
        assert.ok(
            !moment('2015-10-08T1015', moment.ISO_8601, true).isValid(),
            'mixing extended and basic format'
        );
        assert.ok(
            !moment('20151008T10:15', moment.ISO_8601, true).isValid(),
            'mixing basic and extended format'
        );
        assert.ok(
            !moment('2015-10-1', moment.ISO_8601, true).isValid(),
            'missing zero padding for day'
        );
    });

    test('parsing iso week year/week/weekday', function (assert) {
        assert.equal(
            moment.utc('2007-W01').format(),
            '2007-01-01T00:00:00Z',
            '2008 week 1 (1st Jan Mon)'
        );
        assert.equal(
            moment.utc('2008-W01').format(),
            '2007-12-31T00:00:00Z',
            '2008 week 1 (1st Jan Tue)'
        );
        assert.equal(
            moment.utc('2003-W01').format(),
            '2002-12-30T00:00:00Z',
            '2008 week 1 (1st Jan Wed)'
        );
        assert.equal(
            moment.utc('2009-W01').format(),
            '2008-12-29T00:00:00Z',
            '2009 week 1 (1st Jan Thu)'
        );
        assert.equal(
            moment.utc('2010-W01').format(),
            '2010-01-04T00:00:00Z',
            '2010 week 1 (1st Jan Fri)'
        );
        assert.equal(
            moment.utc('2011-W01').format(),
            '2011-01-03T00:00:00Z',
            '2011 week 1 (1st Jan Sat)'
        );
        assert.equal(
            moment.utc('2012-W01').format(),
            '2012-01-02T00:00:00Z',
            '2012 week 1 (1st Jan Sun)'
        );
    });

    test('parsing weekdays verifies the day', function (assert) {
        // string with format
        assert.ok(
            !moment('Wed 08-10-2017', 'ddd MM-DD-YYYY').isValid(),
            'because day of week is incorrect for the date'
        );
        assert.ok(
            moment('Thu 08-10-2017', 'ddd MM-DD-YYYY').isValid(),
            'because day of week is correct for the date'
        );
    });

    test('parsing weekday on utc dates verifies day according to utc time', function (assert) {
        assert.ok(moment.utc('Mon 03:59', 'ddd HH:mm').isValid(), 'Monday 03:59');
    });

    test('parsing weekday on local dates verifies day according to local time', function (assert) {
        // this doesn't do much useful if you're not in the US or at least close to it
        assert.ok(moment('Mon 03:59', 'ddd HH:mm').isValid(), 'Monday 03:59');
    });

    test('parsing weekday on utc dates with specified offsets verifies day according to that offset', function (assert) {
        assert.ok(
            moment.utc('Mon 03:59 +12:00', 'ddd HH:mm Z', true).isValid(),
            'Monday 03:59'
        );
    });

    test('parsing weekday on local dates with specified offsets verifies day according to that offset', function (assert) {
        // if you're in the US, these times will all be sometime Sunday, but they should parse as Monday
        assert.ok(
            moment('Mon 03:59 +12:00', 'ddd HH:mm Z', true).isValid(),
            'Monday 03:59'
        );
    });

    test('parsing week year/week/weekday (dow 1, doy 4)', function (assert) {
        moment.locale('dow:1,doy:4', { week: { dow: 1, doy: 4 } });

        assert.equal(
            moment.utc('2007-01', 'gggg-ww').format(),
            '2007-01-01T00:00:00Z',
            '2007 week 1 (1st Jan Mon)'
        );
        assert.equal(
            moment.utc('2008-01', 'gggg-ww').format(),
            '2007-12-31T00:00:00Z',
            '2008 week 1 (1st Jan Tue)'
        );
        assert.equal(
            moment.utc('2003-01', 'gggg-ww').format(),
            '2002-12-30T00:00:00Z',
            '2003 week 1 (1st Jan Wed)'
        );
        assert.equal(
            moment.utc('2009-01', 'gggg-ww').format(),
            '2008-12-29T00:00:00Z',
            '2009 week 1 (1st Jan Thu)'
        );
        assert.equal(
            moment.utc('2010-01', 'gggg-ww').format(),
            '2010-01-04T00:00:00Z',
            '2010 week 1 (1st Jan Fri)'
        );
        assert.equal(
            moment.utc('2011-01', 'gggg-ww').format(),
            '2011-01-03T00:00:00Z',
            '2011 week 1 (1st Jan Sat)'
        );
        assert.equal(
            moment.utc('2012-01', 'gggg-ww').format(),
            '2012-01-02T00:00:00Z',
            '2012 week 1 (1st Jan Sun)'
        );

        moment.defineLocale('dow:1,doy:4', null);
    });

    test('parsing week year/week/weekday (dow 1, doy 7)', function (assert) {
        moment.locale('dow:1,doy:7', { week: { dow: 1, doy: 7 } });

        assert.equal(
            moment.utc('2007-01', 'gggg-ww').format(),
            '2007-01-01T00:00:00Z',
            '2007 week 1 (1st Jan Mon)'
        );
        assert.equal(
            moment.utc('2008-01', 'gggg-ww').format(),
            '2007-12-31T00:00:00Z',
            '2008 week 1 (1st Jan Tue)'
        );
        assert.equal(
            moment.utc('2003-01', 'gggg-ww').format(),
            '2002-12-30T00:00:00Z',
            '2003 week 1 (1st Jan Wed)'
        );
        assert.equal(
            moment.utc('2009-01', 'gggg-ww').format(),
            '2008-12-29T00:00:00Z',
            '2009 week 1 (1st Jan Thu)'
        );
        assert.equal(
            moment.utc('2010-01', 'gggg-ww').format(),
            '2009-12-28T00:00:00Z',
            '2010 week 1 (1st Jan Fri)'
        );
        assert.equal(
            moment.utc('2011-01', 'gggg-ww').format(),
            '2010-12-27T00:00:00Z',
            '2011 week 1 (1st Jan Sat)'
        );
        assert.equal(
            moment.utc('2012-01', 'gggg-ww').format(),
            '2011-12-26T00:00:00Z',
            '2012 week 1 (1st Jan Sun)'
        );
        moment.defineLocale('dow:1,doy:7', null);
    });

    test('parsing week year/week/weekday (dow 0, doy 6)', function (assert) {
        moment.locale('dow:0,doy:6', { week: { dow: 0, doy: 6 } });

        assert.equal(
            moment.utc('2007-01', 'gggg-ww').format(),
            '2006-12-31T00:00:00Z',
            '2007 week 1 (1st Jan Mon)'
        );
        assert.equal(
            moment.utc('2008-01', 'gggg-ww').format(),
            '2007-12-30T00:00:00Z',
            '2008 week 1 (1st Jan Tue)'
        );
        assert.equal(
            moment.utc('2003-01', 'gggg-ww').format(),
            '2002-12-29T00:00:00Z',
            '2003 week 1 (1st Jan Wed)'
        );
        assert.equal(
            moment.utc('2009-01', 'gggg-ww').format(),
            '2008-12-28T00:00:00Z',
            '2009 week 1 (1st Jan Thu)'
        );
        assert.equal(
            moment.utc('2010-01', 'gggg-ww').format(),
            '2009-12-27T00:00:00Z',
            '2010 week 1 (1st Jan Fri)'
        );
        assert.equal(
            moment.utc('2011-01', 'gggg-ww').format(),
            '2010-12-26T00:00:00Z',
            '2011 week 1 (1st Jan Sat)'
        );
        assert.equal(
            moment.utc('2012-01', 'gggg-ww').format(),
            '2012-01-01T00:00:00Z',
            '2012 week 1 (1st Jan Sun)'
        );
        moment.defineLocale('dow:0,doy:6', null);
    });

    test('parsing week year/week/weekday (dow 6, doy 12)', function (assert) {
        moment.locale('dow:6,doy:12', { week: { dow: 6, doy: 12 } });

        assert.equal(
            moment.utc('2007-01', 'gggg-ww').format(),
            '2006-12-30T00:00:00Z',
            '2007 week 1 (1st Jan Mon)'
        );
        assert.equal(
            moment.utc('2008-01', 'gggg-ww').format(),
            '2007-12-29T00:00:00Z',
            '2008 week 1 (1st Jan Tue)'
        );
        assert.equal(
            moment.utc('2003-01', 'gggg-ww').format(),
            '2002-12-28T00:00:00Z',
            '2003 week 1 (1st Jan Wed)'
        );
        assert.equal(
            moment.utc('2009-01', 'gggg-ww').format(),
            '2008-12-27T00:00:00Z',
            '2009 week 1 (1st Jan Thu)'
        );
        assert.equal(
            moment.utc('2010-01', 'gggg-ww').format(),
            '2009-12-26T00:00:00Z',
            '2010 week 1 (1st Jan Fri)'
        );
        assert.equal(
            moment.utc('2011-01', 'gggg-ww').format(),
            '2011-01-01T00:00:00Z',
            '2011 week 1 (1st Jan Sat)'
        );
        assert.equal(
            moment.utc('2012-01', 'gggg-ww').format(),
            '2011-12-31T00:00:00Z',
            '2012 week 1 (1st Jan Sun)'
        );
        moment.defineLocale('dow:6,doy:12', null);
    });

    test('parsing ISO with Z', function (assert) {
        var i,
            mom,
            formats = [
                ['2011-10-08T18:04', '2011-10-08T18:04:00.000'],
                ['2011-10-08T18:04:20', '2011-10-08T18:04:20.000'],
                ['2011-10-08T18:04:20.1', '2011-10-08T18:04:20.100'],
                ['2011-10-08T18:04:20.11', '2011-10-08T18:04:20.110'],
                ['2011-10-08T18:04:20.111', '2011-10-08T18:04:20.111'],
                ['2011-W40-6T18', '2011-10-08T18:00:00.000'],
                ['2011-W40-6T18:04', '2011-10-08T18:04:00.000'],
                ['2011-W40-6T18:04:20', '2011-10-08T18:04:20.000'],
                ['2011-W40-6T18:04:20.1', '2011-10-08T18:04:20.100'],
                ['2011-W40-6T18:04:20.11', '2011-10-08T18:04:20.110'],
                ['2011-W40-6T18:04:20.111', '2011-10-08T18:04:20.111'],
                ['2011-281T18', '2011-10-08T18:00:00.000'],
                ['2011-281T18:04', '2011-10-08T18:04:00.000'],
                ['2011-281T18:04:20', '2011-10-08T18:04:20.000'],
                ['2011-281T18:04:20', '2011-10-08T18:04:20.000'],
                ['2011-281T18:04:20.1', '2011-10-08T18:04:20.100'],
                ['2011-281T18:04:20.11', '2011-10-08T18:04:20.110'],
                ['2011-281T18:04:20.111', '2011-10-08T18:04:20.111'],
            ];

        for (i = 0; i < formats.length; i++) {
            mom = moment(formats[i][0] + 'Z').utc();
            assert.equal(
                mom.format('YYYY-MM-DDTHH:mm:ss.SSS'),
                formats[i][1],
                'moment should be able to parse ISO in UTC ' + formats[i][0] + 'Z'
            );

            mom = moment(formats[i][0] + ' Z').utc();
            assert.equal(
                mom.format('YYYY-MM-DDTHH:mm:ss.SSS'),
                formats[i][1],
                'moment should be able to parse ISO in UTC ' + formats[i][0] + ' Z'
            );
        }
    });

    test('parsing iso with T', function (assert) {
        assert.equal(
            moment('2011-10-08T18')._f,
            'YYYY-MM-DDTHH',
            "should include 'T' in the format"
        );
        assert.equal(
            moment('2011-10-08T18:20')._f,
            'YYYY-MM-DDTHH:mm',
            "should include 'T' in the format"
        );
        assert.equal(
            moment('2011-10-08T18:20:13')._f,
            'YYYY-MM-DDTHH:mm:ss',
            "should include 'T' in the format"
        );
        assert.equal(
            moment('2011-10-08T18:20:13.321')._f,
            'YYYY-MM-DDTHH:mm:ss.SSSS',
            "should include 'T' in the format"
        );

        assert.equal(
            moment('2011-10-08 18')._f,
            'YYYY-MM-DD HH',
            "should not include 'T' in the format"
        );
        assert.equal(
            moment('2011-10-08 18:20')._f,
            'YYYY-MM-DD HH:mm',
            "should not include 'T' in the format"
        );
        assert.equal(
            moment('2011-10-08 18:20:13')._f,
            'YYYY-MM-DD HH:mm:ss',
            "should not include 'T' in the format"
        );
        assert.equal(
            moment('2011-10-08 18:20:13.321')._f,
            'YYYY-MM-DD HH:mm:ss.SSSS',
            "should not include 'T' in the format"
        );
    });

    test('parsing iso Z timezone', function (assert) {
        var i,
            formats = [
                ['2011-10-08T18:04Z', '2011-10-08T18:04:00.000+00:00'],
                ['2011-10-08T18:04:20Z', '2011-10-08T18:04:20.000+00:00'],
                ['2011-10-08T18:04:20.111Z', '2011-10-08T18:04:20.111+00:00'],
            ];
        for (i = 0; i < formats.length; i++) {
            assert.equal(
                moment.utc(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),
                formats[i][1],
                'moment should be able to parse ISO ' + formats[i][0]
            );
        }
    });

    test('parsing iso Z timezone into local', function (assert) {
        var m = moment('2011-10-08T18:04:20.111Z');

        assert.equal(
            m.utc().format('YYYY-MM-DDTHH:mm:ss.SSS'),
            '2011-10-08T18:04:20.111',
            'moment should be able to parse ISO 2011-10-08T18:04:20.111Z'
        );
    });

    test('parsing iso with more subsecond precision digits', function (assert) {
        assert.equal(
            moment.utc('2013-07-31T22:00:00.0000000Z').format(),
            '2013-07-31T22:00:00Z',
            'more than 3 subsecond digits'
        );
    });

    test('null or empty', function (assert) {
        assert.equal(moment('').isValid(), false, "moment('') is not valid");
        assert.equal(moment(null).isValid(), false, 'moment(null) is not valid');
        assert.equal(
            moment(null, 'YYYY-MM-DD').isValid(),
            false,
            "moment('', 'format') is not valid"
        );
        assert.equal(
            moment('', 'YYYY-MM-DD').isValid(),
            false,
            "moment('', 'format') is not valid"
        );
        assert.equal(
            moment.utc('').isValid(),
            false,
            "moment.utc('') is not valid"
        );
        assert.equal(
            moment.utc(null).isValid(),
            false,
            'moment.utc(null) is not valid'
        );
        assert.equal(
            moment.utc(null, 'YYYY-MM-DD').isValid(),
            false,
            'moment.utc(null) is not valid'
        );
        assert.equal(
            moment.utc('', 'YYYY-MM-DD').isValid(),
            false,
            "moment.utc('', 'YYYY-MM-DD') is not valid"
        );
    });

    test('first century', function (assert) {
        assert.equal(
            moment([0, 0, 1]).format('YYYY-MM-DD'),
            '0000-01-01',
            'Year AD 0'
        );
        assert.equal(
            moment([99, 0, 1]).format('YYYY-MM-DD'),
            '0099-01-01',
            'Year AD 99'
        );
        assert.equal(
            moment([999, 0, 1]).format('YYYY-MM-DD'),
            '0999-01-01',
            'Year AD 999'
        );
        assert.equal(
            moment('0 1 1', 'YYYY MM DD').format('YYYY-MM-DD'),
            '0000-01-01',
            'Year AD 0'
        );
        assert.equal(
            moment('999 1 1', 'YYYY MM DD').format('YYYY-MM-DD'),
            '0999-01-01',
            'Year AD 999'
        );
        assert.equal(
            moment('0 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'),
            '00000-01-01',
            'Year AD 0'
        );
        assert.equal(
            moment('99 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'),
            '00099-01-01',
            'Year AD 99'
        );
        assert.equal(
            moment('999 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'),
            '00999-01-01',
            'Year AD 999'
        );
    });

    test('six digit years', function (assert) {
        assert.equal(
            moment([-270000, 0, 1]).format('YYYYY-MM-DD'),
            '-270000-01-01',
            'format BC 270,001'
        );
        assert.equal(
            moment([270000, 0, 1]).format('YYYYY-MM-DD'),
            '270000-01-01',
            'format AD 270,000'
        );
        assert.equal(
            moment('-270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(),
            -270000,
            'parse BC 270,001'
        );
        assert.equal(
            moment('270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(),
            270000,
            'parse AD 270,000'
        );
        assert.equal(
            moment('+270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(),
            270000,
            'parse AD +270,000'
        );
        assert.equal(
            moment.utc('-270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(),
            -270000,
            'parse utc BC 270,001'
        );
        assert.equal(
            moment.utc('270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(),
            270000,
            'parse utc AD 270,000'
        );
        assert.equal(
            moment.utc('+270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(),
            270000,
            'parse utc AD +270,000'
        );
    });

    test('negative four digit years', function (assert) {
        assert.equal(
            moment('-1000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(),
            -1000,
            'parse BC 1,001'
        );
        assert.equal(
            moment.utc('-1000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(),
            -1000,
            'parse utc BC 1,001'
        );
    });

    test('strict parsing', function (assert) {
        assert.equal(
            moment('2014-', 'YYYY-Q', true).isValid(),
            false,
            'fail missing quarter'
        );

        assert.equal(
            moment('2012-05', 'YYYY-MM', true).format('YYYY-MM'),
            '2012-05',
            'parse correct string'
        );
        assert.equal(
            moment(' 2012-05', 'YYYY-MM', true).isValid(),
            false,
            'fail on extra whitespace'
        );
        assert.equal(
            moment('foo 2012-05', '[foo] YYYY-MM', true).format('YYYY-MM'),
            '2012-05',
            'handle fixed text'
        );
        assert.equal(
            moment('2012 05', 'YYYY-MM', true).isValid(),
            false,
            'fail on different separator'
        );
        assert.equal(
            moment('2012 05', 'YYYY MM DD', true).isValid(),
            false,
            'fail on too many tokens'
        );

        assert.equal(
            moment('05 30 2010', ['DD MM YYYY', 'MM DD YYYY'], true).format(
                'MM DD YYYY'
            ),
            '05 30 2010',
            'array with bad date'
        );
        assert.equal(
            moment('05 30 2010', ['', 'MM DD YYYY'], true).format('MM DD YYYY'),
            '05 30 2010',
            'array with invalid format'
        );
        assert.equal(
            moment('05 30 2010', [' DD MM YYYY', 'MM DD YYYY'], true).format(
                'MM DD YYYY'
            ),
            '05 30 2010',
            'array with non-matching format'
        );

        assert.equal(
            moment('2010.*...', 'YYYY.*', true).isValid(),
            false,
            'invalid format with regex chars'
        );
        assert.equal(
            moment('2010.*', 'YYYY.*', true).year(),
            2010,
            'valid format with regex chars'
        );
        assert.equal(
            moment('.*2010.*', '.*YYYY.*', true).year(),
            2010,
            'valid format with regex chars on both sides'
        );

        //strict tokens
        assert.equal(
            moment('-5-05-25', 'YYYY-MM-DD', true).isValid(),
            false,
            'invalid negative year'
        );
        assert.equal(
            moment('2-05-25', 'YYYY-MM-DD', true).isValid(),
            false,
            'invalid one-digit year'
        );
        assert.equal(
            moment('20-05-25', 'YYYY-MM-DD', true).isValid(),
            false,
            'invalid two-digit year'
        );
        assert.equal(
            moment('201-05-25', 'YYYY-MM-DD', true).isValid(),
            false,
            'invalid three-digit year'
        );
        assert.equal(
            moment('2010-05-25', 'YYYY-MM-DD', true).isValid(),
            true,
            'valid four-digit year'
        );
        assert.equal(
            moment('22010-05-25', 'YYYY-MM-DD', true).isValid(),
            false,
            'invalid five-digit year'
        );

        assert.equal(
            moment('12-05-25', 'YY-MM-DD', true).isValid(),
            true,
            'valid two-digit year'
        );
        assert.equal(
            moment('2012-05-25', 'YY-MM-DD', true).isValid(),
            false,
            'invalid four-digit year'
        );

        assert.equal(
            moment('-5-05-25', 'Y-MM-DD', true).isValid(),
            true,
            'valid negative year'
        );
        assert.equal(
            moment('2-05-25', 'Y-MM-DD', true).isValid(),
            true,
            'valid one-digit year'
        );
        assert.equal(
            moment('20-05-25', 'Y-MM-DD', true).isValid(),
            true,
            'valid two-digit year'
        );
        assert.equal(
            moment('201-05-25', 'Y-MM-DD', true).isValid(),
            true,
            'valid three-digit year'
        );

        assert.equal(
            moment('2012-5-25', 'YYYY-M-DD', true).isValid(),
            true,
            'valid one-digit month'
        );
        assert.equal(
            moment('2012-5-25', 'YYYY-MM-DD', true).isValid(),
            false,
            'invalid one-digit month'
        );
        assert.equal(
            moment('2012-05-25', 'YYYY-M-DD', true).isValid(),
            true,
            'valid one-digit month'
        );
        assert.equal(
            moment('2012-05-25', 'YYYY-MM-DD', true).isValid(),
            true,
            'valid one-digit month'
        );

        assert.equal(
            moment('2012-05-2', 'YYYY-MM-D', true).isValid(),
            true,
            'valid one-digit day'
        );
        assert.equal(
            moment('2012-05-2', 'YYYY-MM-DD', true).isValid(),
            false,
            'invalid one-digit day'
        );
        assert.equal(
            moment('2012-05-02', 'YYYY-MM-D', true).isValid(),
            true,
            'valid two-digit day'
        );
        assert.equal(
            moment('2012-05-02', 'YYYY-MM-DD', true).isValid(),
            true,
            'valid two-digit day'
        );

        assert.equal(
            moment('+002012-05-25', 'YYYYY-MM-DD', true).isValid(),
            true,
            'valid six-digit year'
        );
        assert.equal(
            moment('+2012-05-25', 'YYYYY-MM-DD', true).isValid(),
            false,
            'invalid four-digit year'
        );

        //thse are kinda pointless, but they should work as expected
        assert.equal(
            moment('1', 'S', true).isValid(),
            true,
            'valid one-digit milisecond'
        );
        assert.equal(
            moment('12', 'S', true).isValid(),
            false,
            'invalid two-digit milisecond'
        );
        assert.equal(
            moment('123', 'S', true).isValid(),
            false,
            'invalid three-digit milisecond'
        );

        assert.equal(
            moment('1', 'SS', true).isValid(),
            false,
            'invalid one-digit milisecond'
        );
        assert.equal(
            moment('12', 'SS', true).isValid(),
            true,
            'valid two-digit milisecond'
        );
        assert.equal(
            moment('123', 'SS', true).isValid(),
            false,
            'invalid three-digit milisecond'
        );

        assert.equal(
            moment('1', 'SSS', true).isValid(),
            false,
            'invalid one-digit milisecond'
        );
        assert.equal(
            moment('12', 'SSS', true).isValid(),
            false,
            'invalid two-digit milisecond'
        );
        assert.equal(
            moment('123', 'SSS', true).isValid(),
            true,
            'valid three-digit milisecond'
        );

        // strict parsing respects month length
        assert.ok(
            moment('1 January 2000', 'D MMMM YYYY', true).isValid(),
            'capital long-month + MMMM'
        );
        assert.ok(
            !moment('1 January 2000', 'D MMM YYYY', true).isValid(),
            'capital long-month + MMM'
        );
        assert.ok(
            !moment('1 Jan 2000', 'D MMMM YYYY', true).isValid(),
            'capital short-month + MMMM'
        );
        assert.ok(
            moment('1 Jan 2000', 'D MMM YYYY', true).isValid(),
            'capital short-month + MMM'
        );
        assert.ok(
            moment('1 january 2000', 'D MMMM YYYY', true).isValid(),
            'lower long-month + MMMM'
        );
        assert.ok(
            !moment('1 january 2000', 'D MMM YYYY', true).isValid(),
            'lower long-month + MMM'
        );
        assert.ok(
            !moment('1 jan 2000', 'D MMMM YYYY', true).isValid(),
            'lower short-month + MMMM'
        );
        assert.ok(
            moment('1 jan 2000', 'D MMM YYYY', true).isValid(),
            'lower short-month + MMM'
        );
    });

    test('parsing into a locale', function (assert) {
        moment.defineLocale('parselocale', {
            months: 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split(
                '_'
            ),
            monthsShort: 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split(
                '_'
            ),
        });

        moment.locale('en');

        assert.equal(
            moment('2012 seven', 'YYYY MMM', 'parselocale').month(),
            6,
            'should be able to parse in a specific locale'
        );

        moment.locale('parselocale');

        assert.equal(
            moment('2012 july', 'YYYY MMM', 'en').month(),
            6,
            'should be able to parse in a specific locale'
        );

        moment.defineLocale('parselocale', null);
    });

    function getVerifier(test) {
        return function (input, format, expected, description, asymetrical) {
            var m = moment(input, format);
            test.equal(m.format('YYYY MM DD'), expected, 'compare: ' + description);

            //test round trip
            if (!asymetrical) {
                test.equal(m.format(format), input, 'round trip: ' + description);
            }
        };
    }

    test('parsing week and weekday information', function (assert) {
        var ver = getVerifier(assert),
            currentWeekOfYear = moment().weeks(),
            expectedDate2012 = moment([2012, 0, 1])
                .day(0)
                .add(currentWeekOfYear - 1, 'weeks')
                .format('YYYY MM DD'),
            expectedDate1999 = moment([1999, 0, 1])
                .day(0)
                .add(currentWeekOfYear - 1, 'weeks')
                .format('YYYY MM DD');

        // year
        ver('12', 'gg', expectedDate2012, 'week-year two digits');
        ver('2012', 'gggg', expectedDate2012, 'week-year four digits');
        ver('99', 'gg', expectedDate1999, 'week-year two digits previous year');
        ver(
            '1999',
            'gggg',
            expectedDate1999,
            'week-year four digits previous year'
        );

        ver('99', 'GG', '1999 01 04', 'iso week-year two digits');
        ver('1999', 'GGGG', '1999 01 04', 'iso week-year four digits');

        ver('13', 'GG', '2012 12 31', 'iso week-year two digits previous year');
        ver(
            '2013',
            'GGGG',
            '2012 12 31',
            'iso week-year four digits previous year'
        );

        // year + week
        ver('1999 37', 'gggg w', '1999 09 05', 'week');
        ver('1999 37', 'gggg ww', '1999 09 05', 'week double');
        ver('1999 37', 'GGGG W', '1999 09 13', 'iso week');
        ver('1999 37', 'GGGG WW', '1999 09 13', 'iso week double');

        ver('1999 37 4', 'GGGG WW E', '1999 09 16', 'iso day');
        ver('1999 37 04', 'GGGG WW E', '1999 09 16', 'iso day wide', true);

        ver('1999 37 4', 'gggg ww e', '1999 09 09', 'day');
        ver('1999 37 04', 'gggg ww e', '1999 09 09', 'day wide', true);

        // year + week + day
        ver('1999 37 4', 'gggg ww d', '1999 09 09', 'd');
        ver('1999 37 Th', 'gggg ww dd', '1999 09 09', 'dd');
        ver('1999 37 Thu', 'gggg ww ddd', '1999 09 09', 'ddd');
        ver('1999 37 Thursday', 'gggg ww dddd', '1999 09 09', 'dddd');

        // lower-order only
        assert.equal(moment('22', 'ww').week(), 22, 'week sets the week by itself');
        assert.equal(
            moment('22', 'ww').weekYear(),
            moment().weekYear(),
            'week keeps this year'
        );
        assert.equal(
            moment('2012 22', 'YYYY ww').weekYear(),
            2012,
            'week keeps parsed year'
        );

        assert.equal(
            moment('22', 'WW').isoWeek(),
            22,
            'iso week sets the week by itself'
        );
        assert.equal(
            moment('2012 22', 'YYYY WW').weekYear(),
            2012,
            'iso week keeps parsed year'
        );
        assert.equal(
            moment('22', 'WW').isoWeekYear(),
            moment().isoWeekYear(),
            'iso week keeps this year'
        );

        // order
        ver('6 2013 2', 'e gggg w', '2013 01 12', "order doesn't matter");
        ver('6 2013 2', 'E GGGG W', '2013 01 12', "iso order doesn't matter");

        //can parse other stuff too
        assert.equal(
            moment('1999-W37-4 3:30', 'GGGG-[W]WW-E HH:mm').format(
                'YYYY MM DD HH:mm'
            ),
            '1999 09 16 03:30',
            'parsing weeks and hours'
        );

        // In safari, all years before 1300 are shifted back with one day.
        // http://stackoverflow.com/questions/20768975/safari-subtracts-1-day-from-dates-before-1300
        if (new Date('1300-01-01').getUTCFullYear() === 1300) {
            // Years less than 100
            ver('0098-06', 'GGGG-WW', '0098 02 03', 'small years work', true);
        }
    });

    test('parsing localized weekdays', function (assert) {
        var ver = getVerifier(assert);
        try {
            moment.locale('dow:1,doy:4', {
                weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split(
                    '_'
                ),
                weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
                weekdaysMin: 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
                week: { dow: 1, doy: 4 },
            });
            ver('1999 37 4', 'GGGG WW E', '1999 09 16', 'iso ignores locale');
            ver('1999 37 7', 'GGGG WW E', '1999 09 19', 'iso ignores locale');

            ver(
                '1999 37 0',
                'gggg ww e',
                '1999 09 13',
                'localized e uses local doy and dow: 0 = monday'
            );
            ver(
                '1999 37 4',
                'gggg ww e',
                '1999 09 17',
                'localized e uses local doy and dow: 4 = friday'
            );

            ver(
                '1999 37 1',
                'gggg ww d',
                '1999 09 13',
                'localized d uses 0-indexed days: 1 = monday'
            );
            ver(
                '1999 37 Lu',
                'gggg ww dd',
                '1999 09 13',
                'localized d uses 0-indexed days: Mo'
            );
            ver(
                '1999 37 lun.',
                'gggg ww ddd',
                '1999 09 13',
                'localized d uses 0-indexed days: Mon'
            );
            ver(
                '1999 37 lundi',
                'gggg ww dddd',
                '1999 09 13',
                'localized d uses 0-indexed days: Monday'
            );
            ver(
                '1999 37 4',
                'gggg ww d',
                '1999 09 16',
                'localized d uses 0-indexed days: 4'
            );

            //sunday goes at the end of the week
            ver(
                '1999 37 0',
                'gggg ww d',
                '1999 09 19',
                'localized d uses 0-indexed days: 0 = sund'
            );
            ver(
                '1999 37 Di',
                'gggg ww dd',
                '1999 09 19',
                'localized d uses 0-indexed days: 0 = sund'
            );
        } finally {
            moment.defineLocale('dow:1,doy:4', null);
            moment.locale('en');
        }
    });

    test('parsing with customized two-digit year', function (assert) {
        var original = moment.parseTwoDigitYear;
        try {
            assert.equal(moment('68', 'YY').year(), 2068);
            assert.equal(moment('69', 'YY').year(), 1969);
            moment.parseTwoDigitYear = function (input) {
                return +input + (+input > 30 ? 1900 : 2000);
            };
            assert.equal(moment('68', 'YY').year(), 1968);
            assert.equal(moment('67', 'YY').year(), 1967);
            assert.equal(moment('31', 'YY').year(), 1931);
            assert.equal(moment('30', 'YY').year(), 2030);
        } finally {
            moment.parseTwoDigitYear = original;
        }
    });

    test('array with strings', function (assert) {
        assert.equal(
            moment(['2014', '7', '31']).isValid(),
            true,
            'string array + isValid'
        );
    });

    test('object with strings', function (assert) {
        assert.equal(
            moment({ year: '2014', month: '7', day: '31' }).isValid(),
            true,
            'string object + isValid'
        );
    });

    test('utc with array of formats', function (assert) {
        assert.equal(
            moment.utc('2014-01-01', ['YYYY-MM-DD', 'YYYY-MM']).format(),
            '2014-01-01T00:00:00Z',
            'moment.utc works with array of formats'
        );
    });

    test('parsing invalid string weekdays', function (assert) {
        assert.equal(
            false,
            moment('a', 'dd').isValid(),
            'dd with invalid weekday, non-strict'
        );
        assert.equal(
            false,
            moment('a', 'dd', true).isValid(),
            'dd with invalid weekday, strict'
        );
        assert.equal(
            false,
            moment('a', 'ddd').isValid(),
            'ddd with invalid weekday, non-strict'
        );
        assert.equal(
            false,
            moment('a', 'ddd', true).isValid(),
            'ddd with invalid weekday, strict'
        );
        assert.equal(
            false,
            moment('a', 'dddd').isValid(),
            'dddd with invalid weekday, non-strict'
        );
        assert.equal(
            false,
            moment('a', 'dddd', true).isValid(),
            'dddd with invalid weekday, strict'
        );
    });

    test('milliseconds', function (assert) {
        assert.equal(moment('1', 'S').millisecond(), 100);
        assert.equal(moment('12', 'SS').millisecond(), 120);
        assert.equal(moment('123', 'SSS').millisecond(), 123);
        assert.equal(moment('1234', 'SSSS').millisecond(), 123);
        assert.equal(moment('12345', 'SSSSS').millisecond(), 123);
        assert.equal(moment('123456', 'SSSSSS').millisecond(), 123);
        assert.equal(moment('1234567', 'SSSSSSS').millisecond(), 123);
        assert.equal(moment('12345678', 'SSSSSSSS').millisecond(), 123);
        assert.equal(moment('123456789', 'SSSSSSSSS').millisecond(), 123);
    });

    test('hmm', function (assert) {
        assert.equal(
            moment('123', 'hmm', true).format('HH:mm:ss'),
            '01:23:00',
            '123 with hmm'
        );
        assert.equal(
            moment('123a', 'hmmA', true).format('HH:mm:ss'),
            '01:23:00',
            '123a with hmmA'
        );
        assert.equal(
            moment('123p', 'hmmA', true).format('HH:mm:ss'),
            '13:23:00',
            '123p with hmmA'
        );

        assert.equal(
            moment('1234', 'hmm', true).format('HH:mm:ss'),
            '12:34:00',
            '1234 with hmm'
        );
        assert.equal(
            moment('1234a', 'hmmA', true).format('HH:mm:ss'),
            '00:34:00',
            '1234a with hmmA'
        );
        assert.equal(
            moment('1234p', 'hmmA', true).format('HH:mm:ss'),
            '12:34:00',
            '1234p with hmmA'
        );

        assert.equal(
            moment('12345', 'hmmss', true).format('HH:mm:ss'),
            '01:23:45',
            '12345 with hmmss'
        );
        assert.equal(
            moment('12345a', 'hmmssA', true).format('HH:mm:ss'),
            '01:23:45',
            '12345a with hmmssA'
        );
        assert.equal(
            moment('12345p', 'hmmssA', true).format('HH:mm:ss'),
            '13:23:45',
            '12345p with hmmssA'
        );
        assert.equal(
            moment('112345', 'hmmss', true).format('HH:mm:ss'),
            '11:23:45',
            '112345 with hmmss'
        );
        assert.equal(
            moment('112345a', 'hmmssA', true).format('HH:mm:ss'),
            '11:23:45',
            '112345a with hmmssA'
        );
        assert.equal(
            moment('112345p', 'hmmssA', true).format('HH:mm:ss'),
            '23:23:45',
            '112345p with hmmssA'
        );

        assert.equal(
            moment('023', 'Hmm', true).format('HH:mm:ss'),
            '00:23:00',
            '023 with Hmm'
        );
        assert.equal(
            moment('123', 'Hmm', true).format('HH:mm:ss'),
            '01:23:00',
            '123 with Hmm'
        );
        assert.equal(
            moment('1234', 'Hmm', true).format('HH:mm:ss'),
            '12:34:00',
            '1234 with Hmm'
        );
        assert.equal(
            moment('1534', 'Hmm', true).format('HH:mm:ss'),
            '15:34:00',
            '1234 with Hmm'
        );
        assert.equal(
            moment('12345', 'Hmmss', true).format('HH:mm:ss'),
            '01:23:45',
            '12345 with Hmmss'
        );
        assert.equal(
            moment('112345', 'Hmmss', true).format('HH:mm:ss'),
            '11:23:45',
            '112345 with Hmmss'
        );
        assert.equal(
            moment('172345', 'Hmmss', true).format('HH:mm:ss'),
            '17:23:45',
            '112345 with Hmmss'
        );
    });

    test('Y token', function (assert) {
        assert.equal(moment('1-1-2010', 'M-D-Y', true).year(), 2010, 'parsing Y');
    });

    test('parsing flags retain parsed date parts', function (assert) {
        var a = moment('10 p', 'hh:mm a'),
            b;
        assert.equal(
            a.parsingFlags().parsedDateParts[3],
            10,
            'parsed 10 as the hour'
        );
        assert.equal(
            a.parsingFlags().parsedDateParts[0],
            undefined,
            'year was not parsed'
        );
        assert.equal(a.parsingFlags().meridiem, 'p', 'meridiem flag was added');
        b = moment('10:30', ['MMDDYY', 'HH:mm']);
        assert.equal(
            b.parsingFlags().parsedDateParts[3],
            10,
            'multiple format parshing matched hour'
        );
        assert.equal(
            b.parsingFlags().parsedDateParts[0],
            undefined,
            'array is properly copied, no residual data from first token parse'
        );
    });

    test('parsing only meridiem results in invalid date', function (assert) {
        assert.ok(
            !moment('alkj', 'hh:mm a').isValid(),
            'because an a token is used, a meridiem will be parsed but nothing else was so invalid'
        );
        assert.ok(
            moment('02:30 p more extra stuff', 'hh:mm a').isValid(),
            'because other tokens were parsed, date is valid'
        );
        assert.ok(
            moment('1/1/2016 extra data', ['a', 'M/D/YYYY']).isValid(),
            'took second format, does not pick up on meridiem parsed from first format (good copy)'
        );
    });

    test('invalid dates return invalid for methods that access the _d prop', function (assert) {
        var momentAsDate = moment(['2015', '12', '1']).toDate();
        assert.ok(momentAsDate instanceof Date, 'toDate returns a Date object');
        assert.ok(
            isNaN(momentAsDate.getTime()),
            'toDate returns an invalid Date invalid'
        );
    });

    test('k, kk', function (assert) {
        var i, kVal, kkVal;
        for (i = -1; i <= 24; i++) {
            kVal = i + ':15:59';
            kkVal = (i < 10 ? '0' : '') + i + ':15:59';
            if (i !== 24) {
                assert.ok(
                    moment(kVal, 'k:mm:ss').isSame(moment(kVal, 'H:mm:ss')),
                    kVal + ' k parsing'
                );
                assert.ok(
                    moment(kkVal, 'kk:mm:ss').isSame(moment(kkVal, 'HH:mm:ss')),
                    kkVal + ' kk parsing'
                );
            } else {
                assert.equal(
                    moment(kVal, 'k:mm:ss').format('k:mm:ss'),
                    kVal,
                    kVal + ' k parsing'
                );
                assert.equal(
                    moment(kkVal, 'kk:mm:ss').format('kk:mm:ss'),
                    kkVal,
                    kkVal + ' skk parsing'
                );
            }
        }
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('creation data');

    test('valid date', function (assert) {
        var dat = moment('1992-10-22'),
            orig = dat.creationData();

        assert.equal(dat.isValid(), true, '1992-10-22 is valid');
        assert.equal(orig.input, '1992-10-22', 'original input is not correct.');
        assert.equal(orig.format, 'YYYY-MM-DD', 'original format is defined.');
        assert.equal(orig.locale._abbr, 'en', 'default locale is en');
        assert.equal(orig.isUTC, false, 'not a UTC date');
    });

    test('valid date at fr locale', function (assert) {
        var dat = moment('1992-10-22', 'YYYY-MM-DD', 'fr'),
            orig = dat.creationData();

        assert.equal(orig.locale._abbr, 'fr', 'locale is fr');
    });

    test('valid date with formats', function (assert) {
        var dat = moment('29-06-1995', ['MM-DD-YYYY', 'DD-MM', 'DD-MM-YYYY']),
            orig = dat.creationData();

        assert.equal(orig.format, 'DD-MM-YYYY', 'DD-MM-YYYY format is defined.');
    });

    test('strict', function (assert) {
        assert.ok(
            moment('2015-01-02', 'YYYY-MM-DD', true).creationData().strict,
            'strict is true'
        );
        assert.ok(
            !moment('2015-01-02', 'YYYY-MM-DD').creationData().strict,
            'strict is true'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function addUnitAlias(unit, shorthand) {
        var lowerCase = unit.toLowerCase();
    }

    var hookCallback;

    function hooks() {
        return hookCallback.apply(null, arguments);
    }

    function isFunction(input) {
        return (
            (typeof Function !== 'undefined' && input instanceof Function) ||
            Object.prototype.toString.call(input) === '[object Function]'
        );
    }

    function isLeapYear(year) {
        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
    }

    function absFloor(number) {
        if (number < 0) {
            // -0 -> 0
            return Math.ceil(number) || 0;
        } else {
            return Math.floor(number);
        }
    }

    function toInt(argumentForCoercion) {
        var coercedNumber = +argumentForCoercion,
            value = 0;

        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
            value = absFloor(coercedNumber);
        }

        return value;
    }

    function zeroFill(number, targetLength, forceSign) {
        var absNumber = '' + Math.abs(number),
            zerosToFill = targetLength - absNumber.length,
            sign = number >= 0;
        return (
            (sign ? (forceSign ? '+' : '') : '-') +
            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) +
            absNumber
        );
    }

    var formatTokenFunctions = {};

    // token:    'M'
    // padded:   ['MM', 2]
    // ordinal:  'Mo'
    // callback: function () { this.month() + 1 }
    function addFormatToken(token, padded, ordinal, callback) {
        var func = callback;
        if (typeof callback === 'string') {
            func = function () {
                return this[callback]();
            };
        }
        if (token) {
            formatTokenFunctions[token] = func;
        }
        if (padded) {
            formatTokenFunctions[padded[0]] = function () {
                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
            };
        }
        if (ordinal) {
            formatTokenFunctions[ordinal] = function () {
                return this.localeData().ordinal(
                    func.apply(this, arguments),
                    token
                );
            };
        }
    }

    var match2 = /\d\d/, //      00 - 99
        match4 = /\d{4}/, //    0000 - 9999
        match6 = /[+-]?\d{6}/, // -999999 - 999999
        match1to2 = /\d\d?/, //       0 - 99
        match3to4 = /\d\d\d\d?/, //     999 - 9999
        match5to6 = /\d\d\d\d\d\d?/, //   99999 - 999999
        match1to4 = /\d{1,4}/, //       0 - 9999
        match1to6 = /[+-]?\d{1,6}/, // -999999 - 999999
        matchSigned = /[+-]?\d+/, //    -inf - inf
        regexes;

    regexes = {};

    function addRegexToken(token, regex, strictRegex) {
        regexes[token] = isFunction(regex)
            ? regex
            : function (isStrict, localeData) {
                  return isStrict && strictRegex ? strictRegex : regex;
              };
    }

    function isNumber(input) {
        return (
            typeof input === 'number' ||
            Object.prototype.toString.call(input) === '[object Number]'
        );
    }

    var tokens = {};

    function addParseToken(token, callback) {
        var i,
            func = callback;
        if (typeof token === 'string') {
            token = [token];
        }
        if (isNumber(callback)) {
            func = function (input, array) {
                array[callback] = toInt(input);
            };
        }
        for (i = 0; i < token.length; i++) {
            tokens[token[i]] = func;
        }
    }

    function addWeekParseToken(token, callback) {
        addParseToken(token, function (input, array, config, token) {
            config._w = config._w || {};
            callback(input, config._w, config, token);
        });
    }

    var YEAR = 0,
        MONTH = 1,
        HOUR = 3,
        MINUTE = 4,
        SECOND = 5;

    function mod(n, x) {
        return ((n % x) + x) % x;
    }

    function extend(a, b) {
        for (var i in b) {
            if (hasOwnProp(b, i)) {
                a[i] = b[i];
            }
        }

        if (hasOwnProp(b, 'toString')) {
            a.toString = b.toString;
        }

        if (hasOwnProp(b, 'valueOf')) {
            a.valueOf = b.valueOf;
        }

        return a;
    }

    function defaultParsingFlags() {
        // We need to deep clone this object.
        return {
            empty: false,
            unusedTokens: [],
            unusedInput: [],
            overflow: -2,
            charsLeftOver: 0,
            nullInput: false,
            invalidEra: null,
            invalidMonth: null,
            invalidFormat: false,
            userInvalidated: false,
            iso: false,
            parsedDateParts: [],
            era: null,
            meridiem: null,
            rfc2822: false,
            weekdayMismatch: false,
        };
    }

    function getParsingFlags(m) {
        if (m._pf == null) {
            m._pf = defaultParsingFlags();
        }
        return m._pf;
    }

    // Plugins that add properties should also add the key here (null value),
    // so we can properly clone ourselves.
    var momentProperties = (hooks.momentProperties = []);

    function warn(msg) {
        if (
            hooks.suppressDeprecationWarnings === false &&
            typeof console !== 'undefined' &&
            console.warn
        ) {
            console.warn('Deprecation warning: ' + msg);
        }
    }

    function deprecate(msg, fn) {
        var firstTime = true;

        return extend(function () {
            if (hooks.deprecationHandler != null) {
                hooks.deprecationHandler(null, msg);
            }
            if (firstTime) {
                var args = [],
                    arg,
                    i,
                    key;
                for (i = 0; i < arguments.length; i++) {
                    arg = '';
                    if (typeof arguments[i] === 'object') {
                        arg += '\n[' + i + '] ';
                        for (key in arguments[0]) {
                            if (hasOwnProp(arguments[0], key)) {
                                arg += key + ': ' + arguments[0][key] + ', ';
                            }
                        }
                        arg = arg.slice(0, -2); // Remove trailing comma and space
                    } else {
                        arg = arguments[i];
                    }
                    args.push(arg);
                }
                warn(
                    msg +
                        '\nArguments: ' +
                        Array.prototype.slice.call(args).join('') +
                        '\n' +
                        new Error().stack
                );
                firstTime = false;
            }
            return fn.apply(this, arguments);
        }, fn);
    }

    hooks.suppressDeprecationWarnings = false;
    hooks.deprecationHandler = null;

    // FORMATTING

    addFormatToken('Y', 0, 0, function () {
        var y = this.year();
        return y <= 9999 ? zeroFill(y, 4) : '+' + y;
    });

    addFormatToken(0, ['YY', 2], 0, function () {
        return this.year() % 100;
    });

    addFormatToken(0, ['YYYY', 4], 0, 'year');
    addFormatToken(0, ['YYYYY', 5], 0, 'year');
    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');

    // ALIASES

    addUnitAlias('year');

    // PARSING

    addRegexToken('Y', matchSigned);
    addRegexToken('YY', match1to2, match2);
    addRegexToken('YYYY', match1to4, match4);
    addRegexToken('YYYYY', match1to6, match6);
    addRegexToken('YYYYYY', match1to6, match6);

    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
    addParseToken('YYYY', function (input, array) {
        array[YEAR] =
            input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
    });
    addParseToken('YY', function (input, array) {
        array[YEAR] = hooks.parseTwoDigitYear(input);
    });
    addParseToken('Y', function (input, array) {
        array[YEAR] = parseInt(input, 10);
    });

    // HOOKS

    hooks.parseTwoDigitYear = function (input) {
        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
    };

    // FORMATTING

    addFormatToken('w', ['ww', 2], 'wo', 'week');
    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');

    // ALIASES

    addUnitAlias('week');
    addUnitAlias('isoWeek');

    // PARSING

    addRegexToken('w', match1to2);
    addRegexToken('ww', match1to2, match2);
    addRegexToken('W', match1to2);
    addRegexToken('WW', match1to2, match2);

    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (
        input,
        week,
        config,
        token
    ) {
        week[token.substr(0, 1)] = toInt(input);
    });

    // 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');
    addUnitAlias('weekday');
    addUnitAlias('isoWeekday');

    // 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);
    });

    // FORMATTING

    function hFormat() {
        return this.hours() % 12 || 12;
    }

    function kFormat() {
        return this.hours() || 24;
    }

    addFormatToken('H', ['HH', 2], 0, 'hour');
    addFormatToken('h', ['hh', 2], 0, hFormat);
    addFormatToken('k', ['kk', 2], 0, kFormat);

    addFormatToken('hmm', 0, 0, function () {
        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
    });

    addFormatToken('hmmss', 0, 0, function () {
        return (
            '' +
            hFormat.apply(this) +
            zeroFill(this.minutes(), 2) +
            zeroFill(this.seconds(), 2)
        );
    });

    addFormatToken('Hmm', 0, 0, function () {
        return '' + this.hours() + zeroFill(this.minutes(), 2);
    });

    addFormatToken('Hmmss', 0, 0, function () {
        return (
            '' +
            this.hours() +
            zeroFill(this.minutes(), 2) +
            zeroFill(this.seconds(), 2)
        );
    });

    function meridiem(token, lowercase) {
        addFormatToken(token, 0, 0, function () {
            return this.localeData().meridiem(
                this.hours(),
                this.minutes(),
                lowercase
            );
        });
    }

    meridiem('a', true);
    meridiem('A', false);

    // ALIASES

    addUnitAlias('hour');

    // PARSING

    function matchMeridiem(isStrict, locale) {
        return locale._meridiemParse;
    }

    addRegexToken('a', matchMeridiem);
    addRegexToken('A', matchMeridiem);
    addRegexToken('H', match1to2);
    addRegexToken('h', match1to2);
    addRegexToken('k', match1to2);
    addRegexToken('HH', match1to2, match2);
    addRegexToken('hh', match1to2, match2);
    addRegexToken('kk', match1to2, match2);

    addRegexToken('hmm', match3to4);
    addRegexToken('hmmss', match5to6);
    addRegexToken('Hmm', match3to4);
    addRegexToken('Hmmss', match5to6);

    addParseToken(['H', 'HH'], HOUR);
    addParseToken(['k', 'kk'], function (input, array, config) {
        var kInput = toInt(input);
        array[HOUR] = kInput === 24 ? 0 : kInput;
    });
    addParseToken(['a', 'A'], function (input, array, config) {
        config._isPm = config._locale.isPM(input);
        config._meridiem = input;
    });
    addParseToken(['h', 'hh'], function (input, array, config) {
        array[HOUR] = toInt(input);
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('hmm', function (input, array, config) {
        var pos = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos));
        array[MINUTE] = toInt(input.substr(pos));
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('hmmss', function (input, array, config) {
        var pos1 = input.length - 4,
            pos2 = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos1));
        array[MINUTE] = toInt(input.substr(pos1, 2));
        array[SECOND] = toInt(input.substr(pos2));
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('Hmm', function (input, array, config) {
        var pos = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos));
        array[MINUTE] = toInt(input.substr(pos));
    });
    addParseToken('Hmmss', function (input, array, config) {
        var pos1 = input.length - 4,
            pos2 = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos1));
        array[MINUTE] = toInt(input.substr(pos1, 2));
        array[SECOND] = toInt(input.substr(pos2));
    });

    hooks.createFromInputFallback = deprecate(
        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
            'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
            'discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.',
        function (config) {
            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
        }
    );

    // constant that refers to the ISO standard
    hooks.ISO_8601 = function () {};

    // constant that refers to the RFC 2822 form
    hooks.RFC_2822 = function () {};

    function daysInMonth(year, month) {
        if (isNaN(year) || isNaN(month)) {
            return NaN;
        }
        var modMonth = mod(month, 12);
        year += (month - modMonth) / 12;
        return modMonth === 1
            ? isLeapYear(year)
                ? 29
                : 28
            : 31 - ((modMonth % 7) % 2);
    }

    // FORMATTING

    addFormatToken('M', ['MM', 2], 'Mo', function () {
        return this.month() + 1;
    });

    addFormatToken('MMM', 0, 0, function (format) {
        return this.localeData().monthsShort(this, format);
    });

    addFormatToken('MMMM', 0, 0, function (format) {
        return this.localeData().months(this, format);
    });

    // ALIASES

    addUnitAlias('month');

    // PARSING

    addRegexToken('M', match1to2);
    addRegexToken('MM', match1to2, match2);
    addRegexToken('MMM', function (isStrict, locale) {
        return locale.monthsShortRegex(isStrict);
    });
    addRegexToken('MMMM', function (isStrict, locale) {
        return locale.monthsRegex(isStrict);
    });

    addParseToken(['M', 'MM'], function (input, array) {
        array[MONTH] = toInt(input) - 1;
    });

    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
        var month = config._locale.monthsParse(input, token, config._strict);
        // if we didn't find a month name, mark the date as invalid.
        if (month != null) {
            array[MONTH] = month;
        } else {
            getParsingFlags(config).invalidMonth = input;
        }
    });

    module('days in month');

    test('days in month of all but february', function (assert) {
        var days = [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
            year,
            month;
        for (year = 1899; year < 2100; year++) {
            for (month = 0; month < 12; month++) {
                if (month != 1) {
                    assert.equal(moment([year, month]).daysInMonth(), days[month]);
                    assert.equal(daysInMonth(year, month), days[month]);
                }
            }
        }
    });

    test('days in month', function (assert) {
        each([31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], function (days, i) {
            var firstDay = moment([2012, i]),
                lastDay = moment([2012, i, days]);
            assert.equal(
                firstDay.daysInMonth(),
                days,
                firstDay.format('L') + ' should have ' + days + ' days.'
            );
            assert.equal(
                lastDay.daysInMonth(),
                days,
                lastDay.format('L') + ' should have ' + days + ' days.'
            );
        });
    });

    test('days in month leap years', function (assert) {
        assert.equal(
            moment([2010, 1]).daysInMonth(),
            28,
            'Feb 2010 should have 28 days'
        );
        assert.equal(
            moment([2100, 1]).daysInMonth(),
            28,
            'Feb 2100 should have 28 days'
        );
        assert.equal(
            moment([2008, 1]).daysInMonth(),
            29,
            'Feb 2008 should have 29 days'
        );
        assert.equal(
            moment([2000, 1]).daysInMonth(),
            29,
            'Feb 2000 should have 29 days'
        );
    });

    test('days in month with NaN inputs', function (assert) {
        assert.ok(
            isNaN(daysInMonth(NaN, NaN)),
            'year and month NaN inputs should return NaN'
        );
        assert.ok(isNaN(daysInMonth(2, NaN)), 'month NaN inputs should return NaN');
        assert.ok(isNaN(daysInMonth(NaN, 0)), 'year NaN inputs should return NaN');
        assert.ok(
            !moment([2010, null, null]).isValid(),
            'Invalid date because month is NaN'
        );
    });

    test('days in month with overflow', function (assert) {
        assert.equal(
            daysInMonth(14, 22),
            daysInMonth(15, 10),
            'positive overflow by 1'
        );
        assert.equal(
            daysInMonth(14, 122),
            daysInMonth(24, 2),
            'positive overflow by 10'
        );
        assert.equal(
            daysInMonth(8, -2),
            daysInMonth(7, 10),
            'negative overflow by 1'
        );
        assert.equal(
            daysInMonth(-2380, -25),
            daysInMonth(-2383, 11),
            'negative overflow by 3'
        );
    });

    test('days in month consistent with Date()', function (assert) {
        var oldMethod = function (year, month) {
            return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
        };
        assert.equal(
            daysInMonth(14, 22),
            oldMethod(14, 22),
            'positive overflow by 1'
        );
        assert.equal(
            daysInMonth(14, 122),
            oldMethod(14, 122),
            'positive overflow by 10'
        );
        assert.equal(
            daysInMonth(8, -2),
            oldMethod(8, -2),
            'negative overflow by 1'
        );
        assert.equal(
            daysInMonth(-2380, -25),
            oldMethod(-2380, -25),
            'negative overflow by 3'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('days in year');

    // https://github.com/moment/moment/issues/3717
    test('YYYYDDD should not parse DDD=000', function (assert) {
        assert.equal(moment(7000000, moment.ISO_8601, true).isValid(), false);
        assert.equal(moment('7000000', moment.ISO_8601, true).isValid(), false);
        assert.equal(moment(7000000, moment.ISO_8601, false).isValid(), false);
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function extend(a, b) {
        for (var i in b) {
            if (hasOwnProp(b, i)) {
                a[i] = b[i];
            }
        }

        if (hasOwnProp(b, 'toString')) {
            a.toString = b.toString;
        }

        if (hasOwnProp(b, 'valueOf')) {
            a.valueOf = b.valueOf;
        }

        return a;
    }

    var hookCallback;

    function hooks() {
        return hookCallback.apply(null, arguments);
    }

    function warn(msg) {
        if (
            hooks.suppressDeprecationWarnings === false &&
            typeof console !== 'undefined' &&
            console.warn
        ) {
            console.warn('Deprecation warning: ' + msg);
        }
    }

    function deprecate(msg, fn) {
        var firstTime = true;

        return extend(function () {
            if (hooks.deprecationHandler != null) {
                hooks.deprecationHandler(null, msg);
            }
            if (firstTime) {
                var args = [],
                    arg,
                    i,
                    key;
                for (i = 0; i < arguments.length; i++) {
                    arg = '';
                    if (typeof arguments[i] === 'object') {
                        arg += '\n[' + i + '] ';
                        for (key in arguments[0]) {
                            if (hasOwnProp(arguments[0], key)) {
                                arg += key + ': ' + arguments[0][key] + ', ';
                            }
                        }
                        arg = arg.slice(0, -2); // Remove trailing comma and space
                    } else {
                        arg = arguments[i];
                    }
                    args.push(arg);
                }
                warn(
                    msg +
                        '\nArguments: ' +
                        Array.prototype.slice.call(args).join('') +
                        '\n' +
                        new Error().stack
                );
                firstTime = false;
            }
            return fn.apply(this, arguments);
        }, fn);
    }

    hooks.suppressDeprecationWarnings = false;
    hooks.deprecationHandler = null;

    module('deprecate');

    test('deprecate', function (assert) {
        // NOTE: hooks inside deprecate.js and moment are different, so this is can
        // not be test.expectedDeprecations(...)
        var fn = function () {},
            deprecatedFn = deprecate('testing deprecation', fn);
        deprecatedFn();

        assert.expect(0);
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    function equal(assert, a, b, message) {
        assert.ok(
            Math.abs(a - b) < 0.00000001,
            '(' + a + ' === ' + b + ') ' + message
        );
    }

    function dstForYear(year) {
        var start = moment([year]),
            end = moment([year + 1]),
            current = start.clone(),
            last;

        while (current < end) {
            last = current.clone();
            current.add(24, 'hour');
            if (last.utcOffset() !== current.utcOffset()) {
                end = current.clone();
                current = last.clone();
                break;
            }
        }

        while (current < end) {
            last = current.clone();
            current.add(1, 'hour');
            if (last.utcOffset() !== current.utcOffset()) {
                return {
                    moment: last,
                    diff: -(current.utcOffset() - last.utcOffset()) / 60,
                };
            }
        }
    }

    module('diff');

    test('diff', function (assert) {
        assert.equal(moment(1000).diff(0), 1000, '1 second - 0 = 1000');
        assert.equal(moment(1000).diff(500), 500, '1 second - 0.5 seconds = 500');
        assert.equal(moment(0).diff(1000), -1000, '0 - 1 second = -1000');
        assert.equal(
            moment(new Date(1000)).diff(1000),
            0,
            '1 second - 1 second = 0'
        );
        var oneHourDate = new Date(2015, 5, 21),
            nowDate = new Date(+oneHourDate);
        oneHourDate.setHours(oneHourDate.getHours() + 1);
        assert.equal(
            moment(oneHourDate).diff(nowDate),
            60 * 60 * 1000,
            '1 hour from now = 3600000'
        );
    });

    test('diff key after', function (assert) {
        assert.equal(moment([2010]).diff([2011], 'years'), -1, 'year diff');
        assert.equal(moment([2010]).diff([2010, 2], 'months'), -2, 'month diff');
        assert.equal(moment([2010]).diff([2010, 0, 7], 'weeks'), 0, 'week diff');
        assert.equal(moment([2010]).diff([2010, 0, 8], 'weeks'), -1, 'week diff');
        assert.equal(moment([2010]).diff([2010, 0, 21], 'weeks'), -2, 'week diff');
        assert.equal(moment([2010]).diff([2010, 0, 22], 'weeks'), -3, 'week diff');
        assert.equal(moment([2010]).diff([2010, 0, 4], 'days'), -3, 'day diff');
        assert.equal(
            moment([2010]).diff([2010, 0, 1, 4], 'hours'),
            -4,
            'hour diff'
        );
        assert.equal(
            moment([2010]).diff([2010, 0, 1, 0, 5], 'minutes'),
            -5,
            'minute diff'
        );
        assert.equal(
            moment([2010]).diff([2010, 0, 1, 0, 0, 6], 'seconds'),
            -6,
            'second diff'
        );
    });

    test('diff key before', function (assert) {
        assert.equal(moment([2011]).diff([2010], 'years'), 1, 'year diff');
        assert.equal(moment([2010, 2]).diff([2010], 'months'), 2, 'month diff');
        assert.equal(moment([2010, 0, 4]).diff([2010], 'days'), 3, 'day diff');
        assert.equal(moment([2010, 0, 7]).diff([2010], 'weeks'), 0, 'week diff');
        assert.equal(moment([2010, 0, 8]).diff([2010], 'weeks'), 1, 'week diff');
        assert.equal(moment([2010, 0, 21]).diff([2010], 'weeks'), 2, 'week diff');
        assert.equal(moment([2010, 0, 22]).diff([2010], 'weeks'), 3, 'week diff');
        assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'hours'), 4, 'hour diff');
        assert.equal(
            moment([2010, 0, 1, 0, 5]).diff([2010], 'minutes'),
            5,
            'minute diff'
        );
        assert.equal(
            moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'seconds'),
            6,
            'second diff'
        );
    });

    test('diff key before singular', function (assert) {
        assert.equal(moment([2011]).diff([2010], 'year'), 1, 'year diff singular');
        assert.equal(
            moment([2010, 2]).diff([2010], 'month'),
            2,
            'month diff singular'
        );
        assert.equal(
            moment([2010, 0, 4]).diff([2010], 'day'),
            3,
            'day diff singular'
        );
        assert.equal(
            moment([2010, 0, 7]).diff([2010], 'week'),
            0,
            'week diff singular'
        );
        assert.equal(
            moment([2010, 0, 8]).diff([2010], 'week'),
            1,
            'week diff singular'
        );
        assert.equal(
            moment([2010, 0, 21]).diff([2010], 'week'),
            2,
            'week diff singular'
        );
        assert.equal(
            moment([2010, 0, 22]).diff([2010], 'week'),
            3,
            'week diff singular'
        );
        assert.equal(
            moment([2010, 0, 1, 4]).diff([2010], 'hour'),
            4,
            'hour diff singular'
        );
        assert.equal(
            moment([2010, 0, 1, 0, 5]).diff([2010], 'minute'),
            5,
            'minute diff singular'
        );
        assert.equal(
            moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'second'),
            6,
            'second diff singular'
        );
    });

    test('diff key before abbreviated', function (assert) {
        assert.equal(moment([2011]).diff([2010], 'y'), 1, 'year diff abbreviated');
        assert.equal(
            moment([2010, 2]).diff([2010], 'M'),
            2,
            'month diff abbreviated'
        );
        assert.equal(
            moment([2010, 0, 4]).diff([2010], 'd'),
            3,
            'day diff abbreviated'
        );
        assert.equal(
            moment([2010, 0, 7]).diff([2010], 'w'),
            0,
            'week diff abbreviated'
        );
        assert.equal(
            moment([2010, 0, 8]).diff([2010], 'w'),
            1,
            'week diff abbreviated'
        );
        assert.equal(
            moment([2010, 0, 21]).diff([2010], 'w'),
            2,
            'week diff abbreviated'
        );
        assert.equal(
            moment([2010, 0, 22]).diff([2010], 'w'),
            3,
            'week diff abbreviated'
        );
        assert.equal(
            moment([2010, 0, 1, 4]).diff([2010], 'h'),
            4,
            'hour diff abbreviated'
        );
        assert.equal(
            moment([2010, 0, 1, 0, 5]).diff([2010], 'm'),
            5,
            'minute diff abbreviated'
        );
        assert.equal(
            moment([2010, 0, 1, 0, 0, 6]).diff([2010], 's'),
            6,
            'second diff abbreviated'
        );
    });

    test('diff month', function (assert) {
        assert.equal(
            moment([2011, 0, 31]).diff([2011, 2, 1], 'months'),
            -1,
            'month diff'
        );
    });

    test('end of month diff', function (assert) {
        assert.equal(
            moment('2016-02-29').diff('2016-01-30', 'months'),
            1,
            'Feb 29 to Jan 30 should be 1 month'
        );
        assert.equal(
            moment('2016-02-29').diff('2016-01-31', 'months'),
            1,
            'Feb 29 to Jan 31 should be 1 month'
        );
        assert.equal(
            moment('2016-05-31')
                .add(1, 'month')
                .diff(moment('2016-05-31'), 'month'),
            1,
            '(May 31 plus 1 month) to May 31 should be 1 month diff'
        );
    });

    test('end of month diff with time behind', function (assert) {
        assert.equal(
            moment('2017-03-31').diff('2017-02-28', 'months'),
            1,
            'Feb 28 to March 31 should be 1 month'
        );
        assert.equal(
            moment('2017-02-28').diff('2017-03-31', 'months'),
            -1,
            'Feb 28 to March 31 should be 1 month'
        );
    });

    test('diff across DST', function (assert) {
        var dst = dstForYear(2012),
            a,
            b;
        if (!dst) {
            assert.equal(42, 42, 'at least one assertion');
            return;
        }

        a = dst.moment;
        b = a.clone().utc().add(12, 'hours').local();
        assert.equal(
            b.diff(a, 'milliseconds', true),
            12 * 60 * 60 * 1000,
            'ms diff across DST'
        );
        assert.equal(
            b.diff(a, 'seconds', true),
            12 * 60 * 60,
            'second diff across DST'
        );
        assert.equal(b.diff(a, 'minutes', true), 12 * 60, 'minute diff across DST');
        assert.equal(b.diff(a, 'hours', true), 12, 'hour diff across DST');
        assert.equal(
            b.diff(a, 'days', true),
            (12 - dst.diff) / 24,
            'day diff across DST'
        );
        equal(
            assert,
            b.diff(a, 'weeks', true),
            (12 - dst.diff) / 24 / 7,
            'week diff across DST'
        );
        assert.ok(
            0.95 / (2 * 31) < b.diff(a, 'months', true),
            'month diff across DST, lower bound'
        );
        assert.ok(
            b.diff(a, 'month', true) < 1.05 / (2 * 28),
            'month diff across DST, upper bound'
        );
        assert.ok(
            0.95 / (2 * 31 * 12) < b.diff(a, 'years', true),
            'year diff across DST, lower bound'
        );
        assert.ok(
            b.diff(a, 'year', true) < 1.05 / (2 * 28 * 12),
            'year diff across DST, upper bound'
        );

        a = dst.moment;
        b = a
            .clone()
            .utc()
            .add(12 + dst.diff, 'hours')
            .local();

        assert.equal(
            b.diff(a, 'milliseconds', true),
            (12 + dst.diff) * 60 * 60 * 1000,
            'ms diff across DST'
        );
        assert.equal(
            b.diff(a, 'seconds', true),
            (12 + dst.diff) * 60 * 60,
            'second diff across DST'
        );
        assert.equal(
            b.diff(a, 'minutes', true),
            (12 + dst.diff) * 60,
            'minute diff across DST'
        );
        assert.equal(
            b.diff(a, 'hours', true),
            12 + dst.diff,
            'hour diff across DST'
        );
        assert.equal(b.diff(a, 'days', true), 12 / 24, 'day diff across DST');
        equal(
            assert,
            b.diff(a, 'weeks', true),
            12 / 24 / 7,
            'week diff across DST'
        );
        assert.ok(
            0.95 / (2 * 31) < b.diff(a, 'months', true),
            'month diff across DST, lower bound'
        );
        assert.ok(
            b.diff(a, 'month', true) < 1.05 / (2 * 28),
            'month diff across DST, upper bound'
        );
        assert.ok(
            0.95 / (2 * 31 * 12) < b.diff(a, 'years', true),
            'year diff across DST, lower bound'
        );
        assert.ok(
            b.diff(a, 'year', true) < 1.05 / (2 * 28 * 12),
            'year diff across DST, upper bound'
        );
    });

    test('diff overflow', function (assert) {
        assert.equal(moment([2011]).diff([2010], 'months'), 12, 'month diff');
        assert.equal(moment([2010, 0, 2]).diff([2010], 'hours'), 24, 'hour diff');
        assert.equal(
            moment([2010, 0, 1, 2]).diff([2010], 'minutes'),
            120,
            'minute diff'
        );
        assert.equal(
            moment([2010, 0, 1, 0, 4]).diff([2010], 'seconds'),
            240,
            'second diff'
        );
    });

    test('diff between utc and local', function (assert) {
        if (moment([2012]).utcOffset() === moment([2011]).utcOffset()) {
            // Russia's utc offset on 1st of Jan 2012 vs 2011 is different
            assert.equal(
                moment([2012]).utc().diff([2011], 'years'),
                1,
                'year diff'
            );
        }
        assert.equal(
            moment([2010, 2, 2]).utc().diff([2010, 0, 2], 'months'),
            2,
            'month diff'
        );
        assert.equal(
            moment([2010, 0, 4]).utc().diff([2010], 'days'),
            3,
            'day diff'
        );
        assert.equal(
            moment([2010, 0, 22]).utc().diff([2010], 'weeks'),
            3,
            'week diff'
        );
        assert.equal(
            moment([2010, 0, 1, 4]).utc().diff([2010], 'hours'),
            4,
            'hour diff'
        );
        assert.equal(
            moment([2010, 0, 1, 0, 5]).utc().diff([2010], 'minutes'),
            5,
            'minute diff'
        );
        assert.equal(
            moment([2010, 0, 1, 0, 0, 6]).utc().diff([2010], 'seconds'),
            6,
            'second diff'
        );
    });

    test('diff floored', function (assert) {
        assert.equal(
            moment([2010, 0, 1, 23]).diff([2010], 'day'),
            0,
            '23 hours = 0 days'
        );
        assert.equal(
            moment([2010, 0, 1, 23, 59]).diff([2010], 'day'),
            0,
            '23:59 hours = 0 days'
        );
        assert.equal(
            moment([2010, 0, 1, 24]).diff([2010], 'day'),
            1,
            '24 hours = 1 day'
        );
        assert.equal(
            moment([2010, 0, 2]).diff([2011, 0, 1], 'year'),
            0,
            'year rounded down'
        );
        assert.equal(
            moment([2011, 0, 1]).diff([2010, 0, 2], 'year'),
            0,
            'year rounded down'
        );
        assert.equal(
            moment([2010, 0, 2]).diff([2011, 0, 2], 'year'),
            -1,
            'year rounded down'
        );
        assert.equal(
            moment([2011, 0, 2]).diff([2010, 0, 2], 'year'),
            1,
            'year rounded down'
        );
    });

    test('year diffs include dates', function (assert) {
        assert.ok(
            moment([2012, 1, 19]).diff(moment([2002, 1, 20]), 'years', true) < 10,
            'year diff should include date of month'
        );
    });

    test('month diffs', function (assert) {
        // due to floating point math errors, these tests just need to be accurate within 0.00000001
        assert.equal(
            moment([2012, 0, 1]).diff([2012, 1, 1], 'months', true),
            -1,
            'Jan 1 to Feb 1 should be 1 month'
        );
        equal(
            assert,
            moment([2012, 0, 1]).diff([2012, 0, 1, 12], 'months', true),
            -0.5 / 31,
            'Jan 1 to Jan 1 noon should be 0.5 / 31 months'
        );
        assert.equal(
            moment([2012, 0, 15]).diff([2012, 1, 15], 'months', true),
            -1,
            'Jan 15 to Feb 15 should be 1 month'
        );
        assert.equal(
            moment([2012, 0, 28]).diff([2012, 1, 28], 'months', true),
            -1,
            'Jan 28 to Feb 28 should be 1 month'
        );
        assert.ok(
            moment([2012, 0, 31]).diff([2012, 1, 29], 'months', true),
            -1,
            'Jan 31 to Feb 29 should be 1 month'
        );
        assert.ok(
            -1 > moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true),
            'Jan 31 to Mar 1 should be more than 1 month'
        );
        assert.ok(
            -30 / 28 < moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true),
            'Jan 31 to Mar 1 should be less than 1 month and 1 day'
        );
        equal(
            assert,
            moment([2012, 0, 1]).diff([2012, 0, 31], 'months', true),
            -(30 / 31),
            'Jan 1 to Jan 31 should be 30 / 31 months'
        );
        assert.ok(
            0 < moment('2014-02-01').diff(moment('2014-01-31'), 'months', true),
            'jan-31 to feb-1 diff is positive'
        );
    });

    test('exact month diffs', function (assert) {
        // generate all pairs of months and compute month diff, with fixed day
        // of month = 15.

        var m1, m2;
        for (m1 = 0; m1 < 12; ++m1) {
            for (m2 = m1; m2 < 12; ++m2) {
                assert.equal(
                    moment([2013, m2, 15]).diff(
                        moment([2013, m1, 15]),
                        'months',
                        true
                    ),
                    m2 - m1,
                    'month diff from 2013-' + m1 + '-15 to 2013-' + m2 + '-15'
                );
            }
        }
    });

    test('year diffs', function (assert) {
        // due to floating point math errors, these tests just need to be accurate within 0.00000001
        equal(
            assert,
            moment([2012, 0, 1]).diff([2013, 0, 1], 'years', true),
            -1,
            'Jan 1 2012 to Jan 1 2013 should be 1 year'
        );
        equal(
            assert,
            moment([2012, 1, 28]).diff([2013, 1, 28], 'years', true),
            -1,
            'Feb 28 2012 to Feb 28 2013 should be 1 year'
        );
        equal(
            assert,
            moment([2012, 2, 1]).diff([2013, 2, 1], 'years', true),
            -1,
            'Mar 1 2012 to Mar 1 2013 should be 1 year'
        );
        equal(
            assert,
            moment([2012, 11, 1]).diff([2013, 11, 1], 'years', true),
            -1,
            'Dec 1 2012 to Dec 1 2013 should be 1 year'
        );
        equal(
            assert,
            moment([2012, 11, 31]).diff([2013, 11, 31], 'years', true),
            -1,
            'Dec 31 2012 to Dec 31 2013 should be 1 year'
        );
        equal(
            assert,
            moment([2012, 0, 1]).diff([2013, 6, 1], 'years', true),
            -1.5,
            'Jan 1 2012 to Jul 1 2013 should be 1.5 years'
        );
        equal(
            assert,
            moment([2012, 0, 31]).diff([2013, 6, 31], 'years', true),
            -1.5,
            'Jan 31 2012 to Jul 31 2013 should be 1.5 years'
        );
        equal(
            assert,
            moment([2012, 0, 1]).diff([2013, 0, 1, 12], 'years', true),
            -1 - 0.5 / 31 / 12,
            'Jan 1 2012 to Jan 1 2013 noon should be 1+(0.5 / 31) / 12 years'
        );
        equal(
            assert,
            moment([2012, 0, 1]).diff([2013, 6, 1, 12], 'years', true),
            -1.5 - 0.5 / 31 / 12,
            'Jan 1 2012 to Jul 1 2013 noon should be 1.5+(0.5 / 31) / 12 years'
        );
        equal(
            assert,
            moment([2012, 1, 29]).diff([2013, 1, 28], 'years', true),
            -1,
            'Feb 29 2012 to Feb 28 2013 should be 1-(1 / 28.5) / 12 years'
        );
    });

    test('negative zero', function (assert) {
        function isNegative(n) {
            return 1 / n < 0;
        }
        assert.ok(
            !isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'months')),
            'month diff on same date is zero, not -0'
        );
        assert.ok(
            !isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'years')),
            'year diff on same date is zero, not -0'
        );
        assert.ok(
            !isNegative(
                moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'quarters')
            ),
            'quarter diff on same date is zero, not -0'
        );
        assert.ok(
            !isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 1]), 'days')),
            'days diff on same date is zero, not -0'
        );
        assert.ok(
            !isNegative(
                moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 1]), 'hours')
            ),
            'hour diff on same hour is zero, not -0'
        );
        assert.ok(
            !isNegative(
                moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 0, 1]), 'minutes')
            ),
            'minute diff on same minute is zero, not -0'
        );
        assert.ok(
            !isNegative(
                moment([2012, 0, 1]).diff(
                    moment([2012, 0, 1, 0, 0, 0, 1]),
                    'seconds'
                )
            ),
            'second diff on same second is zero, not -0'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('duration from moments');

    test('pure year diff', function (assert) {
        var m1 = moment('2012-01-01T00:00:00.000Z'),
            m2 = moment('2013-01-01T00:00:00.000Z');

        assert.equal(
            moment.duration({ from: m1, to: m2 }).as('years'),
            1,
            'year moment difference'
        );
        assert.equal(
            moment.duration({ from: m2, to: m1 }).as('years'),
            -1,
            'negative year moment difference'
        );
    });

    test('month and day diff', function (assert) {
        var m1 = moment('2012-01-15T00:00:00.000Z'),
            m2 = moment('2012-02-17T00:00:00.000Z'),
            d = moment.duration({ from: m1, to: m2 });

        assert.equal(d.get('days'), 2);
        assert.equal(d.get('months'), 1);
    });

    test('day diff, separate months', function (assert) {
        var m1 = moment('2012-01-15T00:00:00.000Z'),
            m2 = moment('2012-02-13T00:00:00.000Z'),
            d = moment.duration({ from: m1, to: m2 });

        assert.equal(d.as('days'), 29);
    });

    test('hour diff', function (assert) {
        var m1 = moment('2012-01-15T17:00:00.000Z'),
            m2 = moment('2012-01-16T03:00:00.000Z'),
            d = moment.duration({ from: m1, to: m2 });

        assert.equal(d.as('hours'), 10);
    });

    test('minute diff', function (assert) {
        var m1 = moment('2012-01-15T17:45:00.000Z'),
            m2 = moment('2012-01-16T03:15:00.000Z'),
            d = moment.duration({ from: m1, to: m2 });

        assert.equal(d.as('hours'), 9.5);
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('invalid');

    test('invalid duration', function (assert) {
        var m = moment.duration.invalid(); // should be invalid
        assert.equal(m.isValid(), false);
        assert.ok(isNaN(m.valueOf()));
    });

    test('valid duration', function (assert) {
        var m = moment.duration({ d: null }); // should be valid, for now
        assert.equal(m.isValid(), true);
        assert.equal(m.valueOf(), 0);
    });

    test('invalid duration - clone of invalid duration', function (assert) {
        var m = moment.duration.invalid().clone(); // should be invalid
        assert.equal(m.isValid(), false);
        assert.ok(isNaN(m.valueOf()));
    });

    test('valid duration - clone of valid duration', function (assert) {
        var m = moment.duration({ d: null }).clone(); // should be valid, for now
        assert.equal(m.isValid(), true);
        assert.equal(m.valueOf(), 0);
    });

    test('invalid duration - wrapper of invalid duration', function (assert) {
        var m = moment.duration(moment.duration.invalid()); // should be invalid
        assert.equal(m.isValid(), false);
        assert.ok(isNaN(m.valueOf()));
    });

    test('valid duration - wrapper of valid duration', function (assert) {
        var m = moment.duration(moment.duration({ d: null })); // should be valid, for now
        assert.equal(m.isValid(), true);
        assert.equal(m.valueOf(), 0);
    });

    test('invalid duration - only smallest unit can have decimal', function (assert) {
        var m = moment.duration({ days: 3.5, hours: 1.1 }); // should be invalid
        assert.equal(m.isValid(), false);
        assert.ok(isNaN(m.valueOf())); // .valueOf() returns NaN for invalid durations
    });

    test('valid duration - smallest unit can have decimal', function (assert) {
        var m = moment.duration({ days: 3, hours: 1.1 }); // should be valid
        assert.equal(m.isValid(), true);
        assert.equal(m.asHours(), 73.1);
    });

    test('invalid duration with two arguments', function (assert) {
        var m = moment.duration(NaN, 'days');
        assert.equal(m.isValid(), false);
        assert.ok(isNaN(m.valueOf()));
    });

    test('invalid duration operations', function (assert) {
        var invalids = [
                moment.duration(NaN),
                moment.duration(NaN, 'days'),
                moment.duration.invalid(),
            ],
            i,
            invalid;

        for (i = 0; i < invalids.length; ++i) {
            invalid = invalids[i];

            assert.ok(
                !invalid.add(5, 'hours').isValid(),
                'invalid.add is invalid; i=' + i
            );
            assert.ok(
                !invalid.subtract(30, 'days').isValid(),
                'invalid.subtract is invalid; i=' + i
            );
            assert.ok(!invalid.abs().isValid(), 'invalid.abs is invalid; i=' + i);
            assert.ok(isNaN(invalid.as('years')), 'invalid.as is NaN; i=' + i);
            assert.ok(
                isNaN(invalid.asMilliseconds()),
                'invalid.asMilliseconds is NaN; i=' + i
            );
            assert.ok(
                isNaN(invalid.asSeconds()),
                'invalid.asSeconds is NaN; i=' + i
            );
            assert.ok(
                isNaN(invalid.asMinutes()),
                'invalid.asMinutes is NaN; i=' + i
            );
            assert.ok(isNaN(invalid.asHours()), 'invalid.asHours is NaN; i=' + i);
            assert.ok(isNaN(invalid.asDays()), 'invalid.asDays is NaN; i=' + i);
            assert.ok(isNaN(invalid.asWeeks()), 'invalid.asWeeks is NaN; i=' + i);
            assert.ok(isNaN(invalid.asMonths()), 'invalid.asMonths is NaN; i=' + i);
            assert.ok(
                isNaN(invalid.asQuarters()),
                'invalid.asQuarters is NaN; i=' + i
            );
            assert.ok(isNaN(invalid.asYears()), 'invalid.asYears is NaN; i=' + i);
            assert.ok(isNaN(invalid.valueOf()), 'invalid.valueOf is NaN; i=' + i);
            assert.ok(isNaN(invalid.get('hours')), 'invalid.get is NaN; i=' + i);

            assert.ok(
                isNaN(invalid.milliseconds()),
                'invalid.milliseconds is NaN; i=' + i
            );
            assert.ok(isNaN(invalid.seconds()), 'invalid.seconds is NaN; i=' + i);
            assert.ok(isNaN(invalid.minutes()), 'invalid.minutes is NaN; i=' + i);
            assert.ok(isNaN(invalid.hours()), 'invalid.hours is NaN; i=' + i);
            assert.ok(isNaN(invalid.days()), 'invalid.days is NaN; i=' + i);
            assert.ok(isNaN(invalid.weeks()), 'invalid.weeks is NaN; i=' + i);
            assert.ok(isNaN(invalid.months()), 'invalid.months is NaN; i=' + i);
            assert.ok(isNaN(invalid.years()), 'invalid.years is NaN; i=' + i);

            assert.equal(
                invalid.humanize(),
                invalid.localeData().invalidDate(),
                'invalid.humanize is localized invalid duration string; i=' + i
            );
            assert.equal(
                invalid.toISOString(),
                invalid.localeData().invalidDate(),
                'invalid.toISOString is localized invalid duration string; i=' + i
            );
            assert.equal(
                invalid.toString(),
                invalid.localeData().invalidDate(),
                'invalid.toString is localized invalid duration string; i=' + i
            );
            assert.equal(
                invalid.toJSON(),
                invalid.localeData().invalidDate(),
                'invalid.toJSON is null; i=' + i
            );
            assert.equal(invalid.locale(), 'en', 'invalid.locale; i=' + i);
            assert.equal(
                invalid.localeData()._abbr,
                'en',
                'invalid.localeData()._abbr; i=' + i
            );
        }
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('duration');

    test('object instantiation', function (assert) {
        var d = moment.duration({
            years: 2,
            months: 3,
            weeks: 2,
            days: 1,
            hours: 8,
            minutes: 9,
            seconds: 20,
            milliseconds: 12,
        });

        assert.equal(d.years(), 2, 'years');
        assert.equal(d.months(), 3, 'months');
        assert.equal(d.weeks(), 2, 'weeks');
        assert.equal(d.days(), 15, 'days'); // two weeks + 1 day
        assert.equal(d.hours(), 8, 'hours');
        assert.equal(d.minutes(), 9, 'minutes');
        assert.equal(d.seconds(), 20, 'seconds');
        assert.equal(d.milliseconds(), 12, 'milliseconds');
    });

    test('object instantiation with strings', function (assert) {
        var d = moment.duration({
            years: '2',
            months: '3',
            weeks: '2',
            days: '1',
            hours: '8',
            minutes: '9',
            seconds: '20',
            milliseconds: '12',
        });

        assert.equal(d.years(), 2, 'years');
        assert.equal(d.months(), 3, 'months');
        assert.equal(d.weeks(), 2, 'weeks');
        assert.equal(d.days(), 15, 'days'); // two weeks + 1 day
        assert.equal(d.hours(), 8, 'hours');
        assert.equal(d.minutes(), 9, 'minutes');
        assert.equal(d.seconds(), 20, 'seconds');
        assert.equal(d.milliseconds(), 12, 'milliseconds');
    });

    test('milliseconds instantiation', function (assert) {
        assert.equal(moment.duration(72).milliseconds(), 72, 'milliseconds');
        assert.equal(
            moment.duration(72).humanize(),
            'a few seconds',
            'Duration should be valid'
        );
    });

    test('milliseconds instantiation with string', function (assert) {
        assert.equal(moment.duration('72').milliseconds(), 72, 'milliseconds');
        assert.equal(
            moment.duration('72').humanize(),
            'a few seconds',
            'Duration should be valid'
        );
    });

    test('undefined instantiation', function (assert) {
        assert.equal(moment.duration(undefined).milliseconds(), 0, 'milliseconds');
        assert.equal(moment.duration(undefined).isValid(), true, '_isValid');
        assert.equal(
            moment.duration(undefined).humanize(),
            'a few seconds',
            'Duration should be valid'
        );
    });

    test('null instantiation', function (assert) {
        assert.equal(moment.duration(null).milliseconds(), 0, 'milliseconds');
        assert.equal(moment.duration(null).isValid(), true, '_isValid');
        assert.equal(
            moment.duration(null).humanize(),
            'a few seconds',
            'Duration should be valid'
        );
    });

    test('NaN instantiation', function (assert) {
        assert.ok(
            isNaN(moment.duration(NaN).milliseconds()),
            'milliseconds should be NaN'
        );
        assert.equal(moment.duration(NaN).isValid(), false, '_isValid');
        assert.equal(
            moment.duration(NaN).humanize(),
            'Invalid date',
            'Duration should be invalid'
        );
    });

    test('instantiation by type', function (assert) {
        assert.equal(moment.duration(1, 'years').years(), 1, 'years');
        assert.equal(moment.duration(1, 'y').years(), 1, 'y');
        assert.equal(moment.duration(2, 'months').months(), 2, 'months');
        assert.equal(moment.duration(2, 'M').months(), 2, 'M');
        assert.equal(moment.duration(3, 'weeks').weeks(), 3, 'weeks');
        assert.equal(moment.duration(3, 'w').weeks(), 3, 'weeks');
        assert.equal(moment.duration(4, 'days').days(), 4, 'days');
        assert.equal(moment.duration(4, 'd').days(), 4, 'd');
        assert.equal(moment.duration(5, 'hours').hours(), 5, 'hours');
        assert.equal(moment.duration(5, 'h').hours(), 5, 'h');
        assert.equal(moment.duration(6, 'minutes').minutes(), 6, 'minutes');
        assert.equal(moment.duration(6, 'm').minutes(), 6, 'm');
        assert.equal(moment.duration(7, 'seconds').seconds(), 7, 'seconds');
        assert.equal(moment.duration(7, 's').seconds(), 7, 's');
        assert.equal(
            moment.duration(8, 'milliseconds').milliseconds(),
            8,
            'milliseconds'
        );
        assert.equal(moment.duration(8, 'ms').milliseconds(), 8, 'ms');
    });

    test('instantiation by type with string', function (assert) {
        assert.equal(moment.duration('1', 'years').years(), 1, 'years');
        assert.equal(moment.duration('1', 'y').years(), 1, 'y');
        assert.equal(moment.duration('2', 'months').months(), 2, 'months');
        assert.equal(moment.duration('2', 'M').months(), 2, 'M');
        assert.equal(moment.duration('3', 'weeks').weeks(), 3, 'weeks');
        assert.equal(moment.duration('3', 'w').weeks(), 3, 'weeks');
        assert.equal(moment.duration('4', 'days').days(), 4, 'days');
        assert.equal(moment.duration('4', 'd').days(), 4, 'd');
        assert.equal(moment.duration('5', 'hours').hours(), 5, 'hours');
        assert.equal(moment.duration('5', 'h').hours(), 5, 'h');
        assert.equal(moment.duration('6', 'minutes').minutes(), 6, 'minutes');
        assert.equal(moment.duration('6', 'm').minutes(), 6, 'm');
        assert.equal(moment.duration('7', 'seconds').seconds(), 7, 'seconds');
        assert.equal(moment.duration('7', 's').seconds(), 7, 's');
        assert.equal(
            moment.duration('8', 'milliseconds').milliseconds(),
            8,
            'milliseconds'
        );
        assert.equal(moment.duration('8', 'ms').milliseconds(), 8, 'ms');
    });

    test('shortcuts', function (assert) {
        assert.equal(moment.duration({ y: 1 }).years(), 1, 'years = y');
        assert.equal(moment.duration({ M: 2 }).months(), 2, 'months = M');
        assert.equal(moment.duration({ w: 3 }).weeks(), 3, 'weeks = w');
        assert.equal(moment.duration({ d: 4 }).days(), 4, 'days = d');
        assert.equal(moment.duration({ h: 5 }).hours(), 5, 'hours = h');
        assert.equal(moment.duration({ m: 6 }).minutes(), 6, 'minutes = m');
        assert.equal(moment.duration({ s: 7 }).seconds(), 7, 'seconds = s');
        assert.equal(
            moment.duration({ ms: 8 }).milliseconds(),
            8,
            'milliseconds = ms'
        );
    });

    test('generic getter', function (assert) {
        assert.equal(moment.duration(1, 'years').get('years'), 1, 'years');
        assert.equal(moment.duration(1, 'years').get('year'), 1, 'years = year');
        assert.equal(moment.duration(1, 'years').get('y'), 1, 'years = y');
        assert.equal(moment.duration(2, 'months').get('months'), 2, 'months');
        assert.equal(
            moment.duration(2, 'months').get('month'),
            2,
            'months = month'
        );
        assert.equal(moment.duration(2, 'months').get('M'), 2, 'months = M');
        assert.equal(moment.duration(3, 'weeks').get('weeks'), 3, 'weeks');
        assert.equal(moment.duration(3, 'weeks').get('week'), 3, 'weeks = week');
        assert.equal(moment.duration(3, 'weeks').get('w'), 3, 'weeks = w');
        assert.equal(moment.duration(4, 'days').get('days'), 4, 'days');
        assert.equal(moment.duration(4, 'days').get('day'), 4, 'days = day');
        assert.equal(moment.duration(4, 'days').get('d'), 4, 'days = d');
        assert.equal(moment.duration(5, 'hours').get('hours'), 5, 'hours');
        assert.equal(moment.duration(5, 'hours').get('hour'), 5, 'hours = hour');
        assert.equal(moment.duration(5, 'hours').get('h'), 5, 'hours = h');
        assert.equal(moment.duration(6, 'minutes').get('minutes'), 6, 'minutes');
        assert.equal(
            moment.duration(6, 'minutes').get('minute'),
            6,
            'minutes = minute'
        );
        assert.equal(moment.duration(6, 'minutes').get('m'), 6, 'minutes = m');
        assert.equal(moment.duration(7, 'seconds').get('seconds'), 7, 'seconds');
        assert.equal(
            moment.duration(7, 'seconds').get('second'),
            7,
            'seconds = second'
        );
        assert.equal(moment.duration(7, 'seconds').get('s'), 7, 'seconds = s');
        assert.equal(
            moment.duration(8, 'milliseconds').get('milliseconds'),
            8,
            'milliseconds'
        );
        assert.equal(
            moment.duration(8, 'milliseconds').get('millisecond'),
            8,
            'milliseconds = millisecond'
        );
        assert.equal(
            moment.duration(8, 'milliseconds').get('ms'),
            8,
            'milliseconds = ms'
        );
    });

    test('instantiation from another duration', function (assert) {
        var simple = moment.duration(1234),
            lengthy = moment.duration(60 * 60 * 24 * 360 * 1e3),
            complicated = moment.duration({
                years: 2,
                months: 3,
                weeks: 4,
                days: 1,
                hours: 8,
                minutes: 9,
                seconds: 20,
                milliseconds: 12,
            }),
            modified = moment.duration(1, 'day').add(moment.duration(1, 'day'));

        assert.deepEqual(
            moment.duration(simple),
            simple,
            'simple clones are equal'
        );
        assert.deepEqual(
            moment.duration(lengthy),
            lengthy,
            'lengthy clones are equal'
        );
        assert.deepEqual(
            moment.duration(complicated),
            complicated,
            'complicated clones are equal'
        );
        assert.deepEqual(
            moment.duration(modified),
            modified,
            'cloning modified duration works'
        );
    });

    test('explicit cloning', function (assert) {
        var durationA = moment.duration(5, 'milliseconds'),
            durationB = durationA.clone();
        durationA.add(5, 'milliseconds');
        assert.notEqual(
            durationA.milliseconds(),
            durationB.milliseconds(),
            'Calling duration.clone() on a duration will create a clone'
        );
    });

    test('instantiation from 24-hour time zero', function (assert) {
        assert.equal(moment.duration('00:00').years(), 0, '0 years');
        assert.equal(moment.duration('00:00').days(), 0, '0 days');
        assert.equal(moment.duration('00:00').hours(), 0, '0 hours');
        assert.equal(moment.duration('00:00').minutes(), 0, '0 minutes');
        assert.equal(moment.duration('00:00').seconds(), 0, '0 seconds');
        assert.equal(moment.duration('00:00').milliseconds(), 0, '0 milliseconds');
    });

    test('instantiation from 24-hour time <24 hours', function (assert) {
        assert.equal(moment.duration('06:45').years(), 0, '0 years');
        assert.equal(moment.duration('06:45').days(), 0, '0 days');
        assert.equal(moment.duration('06:45').hours(), 6, '6 hours');
        assert.equal(moment.duration('06:45').minutes(), 45, '45 minutes');
        assert.equal(moment.duration('06:45').seconds(), 0, '0 seconds');
        assert.equal(moment.duration('06:45').milliseconds(), 0, '0 milliseconds');
    });

    test('instantiation from 24-hour time >24 hours', function (assert) {
        assert.equal(moment.duration('26:45').years(), 0, '0 years');
        assert.equal(moment.duration('26:45').days(), 1, '0 days');
        assert.equal(moment.duration('26:45').hours(), 2, '2 hours');
        assert.equal(moment.duration('26:45').minutes(), 45, '45 minutes');
        assert.equal(moment.duration('26:45').seconds(), 0, '0 seconds');
        assert.equal(moment.duration('26:45').milliseconds(), 0, '0 milliseconds');
    });

    test('instantiation from serialized C# TimeSpan zero', function (assert) {
        assert.equal(moment.duration('00:00:00').years(), 0, '0 years');
        assert.equal(moment.duration('00:00:00').days(), 0, '0 days');
        assert.equal(moment.duration('00:00:00').hours(), 0, '0 hours');
        assert.equal(moment.duration('00:00:00').minutes(), 0, '0 minutes');
        assert.equal(moment.duration('00:00:00').seconds(), 0, '0 seconds');
        assert.equal(
            moment.duration('00:00:00').milliseconds(),
            0,
            '0 milliseconds'
        );
    });

    test('instantiation from serialized C# TimeSpan with days', function (assert) {
        assert.equal(moment.duration('1.02:03:04.9999999').years(), 0, '0 years');
        assert.equal(moment.duration('1.02:03:04.9999999').days(), 1, '1 day');
        assert.equal(moment.duration('1.02:03:04.9999999').hours(), 2, '2 hours');
        assert.equal(
            moment.duration('1.02:03:04.9999999').minutes(),
            3,
            '3 minutes'
        );
        assert.equal(
            moment.duration('1.02:03:04.9999999').seconds(),
            5,
            '5 seconds'
        );
        assert.equal(
            moment.duration('1.02:03:04.9999999').milliseconds(),
            0,
            '0 milliseconds'
        );

        assert.equal(moment.duration('1 02:03:04.9999999').years(), 0, '0 years');
        assert.equal(moment.duration('1 02:03:04.9999999').days(), 1, '1 day');
        assert.equal(moment.duration('1 02:03:04.9999999').hours(), 2, '2 hours');
        assert.equal(
            moment.duration('1 02:03:04.9999999').minutes(),
            3,
            '3 minutes'
        );
        assert.equal(
            moment.duration('1 02:03:04.9999999').seconds(),
            5,
            '5 seconds'
        );
        assert.equal(
            moment.duration('1 02:03:04.9999999').milliseconds(),
            0,
            '0 milliseconds'
        );
    });

    test('instantiation from serialized C# TimeSpan without days', function (assert) {
        assert.equal(moment.duration('01:02:03.9999999').years(), 0, '0 years');
        assert.equal(moment.duration('01:02:03.9999999').days(), 0, '0 days');
        assert.equal(moment.duration('01:02:03.9999999').hours(), 1, '1 hour');
        assert.equal(moment.duration('01:02:03.9999999').minutes(), 2, '2 minutes');
        assert.equal(moment.duration('01:02:03.9999999').seconds(), 4, '4 seconds');
        assert.equal(
            moment.duration('01:02:03.9999999').milliseconds(),
            0,
            '0 milliseconds'
        );

        assert.equal(moment.duration('23:59:59.9999999').days(), 1, '1 days');
        assert.equal(moment.duration('23:59:59.9999999').hours(), 0, '0 hours');
        assert.equal(moment.duration('23:59:59.9999999').minutes(), 0, '0 minutes');
        assert.equal(moment.duration('23:59:59.9999999').seconds(), 0, '0 seconds');
        assert.equal(
            moment.duration('23:59:59.9999999').milliseconds(),
            0,
            '0 milliseconds'
        );

        assert.equal(
            moment.duration('500:59:59.8888888').days(),
            20,
            '500 hours overflows to 20 days'
        );
        assert.equal(
            moment.duration('500:59:59.8888888').hours(),
            20,
            '500 hours overflows to 20 hours'
        );
    });

    test('instantiation from serialized C# TimeSpan without days or milliseconds', function (assert) {
        assert.equal(moment.duration('01:02:03').years(), 0, '0 years');
        assert.equal(moment.duration('01:02:03').days(), 0, '0 days');
        assert.equal(moment.duration('01:02:03').hours(), 1, '1 hour');
        assert.equal(moment.duration('01:02:03').minutes(), 2, '2 minutes');
        assert.equal(moment.duration('01:02:03').seconds(), 3, '3 seconds');
        assert.equal(
            moment.duration('01:02:03').milliseconds(),
            0,
            '0 milliseconds'
        );
    });

    test('instantiation from serialized C# TimeSpan without milliseconds', function (assert) {
        assert.equal(moment.duration('1.02:03:04').years(), 0, '0 years');
        assert.equal(moment.duration('1.02:03:04').days(), 1, '1 day');
        assert.equal(moment.duration('1.02:03:04').hours(), 2, '2 hours');
        assert.equal(moment.duration('1.02:03:04').minutes(), 3, '3 minutes');
        assert.equal(moment.duration('1.02:03:04').seconds(), 4, '4 seconds');
        assert.equal(
            moment.duration('1.02:03:04').milliseconds(),
            0,
            '0 milliseconds'
        );
    });

    test('instantiation from serialized C# TimeSpan with low millisecond precision', function (assert) {
        assert.equal(moment.duration('00:00:15.72').years(), 0, '0 years');
        assert.equal(moment.duration('00:00:15.72').days(), 0, '0 days');
        assert.equal(moment.duration('00:00:15.72').hours(), 0, '0 hours');
        assert.equal(moment.duration('00:00:15.72').minutes(), 0, '0 minutes');
        assert.equal(moment.duration('00:00:15.72').seconds(), 15, '15 seconds');
        assert.equal(
            moment.duration('00:00:15.72').milliseconds(),
            720,
            '720 milliseconds'
        );

        assert.equal(
            moment.duration('00:00:15.7').milliseconds(),
            700,
            '700 milliseconds'
        );

        assert.equal(
            moment.duration('00:00:15.').milliseconds(),
            0,
            '0 milliseconds'
        );
    });

    test('instantiation from serialized C# TimeSpan with high millisecond precision', function (assert) {
        assert.equal(
            moment.duration('00:00:15.7200000').seconds(),
            15,
            '15 seconds'
        );
        assert.equal(
            moment.duration('00:00:15.7200000').milliseconds(),
            720,
            '720 milliseconds'
        );

        assert.equal(
            moment.duration('00:00:15.7209999').seconds(),
            15,
            '15 seconds'
        );
        assert.equal(
            moment.duration('00:00:15.7209999').milliseconds(),
            721,
            '721 milliseconds'
        );

        assert.equal(
            moment.duration('00:00:15.7205000').seconds(),
            15,
            '15 seconds'
        );
        assert.equal(
            moment.duration('00:00:15.7205000').milliseconds(),
            721,
            '721 milliseconds'
        );

        assert.equal(
            moment.duration('-00:00:15.7205000').seconds(),
            -15,
            '15 seconds'
        );
        assert.equal(
            moment.duration('-00:00:15.7205000').milliseconds(),
            -721,
            '721 milliseconds'
        );

        assert.equal(
            moment.duration('+00:00:15.7205000').seconds(),
            15,
            '15 seconds'
        );
        assert.equal(
            moment.duration('+00:00:15.7205000').milliseconds(),
            721,
            '721 milliseconds'
        );
    });

    test('instantiation from serialized C# TimeSpan maxValue', function (assert) {
        var d = moment.duration('10675199.02:48:05.4775807');

        assert.equal(d.years(), 29227, '29227 years');
        assert.equal(d.months(), 8, '8 months');
        assert.equal(d.days(), 12, '12 day'); // if you have to change this value -- just do it

        assert.equal(d.hours(), 2, '2 hours');
        assert.equal(d.minutes(), 48, '48 minutes');
        assert.equal(d.seconds(), 5, '5 seconds');
        assert.equal(d.milliseconds(), 478, '478 milliseconds');
    });

    test('instantiation from serialized C# TimeSpan minValue', function (assert) {
        var d = moment.duration('-10675199.02:48:05.4775808');

        assert.equal(d.years(), -29227, '29653 years');
        assert.equal(d.months(), -8, '8 day');
        assert.equal(d.days(), -12, '12 day'); // if you have to change this value -- just do it

        assert.equal(d.hours(), -2, '2 hours');
        assert.equal(d.minutes(), -48, '48 minutes');
        assert.equal(d.seconds(), -5, '5 seconds');
        assert.equal(d.milliseconds(), -478, '478 milliseconds');
    });

    test('instantiation from serialized C# TimeSpan maxValue with + sign', function (assert) {
        var d = moment.duration('+10675199.02:48:05.4775808');

        assert.equal(d.years(), 29227, '29653 years');
        assert.equal(d.months(), 8, '8 day');
        assert.equal(d.days(), 12, '12 day'); // if you have to change this value -- just do it

        assert.equal(d.hours(), 2, '2 hours');
        assert.equal(d.minutes(), 48, '48 minutes');
        assert.equal(d.seconds(), 5, '5 seconds');
        assert.equal(d.milliseconds(), 478, '478 milliseconds');
    });

    test('instantiation from ISO 8601 duration', function (assert) {
        assert.equal(
            moment.duration('P1Y2M3DT4H5M6S').asSeconds(),
            moment.duration({ y: 1, M: 2, d: 3, h: 4, m: 5, s: 6 }).asSeconds(),
            'all fields'
        );
        assert.equal(
            moment.duration('P3W3D').asSeconds(),
            moment.duration({ w: 3, d: 3 }).asSeconds(),
            'week and day fields'
        );
        assert.equal(
            moment.duration('P1M').asSeconds(),
            moment.duration({ M: 1 }).asSeconds(),
            'single month field'
        );
        assert.equal(
            moment.duration('PT1M').asSeconds(),
            moment.duration({ m: 1 }).asSeconds(),
            'single minute field'
        );
        assert.equal(
            moment.duration('P1MT2H').asSeconds(),
            moment.duration({ M: 1, h: 2 }).asSeconds(),
            'random fields missing'
        );
        assert.equal(
            moment.duration('-P60D').asSeconds(),
            moment.duration({ d: -60 }).asSeconds(),
            'negative days'
        );
        assert.equal(
            moment.duration('+P60D').asSeconds(),
            moment.duration({ d: 60 }).asSeconds(),
            'positive days'
        );
        assert.equal(
            moment.duration('PT0.5S').asSeconds(),
            moment.duration({ s: 0.5 }).asSeconds(),
            'fractional seconds'
        );
        assert.equal(
            moment.duration('PT0,5S').asSeconds(),
            moment.duration({ s: 0.5 }).asSeconds(),
            'fractional seconds (comma)'
        );
    });

    test('serialization to ISO 8601 duration strings', function (assert) {
        assert.equal(
            moment.duration({ y: 1, M: 2, d: 3, h: 4, m: 5, s: 6 }).toISOString(),
            'P1Y2M3DT4H5M6S',
            'all fields'
        );
        assert.equal(
            moment.duration({ M: -1 }).toISOString(),
            '-P1M',
            'one month ago'
        );
        assert.equal(
            moment.duration({ m: -1 }).toISOString(),
            '-PT1M',
            'one minute ago'
        );
        assert.equal(
            moment.duration({ s: -0.5 }).toISOString(),
            '-PT0.5S',
            'one half second ago'
        );
        assert.equal(
            moment.duration({ y: -1, M: 1 }).toISOString(),
            '-P11M',
            'a month after a year ago'
        );
        assert.equal(
            moment.duration({ y: -1, h: 1 }).toISOString(),
            '-P1YT-1H',
            'an hour after a year ago'
        );
        assert.equal(
            moment.duration({ y: -1, h: 1, m: -1 }).toISOString(),
            '-P1YT-59M',
            '59 minutes after a year ago'
        );
        assert.equal(
            moment.duration({ y: -1, h: 1, s: -1 }).toISOString(),
            '-P1YT-59M-59S',
            '59 minutes 59 seconds after a year ago'
        );
        assert.equal(
            moment.duration({ y: -1, h: -1, s: 1 }).toISOString(),
            '-P1YT59M59S',
            '59 minutes 59 seconds after a year ago'
        );
        assert.equal(
            moment.duration({ y: -1, d: 2 }).toISOString(),
            '-P1Y-2D',
            '1 year less 2 days ago'
        );
        assert.equal(
            moment.duration({ M: +1 }).toISOString(),
            'P1M',
            'one month ago'
        );
        assert.equal(
            moment.duration({ m: +1 }).toISOString(),
            'PT1M',
            'one minute ago'
        );
        assert.equal(
            moment.duration({ s: +0.5 }).toISOString(),
            'PT0.5S',
            'one half second ago'
        );
        assert.equal(
            moment.duration({ y: +1, M: 1 }).toISOString(),
            'P1Y1M',
            'a month after a year in future'
        );
        assert.equal(
            moment.duration({ y: -1, h: 1 }).toISOString(),
            '-P1YT-1H',
            'an hour after a year ago'
        );
        assert.equal(moment.duration({}).toISOString(), 'P0D', 'zero duration');
        assert.equal(
            moment.duration({ M: 16, d: 40, s: 86465 }).toISOString(),
            'P1Y4M40DT24H1M5S',
            'all fields'
        );
        assert.equal(
            moment.duration({ ms: 123456789 }).toISOString(),
            'PT34H17M36.789S',
            'check floating-point errors'
        );
        assert.equal(
            moment.duration({ ms: 31952 }).toISOString(),
            'PT31.952S',
            'check floating-point errors'
        );
    });

    test('toString acts as toISOString', function (assert) {
        assert.equal(
            moment.duration({ y: 1, M: 2, d: 3, h: 4, m: 5, s: 6 }).toString(),
            'P1Y2M3DT4H5M6S',
            'all fields'
        );
        assert.equal(
            moment.duration({ M: -1 }).toString(),
            '-P1M',
            'one month ago'
        );
        assert.equal(
            moment.duration({ m: -1 }).toString(),
            '-PT1M',
            'one minute ago'
        );
        assert.equal(
            moment.duration({ s: -0.5 }).toString(),
            '-PT0.5S',
            'one half second ago'
        );
        assert.equal(
            moment.duration({ y: -1, M: 1 }).toString(),
            '-P11M',
            'a month after a year ago'
        );
        assert.equal(moment.duration({ M: +1 }).toString(), 'P1M', 'one month ago');
        assert.equal(
            moment.duration({ m: +1 }).toString(),
            'PT1M',
            'one minute ago'
        );
        assert.equal(
            moment.duration({ s: +0.5 }).toString(),
            'PT0.5S',
            'one half second ago'
        );
        assert.equal(
            moment.duration({ y: +1, M: 1 }).toString(),
            'P1Y1M',
            'a month after a year in future'
        );
        assert.equal(moment.duration({}).toString(), 'P0D', 'zero duration');
        assert.equal(
            moment.duration({ M: 16, d: 40, s: 86465 }).toString(),
            'P1Y4M40DT24H1M5S',
            'all fields'
        );
    });

    test('toIsoString deprecation', function (assert) {
        test.expectedDeprecations('toIsoString()');

        assert.equal(
            moment.duration({}).toIsoString(),
            moment.duration({}).toISOString(),
            'toIsoString delegates to toISOString'
        );
    });

    test('`isodate` (python) test cases', function (assert) {
        assert.equal(
            moment.duration('P18Y9M4DT11H9M8S').asSeconds(),
            moment.duration({ y: 18, M: 9, d: 4, h: 11, m: 9, s: 8 }).asSeconds(),
            'python isodate 1'
        );
        assert.equal(
            moment.duration('P2W').asSeconds(),
            moment.duration({ w: 2 }).asSeconds(),
            'python isodate 2'
        );
        assert.equal(
            moment.duration('P3Y6M4DT12H30M5S').asSeconds(),
            moment.duration({ y: 3, M: 6, d: 4, h: 12, m: 30, s: 5 }).asSeconds(),
            'python isodate 3'
        );
        assert.equal(
            moment.duration('P23DT23H').asSeconds(),
            moment.duration({ d: 23, h: 23 }).asSeconds(),
            'python isodate 4'
        );
        assert.equal(
            moment.duration('P4Y').asSeconds(),
            moment.duration({ y: 4 }).asSeconds(),
            'python isodate 5'
        );
        assert.equal(
            moment.duration('P1M').asSeconds(),
            moment.duration({ M: 1 }).asSeconds(),
            'python isodate 6'
        );
        assert.equal(
            moment.duration('PT1M').asSeconds(),
            moment.duration({ m: 1 }).asSeconds(),
            'python isodate 7'
        );
        assert.equal(
            moment.duration('P0.5Y').asSeconds(),
            moment.duration({ y: 0.5 }).asSeconds(),
            'python isodate 8'
        );
        assert.equal(
            moment.duration('PT36H').asSeconds(),
            moment.duration({ h: 36 }).asSeconds(),
            'python isodate 9'
        );
        assert.equal(
            moment.duration('P1DT12H').asSeconds(),
            moment.duration({ d: 1, h: 12 }).asSeconds(),
            'python isodate 10'
        );
        assert.equal(
            moment.duration('-P2W').asSeconds(),
            moment.duration({ w: -2 }).asSeconds(),
            'python isodate 11'
        );
        assert.equal(
            moment.duration('-P2.2W').asSeconds(),
            moment.duration({ w: -2.2 }).asSeconds(),
            'python isodate 12'
        );
        assert.equal(
            moment.duration('+P2W').asSeconds(),
            moment.duration({ w: 2 }).asSeconds(),
            'python isodate 11'
        );
        assert.equal(
            moment.duration('+P2.2W').asSeconds(),
            moment.duration({ w: 2.2 }).asSeconds(),
            'python isodate 12'
        );
        assert.equal(
            moment.duration('P1DT2H3M4S').asSeconds(),
            moment.duration({ d: 1, h: 2, m: 3, s: 4 }).asSeconds(),
            'python isodate 13'
        );
        assert.equal(
            moment.duration('P1DT2H3M').asSeconds(),
            moment.duration({ d: 1, h: 2, m: 3 }).asSeconds(),
            'python isodate 14'
        );
        assert.equal(
            moment.duration('P1DT2H').asSeconds(),
            moment.duration({ d: 1, h: 2 }).asSeconds(),
            'python isodate 15'
        );
        assert.equal(
            moment.duration('PT2H').asSeconds(),
            moment.duration({ h: 2 }).asSeconds(),
            'python isodate 16'
        );
        assert.equal(
            moment.duration('PT2.3H').asSeconds(),
            moment.duration({ h: 2.3 }).asSeconds(),
            'python isodate 17'
        );
        assert.equal(
            moment.duration('PT2H3M4S').asSeconds(),
            moment.duration({ h: 2, m: 3, s: 4 }).asSeconds(),
            'python isodate 18'
        );
        assert.equal(
            moment.duration('PT3M4S').asSeconds(),
            moment.duration({ m: 3, s: 4 }).asSeconds(),
            'python isodate 19'
        );
        assert.equal(
            moment.duration('PT22S').asSeconds(),
            moment.duration({ s: 22 }).asSeconds(),
            'python isodate 20'
        );
        assert.equal(
            moment.duration('PT22.22S').asSeconds(),
            moment.duration({ s: 22.22 }).asSeconds(),
            'python isodate 21'
        );
        assert.equal(
            moment.duration('-P2Y').asSeconds(),
            moment.duration({ y: -2 }).asSeconds(),
            'python isodate 22'
        );
        assert.equal(
            moment.duration('-P3Y6M4DT12H30M5S').asSeconds(),
            moment
                .duration({ y: -3, M: -6, d: -4, h: -12, m: -30, s: -5 })
                .asSeconds(),
            'python isodate 23'
        );
        assert.equal(
            moment.duration('-P1DT2H3M4S').asSeconds(),
            moment.duration({ d: -1, h: -2, m: -3, s: -4 }).asSeconds(),
            'python isodate 24'
        );
        assert.equal(
            moment.duration('PT-6H3M').asSeconds(),
            moment.duration({ h: -6, m: 3 }).asSeconds(),
            'python isodate 25'
        );
        assert.equal(
            moment.duration('-PT-6H3M').asSeconds(),
            moment.duration({ h: 6, m: -3 }).asSeconds(),
            'python isodate 26'
        );
        assert.equal(
            moment.duration('-P-3Y-6M-4DT-12H-30M-5S').asSeconds(),
            moment.duration({ y: 3, M: 6, d: 4, h: 12, m: 30, s: 5 }).asSeconds(),
            'python isodate 27'
        );
        assert.equal(
            moment.duration('P-3Y-6M-4DT-12H-30M-5S').asSeconds(),
            moment
                .duration({ y: -3, M: -6, d: -4, h: -12, m: -30, s: -5 })
                .asSeconds(),
            'python isodate 28'
        );
        assert.equal(
            moment.duration('-P-2W').asSeconds(),
            moment.duration({ w: 2 }).asSeconds(),
            'python isodate 29'
        );
        assert.equal(
            moment.duration('P-2W').asSeconds(),
            moment.duration({ w: -2 }).asSeconds(),
            'python isodate 30'
        );
        assert.equal(
            moment.duration('+P2Y').asSeconds(),
            moment.duration({ y: 2 }).asSeconds(),
            'python isodate 31'
        );
        assert.equal(
            moment.duration('+P3Y6M4DT12H30M5S').asSeconds(),
            moment.duration({ y: 3, M: 6, d: 4, h: 12, m: 30, s: 5 }).asSeconds(),
            'python isodate 32'
        );
        assert.equal(
            moment.duration('+P1DT2H3M4S').asSeconds(),
            moment.duration({ d: 1, h: 2, m: 3, s: 4 }).asSeconds(),
            'python isodate 34'
        );
        assert.equal(
            moment.duration('PT+6H3M').asSeconds(),
            moment.duration({ h: 6, m: 3 }).asSeconds(),
            'python isodate 35'
        );
        assert.equal(
            moment.duration('+PT+6H3M').asSeconds(),
            moment.duration({ h: 6, m: 3 }).asSeconds(),
            'python isodate 36'
        );
        assert.equal(
            moment.duration('+PT-6H3M').asSeconds(),
            moment.duration({ h: -6, m: 3 }).asSeconds(),
            'python isodate 37'
        );
        assert.equal(
            moment.duration('+P+3Y+6M+4DT+12H+30M+5S').asSeconds(),
            moment.duration({ y: 3, M: 6, d: 4, h: 12, m: 30, s: 5 }).asSeconds(),
            'python isodate 38'
        );
        assert.equal(
            moment.duration('+P-3Y-6M-4DT-12H-30M-5S').asSeconds(),
            moment
                .duration({ y: -3, M: -6, d: -4, h: -12, m: -30, s: -5 })
                .asSeconds(),
            'python isodate 39'
        );
        assert.equal(
            moment.duration('P+3Y+6M+4DT+12H+30M+5S').asSeconds(),
            moment.duration({ y: 3, M: 6, d: 4, h: 12, m: 30, s: 5 }).asSeconds(),
            'python isodate 40'
        );
        assert.equal(
            moment.duration('+P+2W').asSeconds(),
            moment.duration({ w: 2 }).asSeconds(),
            'python isodate 41'
        );
        assert.equal(
            moment.duration('+P-2W').asSeconds(),
            moment.duration({ w: -2 }).asSeconds(),
            'python isodate 41'
        );
        assert.equal(
            moment.duration('P+2W').asSeconds(),
            moment.duration({ w: 2 }).asSeconds(),
            'python isodate 43'
        );
    });

    test('ISO 8601 misuse cases', function (assert) {
        assert.equal(moment.duration('P').asSeconds(), 0, 'lonely P');
        assert.equal(moment.duration('PT').asSeconds(), 0, 'just P and T');
        assert.equal(moment.duration('P1H').asSeconds(), 0, 'missing T');
        assert.equal(moment.duration('P1D1Y').asSeconds(), 0, 'out of order');
        assert.equal(
            moment.duration('PT.5S').asSeconds(),
            0.5,
            'accept no leading zero for decimal'
        );
        assert.equal(
            moment.duration('PT1,S').asSeconds(),
            1,
            'accept trailing decimal separator'
        );
        assert.equal(
            moment.duration('PT1M0,,5S').asSeconds(),
            60,
            'extra decimal separators are ignored as 0'
        );
    });

    test('humanize', function (assert) {
        moment.locale('en');
        assert.equal(
            moment.duration({ seconds: 44 }).humanize(),
            'a few seconds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            moment.duration({ seconds: 45 }).humanize(),
            'a minute',
            '45 seconds = a minute'
        );
        assert.equal(
            moment.duration({ seconds: 89 }).humanize(),
            'a minute',
            '89 seconds = a minute'
        );
        assert.equal(
            moment.duration({ seconds: 90 }).humanize(),
            '2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            moment.duration({ minutes: 44 }).humanize(),
            '44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            moment.duration({ minutes: 45 }).humanize(),
            'an hour',
            '45 minutes = an hour'
        );
        assert.equal(
            moment.duration({ minutes: 89 }).humanize(),
            'an hour',
            '89 minutes = an hour'
        );
        assert.equal(
            moment.duration({ minutes: 90 }).humanize(),
            '2 hours',
            '90 minutes = 2 hours'
        );
        assert.equal(
            moment.duration({ hours: 5 }).humanize(),
            '5 hours',
            '5 hours = 5 hours'
        );
        assert.equal(
            moment.duration({ hours: 21 }).humanize(),
            '21 hours',
            '21 hours = 21 hours'
        );
        assert.equal(
            moment.duration({ hours: 22 }).humanize(),
            'a day',
            '22 hours = a day'
        );
        assert.equal(
            moment.duration({ hours: 35 }).humanize(),
            'a day',
            '35 hours = a day'
        );
        assert.equal(
            moment.duration({ hours: 36 }).humanize(),
            '2 days',
            '36 hours = 2 days'
        );
        assert.equal(
            moment.duration({ days: 1 }).humanize(),
            'a day',
            '1 day = a day'
        );
        assert.equal(
            moment.duration({ days: 5 }).humanize(),
            '5 days',
            '5 days = 5 days'
        );
        assert.equal(
            moment.duration({ weeks: 1 }).humanize(),
            '7 days',
            '1 week = 7 days'
        );
        assert.equal(
            moment.duration({ days: 25 }).humanize(),
            '25 days',
            '25 days = 25 days'
        );
        assert.equal(
            moment.duration({ days: 26 }).humanize(),
            'a month',
            '26 days = a month'
        );
        assert.equal(
            moment.duration({ days: 30 }).humanize(),
            'a month',
            '30 days = a month'
        );
        assert.equal(
            moment.duration({ days: 45 }).humanize(),
            'a month',
            '45 days = a month'
        );
        assert.equal(
            moment.duration({ days: 46 }).humanize(),
            '2 months',
            '46 days = 2 months'
        );
        assert.equal(
            moment.duration({ days: 74 }).humanize(),
            '2 months',
            '74 days = 2 months'
        );
        assert.equal(
            moment.duration({ days: 77 }).humanize(),
            '3 months',
            '77 days = 3 months'
        );
        assert.equal(
            moment.duration({ months: 1 }).humanize(),
            'a month',
            '1 month = a month'
        );
        assert.equal(
            moment.duration({ months: 5 }).humanize(),
            '5 months',
            '5 months = 5 months'
        );
        assert.equal(
            moment.duration({ days: 344 }).humanize(),
            'a year',
            '344 days = a year'
        );
        assert.equal(
            moment.duration({ days: 345 }).humanize(),
            'a year',
            '345 days = a year'
        );
        assert.equal(
            moment.duration({ days: 547 }).humanize(),
            'a year',
            '547 days = a year'
        );
        assert.equal(
            moment.duration({ days: 548 }).humanize(),
            '2 years',
            '548 days = 2 years'
        );
        assert.equal(
            moment.duration({ years: 1 }).humanize(),
            'a year',
            '1 year = a year'
        );
        assert.equal(
            moment.duration({ years: 5 }).humanize(),
            '5 years',
            '5 years = 5 years'
        );
        assert.equal(
            moment.duration(7200000).humanize(),
            '2 hours',
            '7200000 = 2 hours'
        );
    });

    test('humanize duration with suffix', function (assert) {
        moment.locale('en');
        assert.equal(
            moment.duration({ seconds: 44 }).humanize(true),
            'in a few seconds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            moment.duration({ seconds: -44 }).humanize(true),
            'a few seconds ago',
            '44 seconds = a few seconds'
        );
        assert.equal(
            moment.duration({ seconds: +44 }).humanize(true),
            'in a few seconds',
            '44 seconds = a few seconds'
        );
    });

    test('humanize duration with thresholds', function (assert) {
        var thresholds = { s: 9 };
        moment.locale('en');
        assert.equal(
            moment.duration({ seconds: -10 }).humanize(thresholds),
            'a minute',
            '10 seconds = a minute (with thresholds)'
        );
        assert.equal(
            moment.duration({ seconds: 10 }).humanize(true, thresholds),
            'in a minute',
            '10 seconds = a minute (with thresholds and suffix)'
        );
        assert.equal(
            moment.duration({ weeks: 3 }).humanize(true, { d: 7, w: 4 }),
            'in 3 weeks',
            'in 3 weeks = in 3 weeks (with thresholds and suffix)'
        );
        assert.equal(
            moment.duration({ weeks: 3 }).humanize(false, { d: 7, w: 4 }),
            '3 weeks',
            '3 weeks = 3 weeks (with thresholds and suffix == false)'
        );
    });

    test('bubble value up', function (assert) {
        assert.equal(
            moment.duration({ milliseconds: 61001 }).milliseconds(),
            1,
            '61001 milliseconds has 1 millisecond left over'
        );
        assert.equal(
            moment.duration({ milliseconds: 61001 }).seconds(),
            1,
            '61001 milliseconds has 1 second left over'
        );
        assert.equal(
            moment.duration({ milliseconds: 61001 }).minutes(),
            1,
            '61001 milliseconds has 1 minute left over'
        );

        assert.equal(
            moment.duration({ minutes: 350 }).minutes(),
            50,
            '350 minutes has 50 minutes left over'
        );
        assert.equal(
            moment.duration({ minutes: 350 }).hours(),
            5,
            '350 minutes has 5 hours left over'
        );
    });

    test('clipping', function (assert) {
        assert.equal(
            moment.duration({ months: 11 }).months(),
            11,
            '11 months is 11 months'
        );
        assert.equal(
            moment.duration({ months: 11 }).years(),
            0,
            '11 months makes no year'
        );
        assert.equal(
            moment.duration({ months: 12 }).months(),
            0,
            '12 months is 0 months left over'
        );
        assert.equal(
            moment.duration({ months: 12 }).years(),
            1,
            '12 months makes 1 year'
        );
        assert.equal(
            moment.duration({ months: 13 }).months(),
            1,
            '13 months is 1 month left over'
        );
        assert.equal(
            moment.duration({ months: 13 }).years(),
            1,
            '13 months makes 1 year'
        );

        assert.equal(
            moment.duration({ days: 30 }).days(),
            30,
            '30 days is 30 days'
        );
        assert.equal(
            moment.duration({ days: 30 }).months(),
            0,
            '30 days makes no month'
        );
        assert.equal(
            moment.duration({ days: 31 }).days(),
            0,
            '31 days is 0 days left over'
        );
        assert.equal(
            moment.duration({ days: 31 }).months(),
            1,
            '31 days is a month'
        );
        assert.equal(
            moment.duration({ days: 32 }).days(),
            1,
            '32 days is 1 day left over'
        );
        assert.equal(
            moment.duration({ days: 32 }).months(),
            1,
            '32 days is a month'
        );

        assert.equal(
            moment.duration({ hours: 23 }).hours(),
            23,
            '23 hours is 23 hours'
        );
        assert.equal(
            moment.duration({ hours: 23 }).days(),
            0,
            '23 hours makes no day'
        );
        assert.equal(
            moment.duration({ hours: 24 }).hours(),
            0,
            '24 hours is 0 hours left over'
        );
        assert.equal(
            moment.duration({ hours: 24 }).days(),
            1,
            '24 hours makes 1 day'
        );
        assert.equal(
            moment.duration({ hours: 25 }).hours(),
            1,
            '25 hours is 1 hour left over'
        );
        assert.equal(
            moment.duration({ hours: 25 }).days(),
            1,
            '25 hours makes 1 day'
        );
    });

    test('bubbling consistency', function (assert) {
        var days = 0,
            months = 0,
            newDays,
            newMonths,
            totalDays,
            d;
        for (totalDays = 1; totalDays <= 500; ++totalDays) {
            d = moment.duration(totalDays, 'days');
            newDays = d.days();
            newMonths = d.months() + d.years() * 12;
            assert.ok(
                (months === newMonths && days + 1 === newDays) ||
                    (months + 1 === newMonths && newDays === 0),
                'consistent total days ' +
                    totalDays +
                    ' was ' +
                    months +
                    ' ' +
                    days +
                    ' now ' +
                    newMonths +
                    ' ' +
                    newDays
            );
            days = newDays;
            months = newMonths;
        }
    });

    test('effective equivalency', function (assert) {
        assert.deepEqual(
            moment.duration({ seconds: 1 })._data,
            moment.duration({ milliseconds: 1000 })._data,
            '1 second is the same as 1000 milliseconds'
        );
        assert.deepEqual(
            moment.duration({ seconds: 60 })._data,
            moment.duration({ minutes: 1 })._data,
            '1 minute is the same as 60 seconds'
        );
        assert.deepEqual(
            moment.duration({ minutes: 60 })._data,
            moment.duration({ hours: 1 })._data,
            '1 hour is the same as 60 minutes'
        );
        assert.deepEqual(
            moment.duration({ hours: 24 })._data,
            moment.duration({ days: 1 })._data,
            '1 day is the same as 24 hours'
        );
        assert.deepEqual(
            moment.duration({ days: 7 })._data,
            moment.duration({ weeks: 1 })._data,
            '1 week is the same as 7 days'
        );
        assert.deepEqual(
            moment.duration({ days: 31 })._data,
            moment.duration({ months: 1 })._data,
            '1 month is the same as 30 days'
        );
        assert.deepEqual(
            moment.duration({ months: 12 })._data,
            moment.duration({ years: 1 })._data,
            '1 years is the same as 12 months'
        );
    });

    test('asGetters', function (assert) {
        // 400 years have exactly 146097 days

        // years
        assert.equal(moment.duration(1, 'year').asYears(), 1, '1 year as years');
        assert.equal(
            moment.duration(1, 'year').asQuarters(),
            4,
            '1 year as quarters'
        );
        assert.equal(moment.duration(1, 'year').asMonths(), 12, '1 year as months');
        assert.equal(
            moment.duration(400, 'year').asMonths(),
            4800,
            '400 years as months'
        );
        assert.equal(
            moment.duration(1, 'year').asWeeks().toFixed(3),
            52.143,
            '1 year as weeks'
        );
        assert.equal(moment.duration(1, 'year').asDays(), 365, '1 year as days');
        assert.equal(moment.duration(2, 'year').asDays(), 730, '2 years as days');
        assert.equal(moment.duration(3, 'year').asDays(), 1096, '3 years as days');
        assert.equal(moment.duration(4, 'year').asDays(), 1461, '4 years as days');
        assert.equal(
            moment.duration(400, 'year').asDays(),
            146097,
            '400 years as days'
        );
        assert.equal(moment.duration(1, 'year').asHours(), 8760, '1 year as hours');
        assert.equal(
            moment.duration(1, 'year').asMinutes(),
            525600,
            '1 year as minutes'
        );
        assert.equal(
            moment.duration(1, 'year').asSeconds(),
            31536000,
            '1 year as seconds'
        );
        assert.equal(
            moment.duration(1, 'year').asMilliseconds(),
            31536000000,
            '1 year as milliseconds'
        );

        // quarters
        assert.equal(
            moment.duration(1, 'quarter').asYears(),
            0.25,
            '1 quarter as years'
        );
        assert.equal(
            moment.duration(1, 'quarter').asQuarters(),
            1,
            '1 quarter as quarters'
        );
        assert.equal(
            moment.duration(1, 'quarter').asMonths(),
            3,
            '1 quarter as months'
        );
        assert.equal(
            moment.duration(2, 'quarter').asWeeks().toFixed(3),
            26.143,
            '2 month as quarters'
        );
        assert.equal(
            moment.duration(1, 'quarter').asDays(),
            91,
            '1 quarter as days'
        );
        assert.equal(
            moment.duration(2, 'quarter').asDays(),
            183,
            '2 quarter as days'
        );
        assert.equal(
            moment.duration(3, 'quarter').asDays(),
            274,
            '4 quarter as days'
        );
        assert.equal(
            moment.duration(4, 'quarter').asDays(),
            365,
            '4 quarter as days'
        );
        assert.equal(
            moment.duration(1, 'quarter').asHours(),
            2184,
            '1 quarter as hours'
        );
        assert.equal(
            moment.duration(3, 'quarter').asHours(),
            6576,
            '3 quarter as hours'
        );
        assert.equal(
            moment.duration(2, 'quarter').asMinutes(),
            263520,
            '2 quarter as minutes'
        );
        assert.equal(
            moment.duration(3, 'quarter').asSeconds(),
            23673600,
            '3 quarter as seconds'
        );
        assert.equal(
            moment.duration(1, 'quarter').asMilliseconds(),
            7862400000,
            '1 quarter as milliseconds'
        );

        // months
        assert.equal(
            moment.duration(1, 'month').asYears().toFixed(4),
            0.0833,
            '1 month as years'
        );
        assert.equal(
            moment.duration(6, 'month').asQuarters(),
            2,
            '6 month as quarters'
        );
        assert.equal(
            moment.duration(1, 'month').asMonths(),
            1,
            '1 month as months'
        );
        assert.equal(
            moment.duration(1, 'month').asWeeks().toFixed(3),
            4.286,
            '1 month as weeks'
        );
        assert.equal(moment.duration(1, 'month').asDays(), 30, '1 month as days');
        assert.equal(moment.duration(2, 'month').asDays(), 61, '2 months as days');
        assert.equal(moment.duration(3, 'month').asDays(), 91, '3 months as days');
        assert.equal(moment.duration(4, 'month').asDays(), 122, '4 months as days');
        assert.equal(moment.duration(5, 'month').asDays(), 152, '5 months as days');
        assert.equal(moment.duration(6, 'month').asDays(), 183, '6 months as days');
        assert.equal(moment.duration(7, 'month').asDays(), 213, '7 months as days');
        assert.equal(moment.duration(8, 'month').asDays(), 243, '8 months as days');
        assert.equal(moment.duration(9, 'month').asDays(), 274, '9 months as days');
        assert.equal(
            moment.duration(10, 'month').asDays(),
            304,
            '10 months as days'
        );
        assert.equal(
            moment.duration(11, 'month').asDays(),
            335,
            '11 months as days'
        );
        assert.equal(
            moment.duration(12, 'month').asDays(),
            365,
            '12 months as days'
        );
        assert.equal(
            moment.duration(24, 'month').asDays(),
            730,
            '24 months as days'
        );
        assert.equal(
            moment.duration(36, 'month').asDays(),
            1096,
            '36 months as days'
        );
        assert.equal(
            moment.duration(48, 'month').asDays(),
            1461,
            '48 months as days'
        );
        assert.equal(
            moment.duration(4800, 'month').asDays(),
            146097,
            '4800 months as days'
        );
        assert.equal(
            moment.duration(1, 'month').asHours(),
            720,
            '1 month as hours'
        );
        assert.equal(
            moment.duration(1, 'month').asMinutes(),
            43200,
            '1 month as minutes'
        );
        assert.equal(
            moment.duration(1, 'month').asSeconds(),
            2592000,
            '1 month as seconds'
        );
        assert.equal(
            moment.duration(1, 'month').asMilliseconds(),
            2592000000,
            '1 month as milliseconds'
        );

        // weeks
        assert.equal(
            moment.duration(1, 'week').asYears().toFixed(4),
            0.0192,
            '1 week as years'
        );
        assert.equal(
            moment.duration(1, 'week').asQuarters().toFixed(4),
            0.0767,
            '1 week as quarters'
        );
        assert.equal(
            moment.duration(1, 'week').asMonths().toFixed(3),
            0.23,
            '1 week as months'
        );
        assert.equal(moment.duration(1, 'week').asWeeks(), 1, '1 week as weeks');
        assert.equal(moment.duration(1, 'week').asDays(), 7, '1 week as days');
        assert.equal(moment.duration(1, 'week').asHours(), 168, '1 week as hours');
        assert.equal(
            moment.duration(1, 'week').asMinutes(),
            10080,
            '1 week as minutes'
        );
        assert.equal(
            moment.duration(1, 'week').asSeconds(),
            604800,
            '1 week as seconds'
        );
        assert.equal(
            moment.duration(1, 'week').asMilliseconds(),
            604800000,
            '1 week as milliseconds'
        );

        // days
        assert.equal(
            moment.duration(1, 'day').asYears().toFixed(4),
            0.0027,
            '1 day as years'
        );
        assert.equal(
            moment.duration(1, 'day').asQuarters().toFixed(4),
            0.011,
            '1 day as quarters'
        );
        assert.equal(
            moment.duration(1, 'day').asMonths().toFixed(3),
            0.033,
            '1 day as months'
        );
        assert.equal(
            moment.duration(1, 'day').asWeeks().toFixed(3),
            0.143,
            '1 day as weeks'
        );
        assert.equal(moment.duration(1, 'day').asDays(), 1, '1 day as days');
        assert.equal(moment.duration(1, 'day').asHours(), 24, '1 day as hours');
        assert.equal(
            moment.duration(1, 'day').asMinutes(),
            1440,
            '1 day as minutes'
        );
        assert.equal(
            moment.duration(1, 'day').asSeconds(),
            86400,
            '1 day as seconds'
        );
        assert.equal(
            moment.duration(1, 'day').asMilliseconds(),
            86400000,
            '1 day as milliseconds'
        );

        // hours
        assert.equal(
            moment.duration(1, 'hour').asYears().toFixed(6),
            0.000114,
            '1 hour as years'
        );
        assert.equal(
            moment.duration(1, 'hour').asQuarters().toFixed(6),
            0.000456,
            '1 hour as quarters'
        );
        assert.equal(
            moment.duration(1, 'hour').asMonths().toFixed(5),
            0.00137,
            '1 hour as months'
        );
        assert.equal(
            moment.duration(1, 'hour').asWeeks().toFixed(5),
            0.00595,
            '1 hour as weeks'
        );
        assert.equal(
            moment.duration(1, 'hour').asDays().toFixed(4),
            0.0417,
            '1 hour as days'
        );
        assert.equal(moment.duration(1, 'hour').asHours(), 1, '1 hour as hours');
        assert.equal(
            moment.duration(1, 'hour').asMinutes(),
            60,
            '1 hour as minutes'
        );
        assert.equal(
            moment.duration(1, 'hour').asSeconds(),
            3600,
            '1 hour as seconds'
        );
        assert.equal(
            moment.duration(1, 'hour').asMilliseconds(),
            3600000,
            '1 hour as milliseconds'
        );

        // minutes
        assert.equal(
            moment.duration(1, 'minute').asYears().toFixed(8),
            0.0000019,
            '1 minute as years'
        );
        assert.equal(
            moment.duration(1, 'minute').asQuarters().toFixed(8),
            0.00000761,
            '1 minute as quarters'
        );
        assert.equal(
            moment.duration(1, 'minute').asMonths().toFixed(7),
            0.0000228,
            '1 minute as months'
        );
        assert.equal(
            moment.duration(1, 'minute').asWeeks().toFixed(7),
            0.0000992,
            '1 minute as weeks'
        );
        assert.equal(
            moment.duration(1, 'minute').asDays().toFixed(6),
            0.000694,
            '1 minute as days'
        );
        assert.equal(
            moment.duration(1, 'minute').asHours().toFixed(4),
            0.0167,
            '1 minute as hours'
        );
        assert.equal(
            moment.duration(1, 'minute').asMinutes(),
            1,
            '1 minute as minutes'
        );
        assert.equal(
            moment.duration(1, 'minute').asSeconds(),
            60,
            '1 minute as seconds'
        );
        assert.equal(
            moment.duration(1, 'minute').asMilliseconds(),
            60000,
            '1 minute as milliseconds'
        );

        // seconds
        assert.equal(
            moment.duration(1, 'second').asYears().toFixed(10),
            0.0000000317,
            '1 second as years'
        );
        assert.equal(
            moment.duration(1, 'second').asQuarters().toFixed(10),
            0.0000001268,
            '1 second as quarters'
        );
        assert.equal(
            moment.duration(1, 'second').asMonths().toFixed(9),
            0.00000038,
            '1 second as months'
        );
        assert.equal(
            moment.duration(1, 'second').asWeeks().toFixed(8),
            0.00000165,
            '1 second as weeks'
        );
        assert.equal(
            moment.duration(1, 'second').asDays().toFixed(7),
            0.0000116,
            '1 second as days'
        );
        assert.equal(
            moment.duration(1, 'second').asHours().toFixed(6),
            0.000278,
            '1 second as hours'
        );
        assert.equal(
            moment.duration(1, 'second').asMinutes().toFixed(4),
            0.0167,
            '1 second as minutes'
        );
        assert.equal(
            moment.duration(1, 'second').asSeconds(),
            1,
            '1 second as seconds'
        );
        assert.equal(
            moment.duration(1, 'second').asMilliseconds(),
            1000,
            '1 second as milliseconds'
        );

        // milliseconds
        assert.equal(
            moment.duration(1, 'millisecond').asYears().toFixed(13),
            0.0000000000317,
            '1 millisecond as years'
        );
        assert.equal(
            moment.duration(1, 'millisecond').asQuarters().toFixed(13),
            0.0000000001268,
            '1 millisecond as quarters'
        );
        assert.equal(
            moment.duration(1, 'millisecond').asMonths().toFixed(12),
            0.00000000038,
            '1 millisecond as months'
        );
        assert.equal(
            moment.duration(1, 'millisecond').asWeeks().toFixed(11),
            0.00000000165,
            '1 millisecond as weeks'
        );
        assert.equal(
            moment.duration(1, 'millisecond').asDays().toFixed(10),
            0.0000000116,
            '1 millisecond as days'
        );
        assert.equal(
            moment.duration(1, 'millisecond').asHours().toFixed(9),
            0.000000278,
            '1 millisecond as hours'
        );
        assert.equal(
            moment.duration(1, 'millisecond').asMinutes().toFixed(7),
            0.0000167,
            '1 millisecond as minutes'
        );
        assert.equal(
            moment.duration(1, 'millisecond').asSeconds(),
            0.001,
            '1 millisecond as seconds'
        );
        assert.equal(
            moment.duration(1, 'millisecond').asMilliseconds(),
            1,
            '1 millisecond as milliseconds'
        );
    });

    test('as getters for small units', function (assert) {
        var dS = moment.duration(1, 'milliseconds'),
            ds = moment.duration(3, 'seconds'),
            dm = moment.duration(13, 'minutes');

        // Tests for issue #1867.
        // Floating point errors for small duration units were introduced in version 2.8.0.
        assert.equal(dS.as('milliseconds'), 1, 'as("milliseconds")');
        assert.equal(dS.asMilliseconds(), 1, 'asMilliseconds()');
        assert.equal(ds.as('seconds'), 3, 'as("seconds")');
        assert.equal(ds.asSeconds(), 3, 'asSeconds()');
        assert.equal(dm.as('minutes'), 13, 'as("minutes")');
        assert.equal(dm.asMinutes(), 13, 'asMinutes()');
    });

    test('minutes getter for floating point hours', function (assert) {
        // Tests for issue #2978.
        // For certain floating point hours, .minutes() getter produced incorrect values due to the rounding errors
        assert.equal(moment.duration(2.3, 'h').minutes(), 18, 'minutes()');
        assert.equal(moment.duration(4.1, 'h').minutes(), 6, 'minutes()');
    });

    test('isDuration', function (assert) {
        assert.ok(
            moment.isDuration(moment.duration(12345678)),
            'correctly says true'
        );
        assert.ok(!moment.isDuration(moment()), 'moment object is not a duration');
        assert.ok(
            !moment.isDuration({ milliseconds: 1 }),
            'plain object is not a duration'
        );
    });

    test('add', function (assert) {
        var d = moment.duration({ months: 4, weeks: 3, days: 2 });
        // for some reason, d._data._months does not get updated; use d._months instead.
        assert.equal(d.add(1, 'month')._months, 5, 'Add months');
        assert.equal(d.add(5, 'days')._days, 28, 'Add days');
        assert.equal(d.add(10000)._milliseconds, 10000, 'Add milliseconds');
        assert.equal(
            d.add({ h: 23, m: 59 })._milliseconds,
            23 * 60 * 60 * 1000 + 59 * 60 * 1000 + 10000,
            'Add hour:minute'
        );
    });

    test('add to moment', function (assert) {
        var d = moment.duration({ months: 1, seconds: -1 }),
            m = moment('2017-03-01').add(d);
        assert.equal(m.month(), 2, 'Adds months before time');
        assert.equal(m.date(), 31, 'Adds time after months');
    });

    test('add and bubble', function (assert) {
        var d;

        assert.equal(
            moment.duration(1, 'second').add(1000, 'milliseconds').seconds(),
            2,
            'Adding milliseconds should bubble up to seconds'
        );
        assert.equal(
            moment.duration(1, 'minute').add(60, 'second').minutes(),
            2,
            'Adding seconds should bubble up to minutes'
        );
        assert.equal(
            moment.duration(1, 'hour').add(60, 'minutes').hours(),
            2,
            'Adding minutes should bubble up to hours'
        );
        assert.equal(
            moment.duration(1, 'day').add(24, 'hours').days(),
            2,
            'Adding hours should bubble up to days'
        );

        d = moment.duration(-1, 'day').add(1, 'hour');
        assert.equal(d.hours(), -23, '-1 day + 1 hour == -23 hour (component)');
        assert.equal(d.asHours(), -23, '-1 day + 1 hour == -23 hours');

        d = moment.duration(+1, 'day').add(1, 'hour');
        assert.equal(d.hours(), 1, '1 day + 1 hour == 1 hour (component)');
        assert.equal(d.asHours(), 25, '1 day + 1 hour == 25 hour');

        d = moment.duration(-1, 'year').add(1, 'day');
        assert.equal(d.days(), -30, '- 1 year + 1 day == -30 days (component)');
        assert.equal(d.months(), -11, '- 1 year + 1 day == -11 months (component)');
        assert.equal(d.years(), 0, '- 1 year + 1 day == 0 years (component)');
        assert.equal(d.asDays(), -364, '- 1 year + 1 day == -364 days');

        d = moment.duration(+1, 'year').add(1, 'day');
        assert.equal(d.days(), 1, '+ 1 year + 1 day == 1 days (component)');
        assert.equal(d.months(), 0, '+ 1 year + 1 day == 0 month (component)');
        assert.equal(d.years(), 1, '+ 1 year + 1 day == 1 year (component)');
        assert.equal(d.asDays(), 366, '+ 1 year + 1 day == +366 day');

        d = moment.duration(-1, 'year').add(1, 'hour');
        assert.equal(d.hours(), -23, '- 1 year + 1 hour == -23 hours (component)');
        assert.equal(d.days(), -30, '- 1 year + 1 hour == -30 days (component)');
        assert.equal(
            d.months(),
            -11,
            '- 1 year + 1 hour == -11 months (component)'
        );
        assert.equal(d.years(), 0, '- 1 year + 1 hour == 0 years (component)');

        d = moment.duration(+1, 'year').add(1, 'hour');
        assert.equal(d.hours(), 1, '+ 1 year + 1 hour == 1 hour (component)');
        assert.equal(d.days(), 0, '+ 1 year + 1 hour == 1 day (component)');
        assert.equal(d.months(), 0, '+ 1 year + 1 hour == 1 month (component)');
        assert.equal(d.years(), 1, '+ 1 year + 1 hour == 1 year (component)');
    });

    test('subtract and bubble', function (assert) {
        var d;

        assert.equal(
            moment.duration(2, 'second').subtract(1000, 'milliseconds').seconds(),
            1,
            'Subtracting milliseconds should bubble up to seconds'
        );
        assert.equal(
            moment.duration(2, 'minute').subtract(60, 'second').minutes(),
            1,
            'Subtracting seconds should bubble up to minutes'
        );
        assert.equal(
            moment.duration(2, 'hour').subtract(60, 'minutes').hours(),
            1,
            'Subtracting minutes should bubble up to hours'
        );
        assert.equal(
            moment.duration(2, 'day').subtract(24, 'hours').days(),
            1,
            'Subtracting hours should bubble up to days'
        );

        d = moment.duration(1, 'day').subtract(1, 'hour');
        assert.equal(d.hours(), 23, '1 day - 1 hour == 23 hour (component)');
        assert.equal(d.asHours(), 23, '1 day - 1 hour == 23 hours');

        d = moment.duration(1, 'year').subtract(1, 'day');
        assert.equal(d.days(), 30, '1 year - 1 day == 30 days (component)');
        assert.equal(d.months(), 11, '1 year - 1 day == 11 months (component)');
        assert.equal(d.years(), 0, '1 year - 1 day == 0 years (component)');
        assert.equal(d.asDays(), 364, '1 year - 1 day == 364 days');

        d = moment.duration(1, 'year').subtract(1, 'hour');
        assert.equal(d.hours(), 23, '1 year - 1 hour == 23 hours (component)');
        assert.equal(d.days(), 30, '1 year - 1 hour == 30 days (component)');
        assert.equal(d.months(), 11, '1 year - 1 hour == 11 months (component)');
        assert.equal(d.years(), 0, '1 year - 1 hour == 0 years (component)');
    });

    test('subtract', function (assert) {
        var d = moment.duration({ months: 2, weeks: 2, days: 0, hours: 5 });
        // for some reason, d._data._months does not get updated; use d._months instead.
        assert.equal(d.subtract(1, 'months')._months, 1, 'Subtract months');
        assert.equal(d.subtract(14, 'days')._days, 0, 'Subtract days');
        assert.equal(
            d.subtract(10000)._milliseconds,
            5 * 60 * 60 * 1000 - 10000,
            'Subtract milliseconds'
        );
        assert.equal(
            d.subtract({ h: 1, m: 59 })._milliseconds,
            3 * 60 * 60 * 1000 + 1 * 60 * 1000 - 10000,
            'Subtract hour:minute'
        );
    });

    test('JSON.stringify duration', function (assert) {
        var d = moment.duration(1024, 'h');

        assert.equal(
            JSON.stringify(d),
            '"' + d.toISOString() + '"',
            'JSON.stringify on duration should return ISO string'
        );
    });

    test('duration plugins', function (assert) {
        var durationObject = moment.duration();
        moment.duration.fn.foo = function (arg) {
            assert.equal(this, durationObject);
            assert.equal(arg, 5);
        };
        durationObject.foo(5);
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function objectKeys(obj) {
        if (Object.keys) {
            return Object.keys(obj);
        } else {
            // IE8
            var res = [],
                i;
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        }
    }

    function eachOwnProp(object, callback) {
        each(objectKeys(object), callback);
    }

    module('format');

    test('format using constants', function (assert) {
        var m = moment('2016-01-02T23:40:40.678');
        assert.equal(
            m.format(moment.HTML5_FMT.DATETIME_LOCAL),
            '2016-01-02T23:40',
            'datetime local format constant'
        );
        assert.equal(
            m.format(moment.HTML5_FMT.DATETIME_LOCAL_SECONDS),
            '2016-01-02T23:40:40',
            'datetime local format constant'
        );
        assert.equal(
            m.format(moment.HTML5_FMT.DATETIME_LOCAL_MS),
            '2016-01-02T23:40:40.678',
            'datetime local format constant with seconds and millis'
        );
        assert.equal(
            m.format(moment.HTML5_FMT.DATE),
            '2016-01-02',
            'date format constant'
        );
        assert.equal(
            m.format(moment.HTML5_FMT.TIME),
            '23:40',
            'time format constant'
        );
        assert.equal(
            m.format(moment.HTML5_FMT.TIME_SECONDS),
            '23:40:40',
            'time format constant with seconds'
        );
        assert.equal(
            m.format(moment.HTML5_FMT.TIME_MS),
            '23:40:40.678',
            'time format constant with seconds and millis'
        );
        assert.equal(
            m.format(moment.HTML5_FMT.WEEK),
            '2015-W53',
            'week format constant'
        );
        assert.equal(
            m.format(moment.HTML5_FMT.MONTH),
            '2016-01',
            'month format constant'
        );
    });

    test('format YY', function (assert) {
        var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125));
        assert.equal(b.format('YY'), '09', 'YY ---> 09');
    });

    test('format escape brackets', function (assert) {
        moment.locale('en');

        var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125));
        assert.equal(b.format('[day]'), 'day', 'Single bracket');
        assert.equal(b.format('[day] YY [YY]'), 'day 09 YY', 'Double bracket');
        assert.equal(b.format('[YY'), '[09', 'Un-ended bracket');
        assert.equal(b.format('[[YY]]'), '[YY]', 'Double nested brackets');
        assert.equal(b.format('[[]'), '[', 'Escape open bracket');
        assert.equal(b.format('[Last]'), 'Last', 'localized tokens');
        assert.equal(
            b.format('[L] L'),
            'L 02/14/2009',
            'localized tokens with escaped localized tokens'
        );
        assert.equal(
            b.format('[L LL LLL LLLL aLa]'),
            'L LL LLL LLLL aLa',
            'localized tokens with escaped localized tokens'
        );
        assert.equal(
            b.format('[LLL] LLL'),
            'LLL February 14, 2009 3:25 PM',
            'localized tokens with escaped localized tokens (recursion)'
        );
        assert.equal(b.format('YYYY[\n]DD[\n]'), '2009\n14\n', 'Newlines');
    });

    test('handle negative years', function (assert) {
        moment.locale('en');
        assert.equal(
            moment.utc().year(-1).format('YY'),
            '-01',
            'YY with negative year'
        );
        assert.equal(
            moment.utc().year(-1).format('YYYY'),
            '-0001',
            'YYYY with negative year'
        );
        assert.equal(
            moment.utc().year(-12).format('YY'),
            '-12',
            'YY with negative year'
        );
        assert.equal(
            moment.utc().year(-12).format('YYYY'),
            '-0012',
            'YYYY with negative year'
        );
        assert.equal(
            moment.utc().year(-123).format('YY'),
            '-23',
            'YY with negative year'
        );
        assert.equal(
            moment.utc().year(-123).format('YYYY'),
            '-0123',
            'YYYY with negative year'
        );
        assert.equal(
            moment.utc().year(-1234).format('YY'),
            '-34',
            'YY with negative year'
        );
        assert.equal(
            moment.utc().year(-1234).format('YYYY'),
            '-1234',
            'YYYY with negative year'
        );
        assert.equal(
            moment.utc().year(-12345).format('YY'),
            '-45',
            'YY with negative year'
        );
        assert.equal(
            moment.utc().year(-12345).format('YYYY'),
            '-12345',
            'YYYY with negative year'
        );
    });

    test('format milliseconds', function (assert) {
        var b = moment(new Date(2009, 1, 14, 15, 25, 50, 123));
        assert.equal(b.format('S'), '1', 'Deciseconds');
        assert.equal(b.format('SS'), '12', 'Centiseconds');
        assert.equal(b.format('SSS'), '123', 'Milliseconds');
        b.milliseconds(789);
        assert.equal(b.format('S'), '7', 'Deciseconds');
        assert.equal(b.format('SS'), '78', 'Centiseconds');
        assert.equal(b.format('SSS'), '789', 'Milliseconds');
    });

    test('format timezone', function (assert) {
        var b = moment(new Date(2010, 1, 14, 15, 25, 50, 125));
        assert.ok(
            b.format('Z').match(/^[\+\-]\d\d:\d\d$/),
            b.format('Z') + " should be something like '+07:30'"
        );
        assert.ok(
            b.format('ZZ').match(/^[\+\-]\d{4}$/),
            b.format('ZZ') + " should be something like '+0700'"
        );
    });

    test('format multiple with utc offset', function (assert) {
        var b = moment('2012-10-08 -1200', [
            'YYYY-MM-DD HH:mm ZZ',
            'YYYY-MM-DD ZZ',
            'YYYY-MM-DD',
        ]);
        assert.equal(
            b.format('YYYY-MM'),
            '2012-10',
            'Parsing multiple formats should not crash with different sized formats'
        );
    });

    test('isDST', function (assert) {
        var janOffset = new Date(2011, 0, 1).getTimezoneOffset(),
            julOffset = new Date(2011, 6, 1).getTimezoneOffset(),
            janIsDst = janOffset < julOffset,
            julIsDst = julOffset < janOffset,
            jan1 = moment([2011]),
            jul1 = moment([2011, 6]);

        if (janIsDst && julIsDst) {
            assert.ok(0, 'January and July cannot both be in DST');
            assert.ok(0, 'January and July cannot both be in DST');
        } else if (janIsDst) {
            assert.ok(jan1.isDST(), 'January 1 is DST');
            assert.ok(!jul1.isDST(), 'July 1 is not DST');
        } else if (julIsDst) {
            assert.ok(!jan1.isDST(), 'January 1 is not DST');
            assert.ok(jul1.isDST(), 'July 1 is DST');
        } else {
            assert.ok(!jan1.isDST(), 'January 1 is not DST');
            assert.ok(!jul1.isDST(), 'July 1 is not DST');
        }
    });

    test('unix timestamp', function (assert) {
        var m = moment('1234567890.123', 'X');
        assert.equal(
            m.format('X'),
            '1234567890',
            'unix timestamp without milliseconds'
        );
        assert.equal(
            m.format('X.S'),
            '1234567890.1',
            'unix timestamp with deciseconds'
        );
        assert.equal(
            m.format('X.SS'),
            '1234567890.12',
            'unix timestamp with centiseconds'
        );
        assert.equal(
            m.format('X.SSS'),
            '1234567890.123',
            'unix timestamp with milliseconds'
        );

        m = moment(1234567890.123, 'X');
        assert.equal(m.format('X'), '1234567890', 'unix timestamp as integer');
    });

    test('unix offset milliseconds', function (assert) {
        var m = moment('1234567890123', 'x');
        assert.equal(m.format('x'), '1234567890123', 'unix offset in milliseconds');

        m = moment(1234567890123, 'x');
        assert.equal(
            m.format('x'),
            '1234567890123',
            'unix offset in milliseconds as integer'
        );
    });

    test('utcOffset sanity checks', function (assert) {
        assert.equal(
            moment().utcOffset() % 15,
            0,
            'utc offset should be a multiple of 15 (was ' +
                moment().utcOffset() +
                ')'
        );

        assert.equal(
            moment().utcOffset(),
            -new Date().getTimezoneOffset(),
            'utcOffset should return the opposite of getTimezoneOffset'
        );
    });

    test('default format', function (assert) {
        var isoRegex = /\d{4}.\d\d.\d\dT\d\d.\d\d.\d\d[\+\-]\d\d:\d\d/;
        assert.ok(
            isoRegex.exec(moment().format()),
            'default format (' + moment().format() + ') should match ISO'
        );
    });

    test('default UTC format', function (assert) {
        var isoRegex = /\d{4}.\d\d.\d\dT\d\d.\d\d.\d\dZ/;
        assert.ok(
            isoRegex.exec(moment.utc().format()),
            'default UTC format (' + moment.utc().format() + ') should match ISO'
        );
    });

    test('toJSON', function (assert) {
        var supportsJson =
                typeof JSON !== 'undefined' &&
                JSON.stringify &&
                JSON.stringify.call,
            date = moment('2012-10-09T21:30:40.678+0100');

        assert.equal(
            date.toJSON(),
            '2012-10-09T20:30:40.678Z',
            'should output ISO8601 on moment.fn.toJSON'
        );

        if (supportsJson) {
            assert.equal(
                JSON.stringify({
                    date: date,
                }),
                '{"date":"2012-10-09T20:30:40.678Z"}',
                'should output ISO8601 on JSON.stringify'
            );
        }
    });

    test('toISOString', function (assert) {
        var date = moment.utc('2012-10-09T20:30:40.678');

        assert.equal(
            date.toISOString(),
            '2012-10-09T20:30:40.678Z',
            'should output ISO8601 on moment.fn.toISOString'
        );

        // big years
        date = moment.utc('+020123-10-09T20:30:40.678');
        assert.equal(
            date.toISOString(),
            '+020123-10-09T20:30:40.678Z',
            'ISO8601 format on big positive year'
        );
        // negative years
        date = moment.utc('-000001-10-09T20:30:40.678');
        assert.equal(
            date.toISOString(),
            '-000001-10-09T20:30:40.678Z',
            'ISO8601 format on negative year'
        );
        // big negative years
        date = moment.utc('-020123-10-09T20:30:40.678');
        assert.equal(
            date.toISOString(),
            '-020123-10-09T20:30:40.678Z',
            'ISO8601 format on big negative year'
        );

        //invalid dates
        date = moment.utc('2017-12-32');
        assert.equal(
            date.toISOString(),
            null,
            'An invalid date to iso string is null'
        );
    });

    test('toISOString without UTC conversion', function (assert) {
        var date = moment.utc('2016-12-31T19:53:45.678').utcOffset('+05:30');

        assert.equal(
            date.toISOString(true),
            '2017-01-01T01:23:45.678+05:30',
            'should output ISO8601 on moment.fn.toISOString'
        );

        // big years
        date = moment.utc('+020122-12-31T19:53:45.678').utcOffset('+05:30');
        assert.equal(
            date.toISOString(true),
            '+020123-01-01T01:23:45.678+05:30',
            'ISO8601 format on big positive year'
        );
        // negative years
        date = moment.utc('-000002-12-31T19:53:45.678').utcOffset('+05:30');
        assert.equal(
            date.toISOString(true),
            '-000001-01-01T01:23:45.678+05:30',
            'ISO8601 format on negative year'
        );
        // big negative years
        date = moment.utc('-020124-12-31T19:53:45.678').utcOffset('+05:30');
        assert.equal(
            date.toISOString(true),
            '-020123-01-01T01:23:45.678+05:30',
            'ISO8601 format on big negative year'
        );

        //invalid dates
        date = moment.utc('2017-12-32').utcOffset('+05:30');
        assert.equal(
            date.toISOString(true),
            null,
            'An invalid date to iso string is null'
        );
    });

    // See https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
    test('inspect', function (assert) {
        function roundtrip(m) {
            return new Function('moment', 'return ' + m.inspect())(moment);
        }
        function testInspect(date, string) {
            var inspected = date.inspect();
            assert.equal(inspected, string);
            assert.ok(date.isSame(roundtrip(date)), 'Tried to parse ' + inspected);
        }

        testInspect(
            moment('2012-10-09T20:30:40.678'),
            'moment("2012-10-09T20:30:40.678")'
        );
        testInspect(
            moment('+020123-10-09T20:30:40.678'),
            'moment("+020123-10-09T20:30:40.678")'
        );
        testInspect(
            moment.utc('2012-10-09T20:30:40.678'),
            'moment.utc("2012-10-09T20:30:40.678+00:00")'
        );
        testInspect(
            moment.utc('+020123-10-09T20:30:40.678'),
            'moment.utc("+020123-10-09T20:30:40.678+00:00")'
        );
        testInspect(
            moment.utc('+020123-10-09T20:30:40.678+01:00'),
            'moment.utc("+020123-10-09T19:30:40.678+00:00")'
        );
        testInspect(
            moment.parseZone('2016-06-11T17:30:40.678+0430'),
            'moment.parseZone("2016-06-11T17:30:40.678+04:30")'
        );
        testInspect(
            moment.parseZone('+112016-06-11T17:30:40.678+0430'),
            'moment.parseZone("+112016-06-11T17:30:40.678+04:30")'
        );

        assert.equal(
            moment(new Date('nope')).inspect(),
            'moment.invalid(/* Invalid Date */)'
        );
        assert.equal(
            moment('blah', 'YYYY').inspect(),
            'moment.invalid(/* blah */)'
        );
    });

    test('long years', function (assert) {
        assert.equal(
            moment.utc().year(2).format('YYYYYY'),
            '+000002',
            'small year with YYYYYY'
        );
        assert.equal(
            moment.utc().year(2012).format('YYYYYY'),
            '+002012',
            'regular year with YYYYYY'
        );
        assert.equal(
            moment.utc().year(20123).format('YYYYYY'),
            '+020123',
            'big year with YYYYYY'
        );

        assert.equal(
            moment.utc().year(-1).format('YYYYYY'),
            '-000001',
            'small negative year with YYYYYY'
        );
        assert.equal(
            moment.utc().year(-2012).format('YYYYYY'),
            '-002012',
            'negative year with YYYYYY'
        );
        assert.equal(
            moment.utc().year(-20123).format('YYYYYY'),
            '-020123',
            'big negative year with YYYYYY'
        );
    });

    test('toISOString() when 0 year', function (assert) {
        // https://github.com/moment/moment/issues/3765
        var date = moment('0000-01-01T21:00:00.000Z');
        assert.equal(date.toISOString(), '0000-01-01T21:00:00.000Z');
        assert.equal(date.toDate().toISOString(), '0000-01-01T21:00:00.000Z');
    });

    test('iso week formats', function (assert) {
        // https://en.wikipedia.org/wiki/ISO_week_date
        var cases = {
            '2005-01-02': '2004-53',
            '2005-12-31': '2005-52',
            '2007-01-01': '2007-01',
            '2007-12-30': '2007-52',
            '2007-12-31': '2008-01',
            '2008-01-01': '2008-01',
            '2008-12-28': '2008-52',
            '2008-12-29': '2009-01',
            '2008-12-30': '2009-01',
            '2008-12-31': '2009-01',
            '2009-01-01': '2009-01',
            '2009-12-31': '2009-53',
            '2010-01-01': '2009-53',
            '2010-01-02': '2009-53',
            '2010-01-03': '2009-53',
            '404-12-31': '0404-53',
            '405-12-31': '0405-52',
        };

        eachOwnProp(cases, function (i) {
            var isoWeek, formatted2, formatted1;
            isoWeek = cases[i].split('-').pop();
            formatted2 = moment(i, 'YYYY-MM-DD').format('WW');
            assert.equal(
                isoWeek,
                formatted2,
                i + ': WW should be ' + isoWeek + ', but ' + formatted2
            );
            isoWeek = isoWeek.replace(/^0+/, '');
            formatted1 = moment(i, 'YYYY-MM-DD').format('W');
            assert.equal(
                isoWeek,
                formatted1,
                i + ': W should be ' + isoWeek + ', but ' + formatted1
            );
        });
    });

    test('iso week year formats', function (assert) {
        // https://en.wikipedia.org/wiki/ISO_week_date
        var cases = {
            '2005-01-02': '2004-53',
            '2005-12-31': '2005-52',
            '2007-01-01': '2007-01',
            '2007-12-30': '2007-52',
            '2007-12-31': '2008-01',
            '2008-01-01': '2008-01',
            '2008-12-28': '2008-52',
            '2008-12-29': '2009-01',
            '2008-12-30': '2009-01',
            '2008-12-31': '2009-01',
            '2009-01-01': '2009-01',
            '2009-12-31': '2009-53',
            '2010-01-01': '2009-53',
            '2010-01-02': '2009-53',
            '2010-01-03': '2009-53',
            '404-12-31': '0404-53',
            '405-12-31': '0405-52',
        };

        eachOwnProp(cases, function (i) {
            var isoWeekYear, formatted5, formatted4, formatted2;
            isoWeekYear = cases[i].split('-')[0];
            formatted5 = moment(i, 'YYYY-MM-DD').format('GGGGG');
            assert.equal(
                '0' + isoWeekYear,
                formatted5,
                i + ': GGGGG should be ' + isoWeekYear + ', but ' + formatted5
            );
            formatted4 = moment(i, 'YYYY-MM-DD').format('GGGG');
            assert.equal(
                isoWeekYear,
                formatted4,
                i + ': GGGG should be ' + isoWeekYear + ', but ' + formatted4
            );
            formatted2 = moment(i, 'YYYY-MM-DD').format('GG');
            assert.equal(
                isoWeekYear.slice(2, 4),
                formatted2,
                i + ': GG should be ' + isoWeekYear + ', but ' + formatted2
            );
        });
    });

    test('week year formats', function (assert) {
        // https://en.wikipedia.org/wiki/ISO_week_date
        var cases = {
            '2005-01-02': '2004-53',
            '2005-12-31': '2005-52',
            '2007-01-01': '2007-01',
            '2007-12-30': '2007-52',
            '2007-12-31': '2008-01',
            '2008-01-01': '2008-01',
            '2008-12-28': '2008-52',
            '2008-12-29': '2009-01',
            '2008-12-30': '2009-01',
            '2008-12-31': '2009-01',
            '2009-01-01': '2009-01',
            '2009-12-31': '2009-53',
            '2010-01-01': '2009-53',
            '2010-01-02': '2009-53',
            '2010-01-03': '2009-53',
            '404-12-31': '0404-53',
            '405-12-31': '0405-52',
        };

        moment.defineLocale('dow:1,doy:4', { week: { dow: 1, doy: 4 } });

        eachOwnProp(cases, function (i) {
            var isoWeekYear, formatted5, formatted4, formatted2;
            isoWeekYear = cases[i].split('-')[0];
            formatted5 = moment(i, 'YYYY-MM-DD').format('ggggg');
            assert.equal(
                '0' + isoWeekYear,
                formatted5,
                i + ': ggggg should be ' + isoWeekYear + ', but ' + formatted5
            );
            formatted4 = moment(i, 'YYYY-MM-DD').format('gggg');
            assert.equal(
                isoWeekYear,
                formatted4,
                i + ': gggg should be ' + isoWeekYear + ', but ' + formatted4
            );
            formatted2 = moment(i, 'YYYY-MM-DD').format('gg');
            assert.equal(
                isoWeekYear.slice(2, 4),
                formatted2,
                i + ': gg should be ' + isoWeekYear + ', but ' + formatted2
            );
        });
        moment.defineLocale('dow:1,doy:4', null);
    });

    test('iso weekday formats', function (assert) {
        assert.equal(
            moment([1985, 1, 4]).format('E'),
            '1',
            'Feb  4 1985 is Monday    -- 1st day'
        );
        assert.equal(
            moment([2029, 8, 18]).format('E'),
            '2',
            'Sep 18 2029 is Tuesday   -- 2nd day'
        );
        assert.equal(
            moment([2013, 3, 24]).format('E'),
            '3',
            'Apr 24 2013 is Wednesday -- 3rd day'
        );
        assert.equal(
            moment([2015, 2, 5]).format('E'),
            '4',
            'Mar  5 2015 is Thursday  -- 4th day'
        );
        assert.equal(
            moment([1970, 0, 2]).format('E'),
            '5',
            'Jan  2 1970 is Friday    -- 5th day'
        );
        assert.equal(
            moment([2001, 4, 12]).format('E'),
            '6',
            'May 12 2001 is Saturday  -- 6th day'
        );
        assert.equal(
            moment([2000, 0, 2]).format('E'),
            '7',
            'Jan  2 2000 is Sunday    -- 7th day'
        );
    });

    test('weekday formats', function (assert) {
        moment.defineLocale('dow: 3,doy: 5', { week: { dow: 3, doy: 5 } });
        assert.equal(
            moment([1985, 1, 6]).format('e'),
            '0',
            'Feb  6 1985 is Wednesday -- 0th day'
        );
        assert.equal(
            moment([2029, 8, 20]).format('e'),
            '1',
            'Sep 20 2029 is Thursday  -- 1st day'
        );
        assert.equal(
            moment([2013, 3, 26]).format('e'),
            '2',
            'Apr 26 2013 is Friday    -- 2nd day'
        );
        assert.equal(
            moment([2015, 2, 7]).format('e'),
            '3',
            'Mar  7 2015 is Saturday  -- 3nd day'
        );
        assert.equal(
            moment([1970, 0, 4]).format('e'),
            '4',
            'Jan  4 1970 is Sunday    -- 4th day'
        );
        assert.equal(
            moment([2001, 4, 14]).format('e'),
            '5',
            'May 14 2001 is Monday    -- 5th day'
        );
        assert.equal(
            moment([2000, 0, 4]).format('e'),
            '6',
            'Jan  4 2000 is Tuesday   -- 6th day'
        );
        moment.defineLocale('dow: 3,doy: 5', null);
    });

    test('toString is just human readable format', function (assert) {
        var b = moment(new Date(2009, 1, 5, 15, 25, 50, 125));
        assert.equal(b.toString(), b.format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'));
    });

    test('toJSON skips postformat', function (assert) {
        moment.defineLocale('postformat', {
            postformat: function (s) {
                s.replace(/./g, 'X');
            },
        });
        assert.equal(
            moment.utc([2000, 0, 1]).toJSON(),
            '2000-01-01T00:00:00.000Z',
            "toJSON doesn't postformat"
        );
        moment.defineLocale('postformat', null);
    });

    test('calendar day timezone', function (assert) {
        moment.locale('en');
        var zones = [60, -60, 90, -90, 360, -360, 720, -720],
            b = moment().utc().startOf('day').subtract({ m: 1 }),
            c = moment().local().startOf('day').subtract({ m: 1 }),
            d = moment().local().startOf('day').subtract({ d: 2 }),
            i,
            z,
            a;

        for (i = 0; i < zones.length; ++i) {
            z = zones[i];
            a = moment().utcOffset(z).startOf('day').subtract({ m: 1 });
            assert.equal(
                moment(a).utcOffset(z).calendar(),
                'Yesterday at 11:59 PM',
                'Yesterday at 11:59 PM, not Today, or the wrong time, tz = ' + z
            );
        }

        assert.equal(
            moment(b).utc().calendar(),
            'Yesterday at 11:59 PM',
            'Yesterday at 11:59 PM, not Today, or the wrong time'
        );
        assert.equal(
            moment(c).local().calendar(),
            'Yesterday at 11:59 PM',
            'Yesterday at 11:59 PM, not Today, or the wrong time'
        );
        assert.equal(
            moment(c).local().calendar(d),
            'Tomorrow at 11:59 PM',
            'Tomorrow at 11:59 PM, not Yesterday, or the wrong time'
        );
    });

    test('calendar with custom formats', function (assert) {
        assert.equal(
            moment().calendar(null, { sameDay: '[Today]' }),
            'Today',
            'Today'
        );
        assert.equal(
            moment().add(1, 'days').calendar(null, { nextDay: '[Tomorrow]' }),
            'Tomorrow',
            'Tomorrow'
        );
        assert.equal(
            moment([1985, 1, 4]).calendar(null, { sameElse: 'YYYY-MM-DD' }),
            '1985-02-04',
            'Else'
        );
    });

    test('invalid', function (assert) {
        assert.equal(moment.invalid().format(), 'Invalid date');
        assert.equal(moment.invalid().format('YYYY-MM-DD'), 'Invalid date');
    });

    test('quarter formats', function (assert) {
        assert.equal(moment([1985, 1, 4]).format('Q'), '1', 'Feb  4 1985 is Q1');
        assert.equal(moment([2029, 8, 18]).format('Q'), '3', 'Sep 18 2029 is Q3');
        assert.equal(moment([2013, 3, 24]).format('Q'), '2', 'Apr 24 2013 is Q2');
        assert.equal(moment([2015, 2, 5]).format('Q'), '1', 'Mar  5 2015 is Q1');
        assert.equal(moment([1970, 0, 2]).format('Q'), '1', 'Jan  2 1970 is Q1');
        assert.equal(moment([2001, 11, 12]).format('Q'), '4', 'Dec 12 2001 is Q4');
        assert.equal(
            moment([2000, 0, 2]).format('[Q]Q-YYYY'),
            'Q1-2000',
            'Jan  2 2000 is Q1'
        );
    });

    test('quarter ordinal formats', function (assert) {
        assert.equal(
            moment([1985, 1, 4]).format('Qo'),
            '1st',
            'Feb 4 1985 is 1st quarter'
        );
        assert.equal(
            moment([2029, 8, 18]).format('Qo'),
            '3rd',
            'Sep 18 2029 is 3rd quarter'
        );
        assert.equal(
            moment([2013, 3, 24]).format('Qo'),
            '2nd',
            'Apr 24 2013 is 2nd quarter'
        );
        assert.equal(
            moment([2015, 2, 5]).format('Qo'),
            '1st',
            'Mar  5 2015 is 1st quarter'
        );
        assert.equal(
            moment([1970, 0, 2]).format('Qo'),
            '1st',
            'Jan  2 1970 is 1st quarter'
        );
        assert.equal(
            moment([2001, 11, 12]).format('Qo'),
            '4th',
            'Dec 12 2001 is 4th quarter'
        );
        assert.equal(
            moment([2000, 0, 2]).format('Qo [quarter] YYYY'),
            '1st quarter 2000',
            'Jan  2 2000 is 1st quarter'
        );
    });

    // test('full expanded format is returned from abbreviated formats', function (assert) {

    //     var locales =
    //         'ar-sa ar-tn ar az be bg bn bo br bs ca cs cv cy da de-at de dv el ' +
    //         'en-au en-ca en-gb en-ie en-nz eo es et eu fa fi fo fr-ca fr-ch fr fy ' +
    //         'gd gl he hi hr hu hy-am id is it ja jv ka kk km ko lb lo lt lv me mk ml ' +
    //         'mr ms-my ms my nb ne nl nn pl pt-br pt ro ru se si sk sl sq sr-cyrl ' +
    //         'sr sv sw ta te th tl-ph tlh tr tzl tzm-latn tzm uk uz vi zh-cn zh-tw';

    //     each(locales.split(' '), function (locale) {
    //         var data = moment().locale(locale).localeData()._longDateFormat;
    //         eachOwnProp(data, function (token) {
    //             // Check each format string to make sure it does not contain any
    //             // tokens that need to be expanded.
    //             each(tokens, function (i) {
    //                 // strip escaped sequences
    //                 var format = data[i].replace(/(\[[^\]]*\])/g, '');
    //                 assert.equal(false, !!~format.indexOf(token), 'locale ' + locale + ' contains ' + token + ' in ' + i);
    //             });
    //         });
    //     });
    // });

    test('milliseconds', function (assert) {
        var m = moment('123', 'SSS');

        assert.equal(m.format('S'), '1');
        assert.equal(m.format('SS'), '12');
        assert.equal(m.format('SSS'), '123');
        assert.equal(m.format('SSSS'), '1230');
        assert.equal(m.format('SSSSS'), '12300');
        assert.equal(m.format('SSSSSS'), '123000');
        assert.equal(m.format('SSSSSSS'), '1230000');
        assert.equal(m.format('SSSSSSSS'), '12300000');
        assert.equal(m.format('SSSSSSSSS'), '123000000');
    });

    test('hmm and hmmss', function (assert) {
        assert.equal(moment('12:34:56', 'HH:mm:ss').format('hmm'), '1234');
        assert.equal(moment('01:34:56', 'HH:mm:ss').format('hmm'), '134');
        assert.equal(moment('13:34:56', 'HH:mm:ss').format('hmm'), '134');

        assert.equal(moment('12:34:56', 'HH:mm:ss').format('hmmss'), '123456');
        assert.equal(moment('01:34:56', 'HH:mm:ss').format('hmmss'), '13456');
        assert.equal(moment('13:34:56', 'HH:mm:ss').format('hmmss'), '13456');
    });

    test('Hmm and Hmmss', function (assert) {
        assert.equal(moment('12:34:56', 'HH:mm:ss').format('Hmm'), '1234');
        assert.equal(moment('01:34:56', 'HH:mm:ss').format('Hmm'), '134');
        assert.equal(moment('13:34:56', 'HH:mm:ss').format('Hmm'), '1334');

        assert.equal(moment('12:34:56', 'HH:mm:ss').format('Hmmss'), '123456');
        assert.equal(moment('01:34:56', 'HH:mm:ss').format('Hmmss'), '13456');
        assert.equal(moment('08:34:56', 'HH:mm:ss').format('Hmmss'), '83456');
        assert.equal(moment('18:34:56', 'HH:mm:ss').format('Hmmss'), '183456');
    });

    test('k and kk', function (assert) {
        assert.equal(moment('01:23:45', 'HH:mm:ss').format('k'), '1');
        assert.equal(moment('12:34:56', 'HH:mm:ss').format('k'), '12');
        assert.equal(moment('01:23:45', 'HH:mm:ss').format('kk'), '01');
        assert.equal(moment('12:34:56', 'HH:mm:ss').format('kk'), '12');
        assert.equal(moment('00:34:56', 'HH:mm:ss').format('kk'), '24');
        assert.equal(moment('00:00:00', 'HH:mm:ss').format('kk'), '24');
    });

    test('Y token', function (assert) {
        assert.equal(
            moment('2010-01-01', 'YYYY-MM-DD', true).format('Y'),
            '2010',
            'format 2010 with Y'
        );
        assert.equal(
            moment('-123-01-01', 'Y-MM-DD', true).format('Y'),
            '-0123',
            'format -123 with Y'
        );
        assert.equal(
            moment('12345-01-01', 'Y-MM-DD', true).format('Y'),
            '+12345',
            'format 12345 with Y'
        );
        assert.equal(
            moment('0-01-01', 'Y-MM-DD', true).format('Y'),
            '0000',
            'format 0 with Y'
        );
        assert.equal(
            moment('1-01-01', 'Y-MM-DD', true).format('Y'),
            '0001',
            'format 1 with Y'
        );
        assert.equal(
            moment('9999-01-01', 'Y-MM-DD', true).format('Y'),
            '9999',
            'format 9999 with Y'
        );
        assert.equal(
            moment('10000-01-01', 'Y-MM-DD', true).format('Y'),
            '+10000',
            'format 10000 with Y'
        );
    });

    test('HTML5_FMT.WEEK', function (assert) {
        assert.equal(
            moment('2004-W01', moment.HTML5_FMT.WEEK).format(moment.HTML5_FMT.WEEK),
            '2004-W01',
            'issue #4698 regression'
        );
        assert.equal(
            moment('2019-W01').format(moment.HTML5_FMT.WEEK),
            '2019-W01',
            'issue #4833 regression'
        );
    });

    test('does not modify original moment instance', function (assert) {
        let m = moment(0),
            original = moment(0);
        m.format('yyyy-MM-DD');
        assert.equal(
            m.toISOString(),
            original.toISOString(),
            'issue #5571 regression'
        );

        assert.deepEqual(
            moment(new Date('2020-08-11 23:59:59'))
                .format('yyyy-MM-DD HH:mm:ss')
                .split(' '),
            moment(new Date('2020-08-11 23:59:59'))
                .format('HH:mm:ss yyyy-MM-DD')
                .split(' ')
                .reverse(),
            'issue #5681 regression'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('from_to');

    test('from', function (assert) {
        var start = moment();
        moment.locale('en');
        assert.equal(
            start.from(start.clone().add(5, 'seconds')),
            'a few seconds ago',
            '5 seconds = a few seconds ago'
        );
        assert.equal(
            start.from(start.clone().add(1, 'minute')),
            'a minute ago',
            '1 minute = a minute ago'
        );
        assert.equal(
            start.from(start.clone().add(5, 'minutes')),
            '5 minutes ago',
            '5 minutes = 5 minutes ago'
        );

        assert.equal(
            start.from(start.clone().subtract(5, 'seconds')),
            'in a few seconds',
            '5 seconds = in a few seconds'
        );
        assert.equal(
            start.from(start.clone().subtract(1, 'minute')),
            'in a minute',
            '1 minute = in a minute'
        );
        assert.equal(
            start.from(start.clone().subtract(5, 'minutes')),
            'in 5 minutes',
            '5 minutes = in 5 minutes'
        );
    });

    test('from with absolute duration', function (assert) {
        var start = moment();
        moment.locale('en');
        assert.equal(
            start.from(start.clone().add(5, 'seconds'), true),
            'a few seconds',
            '5 seconds = a few seconds'
        );
        assert.equal(
            start.from(start.clone().add(1, 'minute'), true),
            'a minute',
            '1 minute = a minute'
        );
        assert.equal(
            start.from(start.clone().add(5, 'minutes'), true),
            '5 minutes',
            '5 minutes = 5 minutes'
        );

        assert.equal(
            start.from(start.clone().subtract(5, 'seconds'), true),
            'a few seconds',
            '5 seconds = a few seconds'
        );
        assert.equal(
            start.from(start.clone().subtract(1, 'minute'), true),
            'a minute',
            '1 minute = a minute'
        );
        assert.equal(
            start.from(start.clone().subtract(5, 'minutes'), true),
            '5 minutes',
            '5 minutes = 5 minutes'
        );
    });

    test('to', function (assert) {
        var start = moment();
        moment.locale('en');
        assert.equal(
            start.to(start.clone().subtract(5, 'seconds')),
            'a few seconds ago',
            '5 seconds = a few seconds ago'
        );
        assert.equal(
            start.to(start.clone().subtract(1, 'minute')),
            'a minute ago',
            '1 minute = a minute ago'
        );
        assert.equal(
            start.to(start.clone().subtract(5, 'minutes')),
            '5 minutes ago',
            '5 minutes = 5 minutes ago'
        );

        assert.equal(
            start.to(start.clone().add(5, 'seconds')),
            'in a few seconds',
            '5 seconds = in a few seconds'
        );
        assert.equal(
            start.to(start.clone().add(1, 'minute')),
            'in a minute',
            '1 minute = in a minute'
        );
        assert.equal(
            start.to(start.clone().add(5, 'minutes')),
            'in 5 minutes',
            '5 minutes = in 5 minutes'
        );
    });

    test('to with absolute duration', function (assert) {
        var start = moment();
        moment.locale('en');
        assert.equal(
            start.to(start.clone().add(5, 'seconds'), true),
            'a few seconds',
            '5 seconds = a few seconds'
        );
        assert.equal(
            start.to(start.clone().add(1, 'minute'), true),
            'a minute',
            '1 minute = a minute'
        );
        assert.equal(
            start.to(start.clone().add(5, 'minutes'), true),
            '5 minutes',
            '5 minutes = 5 minutes'
        );

        assert.equal(
            start.to(start.clone().subtract(5, 'seconds'), true),
            'a few seconds',
            '5 seconds = a few seconds'
        );
        assert.equal(
            start.to(start.clone().subtract(1, 'minute'), true),
            'a minute',
            '1 minute = a minute'
        );
        assert.equal(
            start.to(start.clone().subtract(5, 'minutes'), true),
            '5 minutes',
            '5 minutes = 5 minutes'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('getters and setters');

    test('getters', function (assert) {
        var a = moment([2011, 9, 12, 6, 7, 8, 9]);
        assert.equal(a.year(), 2011, 'year');
        assert.equal(a.month(), 9, 'month');
        assert.equal(a.date(), 12, 'date');
        assert.equal(a.day(), 3, 'day');
        assert.equal(a.hours(), 6, 'hour');
        assert.equal(a.minutes(), 7, 'minute');
        assert.equal(a.seconds(), 8, 'second');
        assert.equal(a.milliseconds(), 9, 'milliseconds');
    });

    test('getters programmatic', function (assert) {
        var a = moment([2011, 9, 12, 6, 7, 8, 9]);
        assert.equal(a.get('year'), 2011, 'year');
        assert.equal(a.get('month'), 9, 'month');
        assert.equal(a.get('date'), 12, 'date');
        assert.equal(a.get('day'), 3, 'day');
        assert.equal(a.get('hour'), 6, 'hour');
        assert.equal(a.get('minute'), 7, 'minute');
        assert.equal(a.get('second'), 8, 'second');
        assert.equal(a.get('milliseconds'), 9, 'milliseconds');

        //actual getters tested elsewhere
        assert.equal(a.get('weekday'), a.weekday(), 'weekday');
        assert.equal(a.get('isoWeekday'), a.isoWeekday(), 'isoWeekday');
        assert.equal(a.get('week'), a.week(), 'week');
        assert.equal(a.get('isoWeek'), a.isoWeek(), 'isoWeek');
        assert.equal(a.get('dayOfYear'), a.dayOfYear(), 'dayOfYear');

        //getter no longer sets values when passed an object
        assert.equal(
            moment([2016, 0, 1]).get({ year: 2015 }).year(),
            2016,
            'getter no longer sets values when passed an object'
        );
    });

    test('setters plural', function (assert) {
        var a = moment();
        test.expectedDeprecations(
            'years accessor',
            'months accessor',
            'dates accessor'
        );

        a.years(2011);
        a.months(9);
        a.dates(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(9);
        assert.equal(a.years(), 2011, 'years');
        assert.equal(a.months(), 9, 'months');
        assert.equal(a.dates(), 12, 'dates');
        assert.equal(a.days(), 3, 'days');
        assert.equal(a.hours(), 6, 'hours');
        assert.equal(a.minutes(), 7, 'minutes');
        assert.equal(a.seconds(), 8, 'seconds');
        assert.equal(a.milliseconds(), 9, 'milliseconds');
    });

    test('setters singular', function (assert) {
        var a = moment();
        a.year(2011);
        a.month(9);
        a.date(12);
        a.hour(6);
        a.minute(7);
        a.second(8);
        a.millisecond(9);
        assert.equal(a.year(), 2011, 'year');
        assert.equal(a.month(), 9, 'month');
        assert.equal(a.date(), 12, 'date');
        assert.equal(a.day(), 3, 'day');
        assert.equal(a.hour(), 6, 'hour');
        assert.equal(a.minute(), 7, 'minute');
        assert.equal(a.second(), 8, 'second');
        assert.equal(a.millisecond(), 9, 'milliseconds');
    });

    test('setters', function (assert) {
        var a = moment();
        a.year(2011);
        a.month(9);
        a.date(12);
        a.hours(6);
        a.minutes(7);
        a.seconds(8);
        a.milliseconds(9);
        assert.equal(a.year(), 2011, 'year');
        assert.equal(a.month(), 9, 'month');
        assert.equal(a.date(), 12, 'date');
        assert.equal(a.day(), 3, 'day');
        assert.equal(a.hours(), 6, 'hour');
        assert.equal(a.minutes(), 7, 'minute');
        assert.equal(a.seconds(), 8, 'second');
        assert.equal(a.milliseconds(), 9, 'milliseconds');

        // Test month() behavior. See https://github.com/timrwood/moment/pull/822
        a = moment('20130531', 'YYYYMMDD');
        a.month(3);
        assert.equal(a.month(), 3, 'month edge case');
    });

    test('setters should handle garbage input', function (assert) {
        var a = moment();
        a.set('year', 2011);
        a.set('month', 9);
        a.set('date', 12);
        a.set('hours', 6);
        a.set('minutes', 7);
        a.set('seconds', 8);
        a.set('milliseconds', 9);

        a.year(undefined);
        a.month('foo');
        a.date(null);
        a.day({ a: 2, b: 3 });
        a.hours('[1]');
        a.minutes(undefined);
        a.seconds(null);
        a.milliseconds(NaN);

        assert.equal(a.year(), 2011, 'year - provided undefined');
        assert.equal(a.month(), 9, 'month - provided null');
        assert.equal(a.date(), 12, 'date - provided [1]');
        assert.equal(a.day(), 3, 'day - provided Infinity');
        assert.equal(a.hours(), 6, 'hour - provided new Date');
        assert.equal(a.minutes(), 7, 'minute - provided {a:1,b:2}');
        assert.equal(a.seconds(), 8, 'second - provided foo');
        assert.equal(a.milliseconds(), 9, 'milliseconds - provided Infinity');
    });

    test('setter programmatic', function (assert) {
        var a = moment();
        a.set('year', 2011);
        a.set('month', 9);
        a.set('date', 12);
        a.set('hours', 6);
        a.set('minutes', 7);
        a.set('seconds', 8);
        a.set('milliseconds', 9);
        assert.equal(a.year(), 2011, 'year');
        assert.equal(a.month(), 9, 'month');
        assert.equal(a.date(), 12, 'date');
        assert.equal(a.day(), 3, 'day');
        assert.equal(a.hours(), 6, 'hour');
        assert.equal(a.minutes(), 7, 'minute');
        assert.equal(a.seconds(), 8, 'second');
        assert.equal(a.milliseconds(), 9, 'milliseconds');

        // Test month() behavior. See https://github.com/timrwood/moment/pull/822
        a = moment('20130531', 'YYYYMMDD');
        a.month(3);
        assert.equal(a.month(), 3, 'month edge case');
    });

    test('setters programatic with weeks', function (assert) {
        var a = moment();
        a.set('weekYear', 2001);
        a.set('week', 49);
        a.set('day', 4);

        assert.equal(a.weekYear(), 2001, 'weekYear');
        assert.equal(a.week(), 49, 'week');
        assert.equal(a.day(), 4, 'day');

        a.set('weekday', 1);
        assert.equal(a.weekday(), 1, 'weekday');
    });

    test('setters programatic with weeks ISO', function (assert) {
        var a = moment();
        a.set('isoWeekYear', 2001);
        a.set('isoWeek', 49);
        a.set('isoWeekday', 4);

        assert.equal(a.isoWeekYear(), 2001, 'isoWeekYear');
        assert.equal(a.isoWeek(), 49, 'isoWeek');
        assert.equal(a.isoWeekday(), 4, 'isoWeekday');
    });

    test('setters strings', function (assert) {
        var a = moment([2012]).locale('en');
        assert.equal(a.clone().day(0).day('Wednesday').day(), 3, 'day full name');
        assert.equal(a.clone().day(0).day('Wed').day(), 3, 'day short name');
        assert.equal(a.clone().day(0).day('We').day(), 3, 'day minimal name');
        assert.equal(a.clone().day(0).day('invalid').day(), 0, 'invalid day name');
        assert.equal(
            a.clone().month(0).month('April').month(),
            3,
            'month full name'
        );
        assert.equal(
            a.clone().month(0).month('Apr').month(),
            3,
            'month short name'
        );
        assert.equal(
            a.clone().month(0).month('invalid').month(),
            0,
            'invalid month name'
        );
    });

    test('setters - falsey values', function (assert) {
        var a = moment();
        // ensure minutes wasn't coincidentally 0 already
        a.minutes(1);
        a.minutes(0);
        assert.equal(a.minutes(), 0, 'falsey value');
    });

    test('chaining setters', function (assert) {
        var a = moment();
        a.year(2011).month(9).date(12).hours(6).minutes(7).seconds(8);
        assert.equal(a.year(), 2011, 'year');
        assert.equal(a.month(), 9, 'month');
        assert.equal(a.date(), 12, 'date');
        assert.equal(a.day(), 3, 'day');
        assert.equal(a.hours(), 6, 'hour');
        assert.equal(a.minutes(), 7, 'minute');
        assert.equal(a.seconds(), 8, 'second');
    });

    test('setter with multiple unit values', function (assert) {
        var a = moment(),
            c;
        a.set({
            year: 2011,
            month: 9,
            date: 12,
            hours: 6,
            minutes: 7,
            seconds: 8,
            milliseconds: 9,
        });
        assert.equal(a.year(), 2011, 'year');
        assert.equal(a.month(), 9, 'month');
        assert.equal(a.date(), 12, 'date');
        assert.equal(a.day(), 3, 'day');
        assert.equal(a.hours(), 6, 'hour');
        assert.equal(a.minutes(), 7, 'minute');
        assert.equal(a.seconds(), 8, 'second');
        assert.equal(a.milliseconds(), 9, 'milliseconds');

        c = moment([2016, 0, 1]);
        assert.equal(
            c.set({ weekYear: 2016 }).weekYear(),
            2016,
            'week year correctly sets with object syntax'
        );
        assert.equal(
            c.set({ quarter: 3 }).quarter(),
            3,
            'quarter sets correctly with object syntax'
        );
    });

    test('day setter', function (assert) {
        var a = moment([2011, 0, 15]);
        assert.equal(moment(a).day(0).date(), 9, 'set from saturday to sunday');
        assert.equal(moment(a).day(6).date(), 15, 'set from saturday to saturday');
        assert.equal(moment(a).day(3).date(), 12, 'set from saturday to wednesday');

        a = moment([2011, 0, 9]);
        assert.equal(moment(a).day(0).date(), 9, 'set from sunday to sunday');
        assert.equal(moment(a).day(6).date(), 15, 'set from sunday to saturday');
        assert.equal(moment(a).day(3).date(), 12, 'set from sunday to wednesday');

        a = moment([2011, 0, 12]);
        assert.equal(moment(a).day(0).date(), 9, 'set from wednesday to sunday');
        assert.equal(moment(a).day(6).date(), 15, 'set from wednesday to saturday');
        assert.equal(
            moment(a).day(3).date(),
            12,
            'set from wednesday to wednesday'
        );

        assert.equal(
            moment(a).day(-7).date(),
            2,
            'set from wednesday to last sunday'
        );
        assert.equal(
            moment(a).day(-1).date(),
            8,
            'set from wednesday to last saturday'
        );
        assert.equal(
            moment(a).day(-4).date(),
            5,
            'set from wednesday to last wednesday'
        );

        assert.equal(
            moment(a).day(7).date(),
            16,
            'set from wednesday to next sunday'
        );
        assert.equal(
            moment(a).day(13).date(),
            22,
            'set from wednesday to next saturday'
        );
        assert.equal(
            moment(a).day(10).date(),
            19,
            'set from wednesday to next wednesday'
        );

        assert.equal(
            moment(a).day(14).date(),
            23,
            'set from wednesday to second next sunday'
        );
        assert.equal(
            moment(a).day(20).date(),
            29,
            'set from wednesday to second next saturday'
        );
        assert.equal(
            moment(a).day(17).date(),
            26,
            'set from wednesday to second next wednesday'
        );
    });

    test('year setter', function (assert) {
        var a = moment([2015, 3, 15]),
            b,
            c,
            d,
            e;
        assert.equal(
            moment(a).year(2016).format('YYYY-MM-DD'),
            '2016-04-15',
            'set from 2015 to 2016'
        );
        assert.equal(
            moment(a).year(2011).format('YYYY-MM-DD'),
            '2011-04-15',
            'set from 2015 to 2011'
        );

        b = moment([2012, 1, 29]);
        assert.equal(
            moment(b).year(2017).format('YYYY-MM-DD'),
            '2017-02-28',
            'set from last day of february on a leap year to a non leap year'
        );
        assert.equal(
            moment(b).year(2004).format('YYYY-MM-DD'),
            '2004-02-29',
            'set from last day of february on a leap year to a leap year'
        );

        c = moment([2012, 9, 4]);
        assert.equal(
            moment(c).year(2017).format('YYYY-MM-DD'),
            '2017-10-04',
            'set from a random day on a leap year to a non leap year'
        );
        assert.equal(
            moment(c).year(2004).format('YYYY-MM-DD'),
            '2004-10-04',
            'set from a random day on a leap year to a leap year'
        );

        d = moment([2020, 1, 29]);
        assert.equal(
            moment(d).year('2020').format('YYYY-MM-DD'),
            '2020-02-29',
            'set from last day of february in 2020 to the same year, provided as string'
        );

        e = moment([2012, 1, 29]);
        assert.equal(
            moment(e).year('2020').format('YYYY-MM-DD'),
            '2020-02-29',
            'set from last day of february on a leap year to 2020, provided as string'
        );
    });

    test('object set ordering', function (assert) {
        var a = moment([2016, 3, 30]),
            b,
            c;
        assert.equal(
            a.set({ date: 31, month: 4 }).date(),
            31,
            'setter order automatically arranged by size'
        );
        b = moment([2015, 1, 28]);
        assert.equal(
            b.set({ date: 29, year: 2016 }).format('YYYY-MM-DD'),
            '2016-02-29',
            'year is prioritized over date'
        );
        //check a nonexistent time in US isn't set
        c = moment([2016, 2, 13]);
        c.set({
            hour: 2,
            minutes: 30,
            date: 14,
        });
        assert.equal(
            c.format('YYYY-MM-DDTHH:mm'),
            '2016-03-14T02:30',
            'setting hours, minutes date puts date first allowing time set to work'
        );
    });

    test('string setters', function (assert) {
        var a = moment();
        a.year('2011');
        a.month('9');
        a.date('12');
        a.hours('6');
        a.minutes('7');
        a.seconds('8');
        a.milliseconds('9');
        assert.equal(a.year(), 2011, 'year');
        assert.equal(a.month(), 9, 'month');
        assert.equal(a.date(), 12, 'date');
        assert.equal(a.day(), 3, 'day');
        assert.equal(a.hours(), 6, 'hour');
        assert.equal(a.minutes(), 7, 'minute');
        assert.equal(a.seconds(), 8, 'second');
        assert.equal(a.milliseconds(), 9, 'milliseconds');
    });

    test('setters across DST +1', function (assert) {
        var oldUpdateOffset = moment.updateOffset,
            // Based on a real story somewhere in America/Los_Angeles
            dstAt = moment('2014-03-09T02:00:00-08:00').parseZone(),
            m;

        moment.updateOffset = function (mom, keepTime) {
            if (mom.isBefore(dstAt)) {
                mom.utcOffset(-8, keepTime);
            } else {
                mom.utcOffset(-7, keepTime);
            }
        };

        m = moment('2014-03-15T00:00:00-07:00').parseZone();
        m.year(2013);
        assert.equal(m.format(), '2013-03-15T00:00:00-08:00', 'year across +1');

        m = moment('2014-03-15T00:00:00-07:00').parseZone();
        m.month(0);
        assert.equal(m.format(), '2014-01-15T00:00:00-08:00', 'month across +1');

        m = moment('2014-03-15T00:00:00-07:00').parseZone();
        m.date(1);
        assert.equal(m.format(), '2014-03-01T00:00:00-08:00', 'date across +1');

        m = moment('2014-03-09T03:05:00-07:00').parseZone();
        m.hour(0);
        assert.equal(m.format(), '2014-03-09T00:05:00-08:00', 'hour across +1');

        moment.updateOffset = oldUpdateOffset;
    });

    test('setters across DST -1', function (assert) {
        var oldUpdateOffset = moment.updateOffset,
            // Based on a real story somewhere in America/Los_Angeles
            dstAt = moment('2014-11-02T02:00:00-07:00').parseZone(),
            m;

        moment.updateOffset = function (mom, keepTime) {
            if (mom.isBefore(dstAt)) {
                mom.utcOffset(-7, keepTime);
            } else {
                mom.utcOffset(-8, keepTime);
            }
        };

        m = moment('2014-11-15T00:00:00-08:00').parseZone();
        m.year(2013);
        assert.equal(m.format(), '2013-11-15T00:00:00-07:00', 'year across -1');

        m = moment('2014-11-15T00:00:00-08:00').parseZone();
        m.month(0);
        assert.equal(m.format(), '2014-01-15T00:00:00-07:00', 'month across -1');

        m = moment('2014-11-15T00:00:00-08:00').parseZone();
        m.date(1);
        assert.equal(m.format(), '2014-11-01T00:00:00-07:00', 'date across -1');

        m = moment('2014-11-02T03:30:00-08:00').parseZone();
        m.hour(0);
        assert.equal(m.format(), '2014-11-02T00:30:00-07:00', 'hour across -1');

        moment.updateOffset = oldUpdateOffset;
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('instanceof');

    test('instanceof', function (assert) {
        var extend = function (a, b) {
            var i;
            for (i in b) {
                a[i] = b[i];
            }
            return a;
        };

        assert.equal(moment() instanceof moment, true, 'simple moment object');
        assert.equal(
            extend({}, moment()) instanceof moment,
            false,
            'extended moment object'
        );
        assert.equal(moment(null) instanceof moment, true, 'invalid moment object');

        assert.equal(
            new Date() instanceof moment,
            false,
            'date object is not moment object'
        );
        assert.equal(
            Object instanceof moment,
            false,
            'Object is not moment object'
        );
        assert.equal('foo' instanceof moment, false, 'string is not moment object');
        assert.equal(1 instanceof moment, false, 'number is not moment object');
        assert.equal(NaN instanceof moment, false, 'NaN is not moment object');
        assert.equal(null instanceof moment, false, 'null is not moment object');
        assert.equal(
            undefined instanceof moment,
            false,
            'undefined is not moment object'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('invalid');

    test('invalid', function (assert) {
        var m = moment.invalid();
        assert.equal(m.isValid(), false);
        assert.equal(m.parsingFlags().userInvalidated, true);
        assert.ok(isNaN(m.valueOf()));
    });

    test('invalid with existing flag', function (assert) {
        var m = moment.invalid({ invalidMonth: 'whatchamacallit' });
        assert.equal(m.isValid(), false);
        assert.equal(m.parsingFlags().userInvalidated, false);
        assert.equal(m.parsingFlags().invalidMonth, 'whatchamacallit');
        assert.ok(isNaN(m.valueOf()));
    });

    test('invalid with custom flag', function (assert) {
        var m = moment.invalid({ tooBusyWith: 'reiculating splines' });
        assert.equal(m.isValid(), false);
        assert.equal(m.parsingFlags().userInvalidated, false);
        assert.equal(m.parsingFlags().tooBusyWith, 'reiculating splines');
        assert.ok(isNaN(m.valueOf()));
    });

    test('invalid operations', function (assert) {
        var invalids = [
                moment.invalid(),
                moment('xyz', 'l'),
                moment('2015-01-35', 'YYYY-MM-DD'),
                moment('2015-01-25 a', 'YYYY-MM-DD', true),
            ],
            i,
            invalid,
            valid = moment();

        test.expectedDeprecations('moment().min', 'moment().max', 'isDSTShifted');

        for (i = 0; i < invalids.length; ++i) {
            invalid = invalids[i];

            assert.ok(
                !invalid.clone().add(5, 'hours').isValid(),
                'invalid.add is invalid'
            );
            assert.equal(
                invalid.calendar(),
                'Invalid date',
                "invalid.calendar is 'Invalid date'"
            );
            assert.ok(!invalid.clone().isValid(), 'invalid.clone is invalid');
            assert.ok(isNaN(invalid.diff(valid)), 'invalid.diff(valid) is NaN');
            assert.ok(isNaN(valid.diff(invalid)), 'valid.diff(invalid) is NaN');
            assert.ok(isNaN(invalid.diff(invalid)), 'invalid.diff(invalid) is NaN');
            assert.ok(
                !invalid.clone().endOf('month').isValid(),
                'invalid.endOf is invalid'
            );
            assert.equal(
                invalid.format(),
                'Invalid date',
                "invalid.format is 'Invalid date'"
            );
            assert.equal(invalid.from(), 'Invalid date');
            assert.equal(invalid.from(valid), 'Invalid date');
            assert.equal(valid.from(invalid), 'Invalid date');
            assert.equal(invalid.fromNow(), 'Invalid date');
            assert.equal(invalid.to(), 'Invalid date');
            assert.equal(invalid.to(valid), 'Invalid date');
            assert.equal(valid.to(invalid), 'Invalid date');
            assert.equal(invalid.toNow(), 'Invalid date');
            assert.ok(isNaN(invalid.get('year')), 'invalid.get is NaN');
            // TODO invalidAt
            assert.ok(!invalid.isAfter(valid));
            assert.ok(!valid.isAfter(invalid));
            assert.ok(!invalid.isAfter(invalid));
            assert.ok(!invalid.isBefore(valid));
            assert.ok(!valid.isBefore(invalid));
            assert.ok(!invalid.isBefore(invalid));
            assert.ok(!invalid.isBetween(valid, valid));
            assert.ok(!valid.isBetween(invalid, valid));
            assert.ok(!valid.isBetween(valid, invalid));
            assert.ok(!invalid.isSame(invalid));
            assert.ok(!invalid.isSame(valid));
            assert.ok(!valid.isSame(invalid));
            assert.ok(!invalid.isValid());
            assert.equal(invalid.locale(), 'en');
            assert.equal(invalid.localeData()._abbr, 'en');
            assert.ok(!invalid.clone().max(valid).isValid());
            assert.ok(!valid.clone().max(invalid).isValid());
            assert.ok(!invalid.clone().max(invalid).isValid());
            assert.ok(!invalid.clone().min(valid).isValid());
            assert.ok(!valid.clone().min(invalid).isValid());
            assert.ok(!invalid.clone().min(invalid).isValid());
            assert.ok(!moment.min(invalid, valid).isValid());
            assert.ok(!moment.min(valid, invalid).isValid());
            assert.ok(!moment.max(invalid, valid).isValid());
            assert.ok(!moment.max(valid, invalid).isValid());
            assert.ok(!invalid.clone().set('year', 2005).isValid());
            assert.ok(!invalid.clone().startOf('month').isValid());

            assert.ok(!invalid.clone().subtract(5, 'days').isValid());
            assert.deepEqual(invalid.toArray(), [
                NaN,
                NaN,
                NaN,
                NaN,
                NaN,
                NaN,
                NaN,
            ]);
            assert.deepEqual(invalid.toObject(), {
                years: NaN,
                months: NaN,
                date: NaN,
                hours: NaN,
                minutes: NaN,
                seconds: NaN,
                milliseconds: NaN,
            });
            assert.ok(moment.isDate(invalid.toDate()));
            assert.ok(isNaN(invalid.toDate().valueOf()));
            assert.equal(invalid.toJSON(), null);
            assert.equal(invalid.toString(), 'Invalid date');
            assert.ok(isNaN(invalid.unix()));
            assert.ok(isNaN(invalid.valueOf()));

            assert.ok(isNaN(invalid.year()));
            assert.ok(isNaN(invalid.weekYear()));
            assert.ok(isNaN(invalid.isoWeekYear()));
            assert.ok(isNaN(invalid.quarter()));
            assert.ok(isNaN(invalid.quarters()));
            assert.ok(isNaN(invalid.month()));
            assert.ok(isNaN(invalid.daysInMonth()));
            assert.ok(isNaN(invalid.week()));
            assert.ok(isNaN(invalid.weeks()));
            assert.ok(isNaN(invalid.isoWeek()));
            assert.ok(isNaN(invalid.isoWeeks()));
            assert.ok(isNaN(invalid.weeksInYear()));
            assert.ok(isNaN(invalid.isoWeeksInYear()));
            assert.ok(isNaN(invalid.date()));
            assert.ok(isNaN(invalid.day()));
            assert.ok(isNaN(invalid.days()));
            assert.ok(isNaN(invalid.weekday()));
            assert.ok(isNaN(invalid.isoWeekday()));
            assert.ok(isNaN(invalid.dayOfYear()));
            assert.ok(isNaN(invalid.hour()));
            assert.ok(isNaN(invalid.hours()));
            assert.ok(isNaN(invalid.minute()));
            assert.ok(isNaN(invalid.minutes()));
            assert.ok(isNaN(invalid.second()));
            assert.ok(isNaN(invalid.seconds()));
            assert.ok(isNaN(invalid.millisecond()));
            assert.ok(isNaN(invalid.milliseconds()));
            assert.ok(isNaN(invalid.utcOffset()));

            assert.ok(!invalid.clone().year(2001).isValid());
            assert.ok(!invalid.clone().weekYear(2001).isValid());
            assert.ok(!invalid.clone().isoWeekYear(2001).isValid());
            assert.ok(!invalid.clone().quarter(1).isValid());
            assert.ok(!invalid.clone().quarters(1).isValid());
            assert.ok(!invalid.clone().month(1).isValid());
            assert.ok(!invalid.clone().week(1).isValid());
            assert.ok(!invalid.clone().weeks(1).isValid());
            assert.ok(!invalid.clone().isoWeek(1).isValid());
            assert.ok(!invalid.clone().isoWeeks(1).isValid());
            assert.ok(!invalid.clone().date(1).isValid());
            assert.ok(!invalid.clone().day(1).isValid());
            assert.ok(!invalid.clone().days(1).isValid());
            assert.ok(!invalid.clone().weekday(1).isValid());
            assert.ok(!invalid.clone().isoWeekday(1).isValid());
            assert.ok(!invalid.clone().dayOfYear(1).isValid());
            assert.ok(!invalid.clone().hour(1).isValid());
            assert.ok(!invalid.clone().hours(1).isValid());
            assert.ok(!invalid.clone().minute(1).isValid());
            assert.ok(!invalid.clone().minutes(1).isValid());
            assert.ok(!invalid.clone().second(1).isValid());
            assert.ok(!invalid.clone().seconds(1).isValid());
            assert.ok(!invalid.clone().millisecond(1).isValid());
            assert.ok(!invalid.clone().milliseconds(1).isValid());
            assert.ok(!invalid.clone().utcOffset(1).isValid());

            assert.ok(!invalid.clone().utc().isValid());
            assert.ok(!invalid.clone().local().isValid());
            assert.ok(!invalid.clone().parseZone('05:30').isValid());
            assert.ok(!invalid.hasAlignedHourOffset());
            assert.ok(!invalid.isDST());
            assert.ok(!invalid.isDSTShifted());
            assert.ok(!invalid.isLocal());
            assert.ok(!invalid.isUtcOffset());
            assert.ok(!invalid.isUtc());
            assert.ok(!invalid.isUTC());

            assert.ok(!invalid.isLeapYear());

            assert.equal(
                moment.duration({ from: invalid, to: valid }).asMilliseconds(),
                0
            );
            assert.equal(
                moment.duration({ from: valid, to: invalid }).asMilliseconds(),
                0
            );
            assert.equal(
                moment.duration({ from: invalid, to: invalid }).asMilliseconds(),
                0
            );
        }
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('is after');

    test('is after without units', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isAfter(moment(new Date(2012, 3, 2, 3, 5, 5, 10))),
            false,
            'year is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 3, 2, 3, 3, 5, 10))),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10))),
            false,
            'month is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10))),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10))),
            false,
            'day is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 1, 3, 4, 5, 10))),
            true,
            'day is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10))),
            false,
            'hour is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 2, 4, 5, 10))),
            true,
            'hour is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10))),
            false,
            'minute is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10))),
            true,
            'minute is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10))),
            false,
            'second is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 11))),
            true,
            'second is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10))),
            false,
            'millisecond match'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 11))),
            false,
            'millisecond is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 9))),
            true,
            'millisecond is earlier'
        );
        assert.equal(m.isAfter(m), false, 'moments are not after themselves');
        assert.equal(+m, +mCopy, 'isAfter second should not change moment');
    });

    test('is after year', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'),
            false,
            'year match'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'years'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isAfter(moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'),
            false,
            'year is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'),
            false,
            'exact start of year'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'),
            false,
            'exact end of year'
        );
        assert.equal(
            m.isAfter(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'),
            false,
            'start of next year'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'),
            true,
            'end of previous year'
        );
        assert.equal(
            m.isAfter(moment(new Date(1980, 11, 31, 23, 59, 59, 999)), 'year'),
            true,
            'end of year far before'
        );
        assert.equal(
            m.isAfter(m, 'year'),
            false,
            'same moments are not after the same year'
        );
        assert.equal(+m, +mCopy, 'isAfter year should not change moment');
    });

    test('is after month', function (assert) {
        var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)),
            mCopy = moment(m);
        assert.equal(
            m.isAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'),
            false,
            'month match'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'months'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isAfter(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'),
            false,
            'year is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'),
            false,
            'month is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'),
            false,
            'exact start of month'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'),
            false,
            'exact end of month'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'),
            false,
            'start of next month'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'),
            true,
            'end of previous month'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 12, 31, 23, 59, 59, 999)), 'month'),
            true,
            'later month but earlier year'
        );
        assert.equal(
            m.isAfter(m, 'month'),
            false,
            'same moments are not after the same month'
        );
        assert.equal(+m, +mCopy, 'isAfter month should not change moment');
    });

    test('is after day', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 7, 8, 9, 10)), 'day'),
            false,
            'day match'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'days'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isAfter(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'day'),
            false,
            'year is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'day'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 4, 2, 7, 8, 9, 10)), 'day'),
            false,
            'month is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 3, 7, 8, 9, 10)), 'day'),
            false,
            'day is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 1, 7, 8, 9, 10)), 'day'),
            true,
            'day is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 0, 0, 0, 0)), 'day'),
            false,
            'exact start of day'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 23, 59, 59, 999)), 'day'),
            false,
            'exact end of day'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 3, 0, 0, 0, 0)), 'day'),
            false,
            'start of next day'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 1, 23, 59, 59, 999)), 'day'),
            true,
            'end of previous day'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 3, 10, 0, 0, 0, 0)), 'day'),
            true,
            'later day but earlier year'
        );
        assert.equal(
            m.isAfter(m, 'day'),
            false,
            'same moments are not after the same day'
        );
        assert.equal(+m, +mCopy, 'isAfter day should not change moment');
    });

    test('is after hour', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'hour match'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hours'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isAfter(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'year is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hour'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 4, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'month is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 3, 3, 8, 9, 10)), 'hour'),
            false,
            'day is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 1, 3, 8, 9, 10)), 'hour'),
            true,
            'day is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 4, 8, 9, 10)), 'hour'),
            false,
            'hour is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 0, 0, 0)), 'hour'),
            false,
            'exact start of hour'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 59, 59, 999)), 'hour'),
            false,
            'exact end of hour'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 4, 0, 0, 0)), 'hour'),
            false,
            'start of next hour'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 2, 59, 59, 999)), 'hour'),
            true,
            'end of previous hour'
        );
        assert.equal(
            m.isAfter(m, 'hour'),
            false,
            'same moments are not after the same hour'
        );
        assert.equal(+m, +mCopy, 'isAfter hour should not change moment');
    });

    test('is after minute', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 9, 10)), 'minute'),
            false,
            'minute match'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minutes'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minute'),
            false,
            'year is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minute'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 9, 10)), 'minute'),
            false,
            'month is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 9, 10)), 'minute'),
            false,
            'day is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 1, 3, 4, 9, 10)), 'minute'),
            true,
            'day is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 9, 10)), 'minute'),
            false,
            'hour is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 2, 4, 9, 10)), 'minute'),
            true,
            'hour is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 9, 10)), 'minute'),
            false,
            'minute is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 9, 10)), 'minute'),
            true,
            'minute is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 0, 0)), 'minute'),
            false,
            'exact start of minute'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 59, 999)), 'minute'),
            false,
            'exact end of minute'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 0, 0)), 'minute'),
            false,
            'start of next minute'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 59, 999)), 'minute'),
            true,
            'end of previous minute'
        );
        assert.equal(
            m.isAfter(m, 'minute'),
            false,
            'same moments are not after the same minute'
        );
        assert.equal(+m, +mCopy, 'isAfter minute should not change moment');
    });

    test('is after second', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'second'),
            false,
            'second match'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'seconds'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'second'),
            false,
            'year is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'second'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'second'),
            false,
            'month is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'second'),
            false,
            'day is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'second'),
            true,
            'day is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'second'),
            false,
            'hour is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'second'),
            true,
            'hour is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'second'),
            false,
            'minute is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'second'),
            true,
            'minute is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'second'),
            false,
            'second is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'second'),
            true,
            'second is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 0)), 'second'),
            false,
            'exact start of second'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 999)), 'second'),
            false,
            'exact end of second'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 0)), 'second'),
            false,
            'start of next second'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 999)), 'second'),
            true,
            'end of previous second'
        );
        assert.equal(
            m.isAfter(m, 'second'),
            false,
            'same moments are not after the same second'
        );
        assert.equal(+m, +mCopy, 'isAfter second should not change moment');
    });

    test('is after millisecond', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'),
            false,
            'millisecond match'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'),
            false,
            'year is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'),
            false,
            'month is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'),
            false,
            'day is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'),
            true,
            'day is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'),
            false,
            'hour is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'),
            true,
            'hour is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'),
            false,
            'minute is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'),
            true,
            'minute is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'),
            false,
            'second is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'),
            true,
            'second is earlier'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'),
            false,
            'millisecond is later'
        );
        assert.equal(
            m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'),
            true,
            'millisecond is earlier'
        );
        assert.equal(
            m.isAfter(m, 'millisecond'),
            false,
            'same moments are not after the same millisecond'
        );
        assert.equal(+m, +mCopy, 'isAfter millisecond should not change moment');
    });

    test('is after invalid', function (assert) {
        var m = moment(),
            invalid = moment.invalid();
        assert.equal(
            m.isAfter(invalid),
            false,
            'valid moment is not after invalid moment'
        );
        assert.equal(
            invalid.isAfter(m),
            false,
            'invalid moment is not after valid moment'
        );
        assert.equal(m.isAfter(invalid, 'year'), false, 'invalid moment year');
        assert.equal(m.isAfter(invalid, 'month'), false, 'invalid moment month');
        assert.equal(m.isAfter(invalid, 'day'), false, 'invalid moment day');
        assert.equal(m.isAfter(invalid, 'hour'), false, 'invalid moment hour');
        assert.equal(m.isAfter(invalid, 'minute'), false, 'invalid moment minute');
        assert.equal(m.isAfter(invalid, 'second'), false, 'invalid moment second');
        assert.equal(
            m.isAfter(invalid, 'milliseconds'),
            false,
            'invalid moment milliseconds'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function isArray(input) {
        return (
            input instanceof Array ||
            Object.prototype.toString.call(input) === '[object Array]'
        );
    }

    test('isArray recognizes Array objects', function (assert) {
        assert.ok(isArray([1, 2, 3]), 'array args');
        assert.ok(isArray([]), 'empty array');
        assert.ok(isArray(new Array(1, 2, 3)), 'array constructor');
    });

    test('isArray rejects non-Array objects', function (assert) {
        assert.ok(!isArray(), 'nothing');
        assert.ok(!isArray(undefined), 'undefined');
        assert.ok(!isArray(null), 'null');
        assert.ok(!isArray(123), 'number');
        assert.ok(!isArray('[1,2,3]'), 'string');
        assert.ok(!isArray(new Date()), 'date');
        assert.ok(!isArray({ a: 1, b: 2 }), 'object');
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('is before');

    test('is after without units', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isBefore(moment(new Date(2012, 3, 2, 3, 5, 5, 10))),
            true,
            'year is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2010, 3, 2, 3, 3, 5, 10))),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10))),
            true,
            'month is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10))),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10))),
            true,
            'day is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 1, 3, 4, 5, 10))),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10))),
            true,
            'hour is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 2, 4, 5, 10))),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10))),
            true,
            'minute is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10))),
            false,
            'minute is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10))),
            true,
            'second is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 11))),
            false,
            'second is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10))),
            false,
            'millisecond match'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 11))),
            true,
            'millisecond is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 9))),
            false,
            'millisecond is earlier'
        );
        assert.equal(m.isBefore(m), false, 'moments are not before themselves');
        assert.equal(+m, +mCopy, 'isBefore second should not change moment');
    });

    test('is before year', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'),
            false,
            'year match'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'years'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBefore(moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'),
            true,
            'year is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'),
            false,
            'exact start of year'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'),
            false,
            'exact end of year'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'),
            true,
            'start of next year'
        );
        assert.equal(
            m.isBefore(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'),
            false,
            'end of previous year'
        );
        assert.equal(
            m.isBefore(moment(new Date(1980, 11, 31, 23, 59, 59, 999)), 'year'),
            false,
            'end of year far before'
        );
        assert.equal(
            m.isBefore(m, 'year'),
            false,
            'same moments are not before the same year'
        );
        assert.equal(+m, +mCopy, 'isBefore year should not change moment');
    });

    test('is before month', function (assert) {
        var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)),
            mCopy = moment(m);
        assert.equal(
            m.isBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'),
            false,
            'month match'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'months'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'),
            true,
            'year is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'),
            true,
            'month is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'),
            false,
            'exact start of month'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'),
            false,
            'exact end of month'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'),
            true,
            'start of next month'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'),
            false,
            'end of previous month'
        );
        assert.equal(
            m.isBefore(moment(new Date(2010, 12, 31, 23, 59, 59, 999)), 'month'),
            false,
            'later month but earlier year'
        );
        assert.equal(
            m.isBefore(m, 'month'),
            false,
            'same moments are not before the same month'
        );
        assert.equal(+m, +mCopy, 'isBefore month should not change moment');
    });

    test('is before day', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 7, 8, 9, 10)), 'day'),
            false,
            'day match'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'days'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'day'),
            true,
            'year is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'day'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 4, 2, 7, 8, 9, 10)), 'day'),
            true,
            'month is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 3, 7, 8, 9, 10)), 'day'),
            true,
            'day is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 1, 7, 8, 9, 10)), 'day'),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 0, 0, 0, 0)), 'day'),
            false,
            'exact start of day'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 23, 59, 59, 999)), 'day'),
            false,
            'exact end of day'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 3, 0, 0, 0, 0)), 'day'),
            true,
            'start of next day'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 1, 23, 59, 59, 999)), 'day'),
            false,
            'end of previous day'
        );
        assert.equal(
            m.isBefore(moment(new Date(2010, 3, 10, 0, 0, 0, 0)), 'day'),
            false,
            'later day but earlier year'
        );
        assert.equal(
            m.isBefore(m, 'day'),
            false,
            'same moments are not before the same day'
        );
        assert.equal(+m, +mCopy, 'isBefore day should not change moment');
    });

    test('is before hour', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'hour match'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hours'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hour'),
            true,
            'year is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 4, 2, 3, 8, 9, 10)), 'hour'),
            true,
            'month is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 3, 3, 8, 9, 10)), 'hour'),
            true,
            'day is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 1, 3, 8, 9, 10)), 'hour'),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 4, 8, 9, 10)), 'hour'),
            true,
            'hour is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 0, 0, 0)), 'hour'),
            false,
            'exact start of hour'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 59, 59, 999)), 'hour'),
            false,
            'exact end of hour'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 4, 0, 0, 0)), 'hour'),
            true,
            'start of next hour'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 2, 59, 59, 999)), 'hour'),
            false,
            'end of previous hour'
        );
        assert.equal(
            m.isBefore(m, 'hour'),
            false,
            'same moments are not before the same hour'
        );
        assert.equal(+m, +mCopy, 'isBefore hour should not change moment');
    });

    test('is before minute', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 9, 10)), 'minute'),
            false,
            'minute match'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minutes'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minute'),
            true,
            'year is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minute'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 9, 10)), 'minute'),
            true,
            'month is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 9, 10)), 'minute'),
            true,
            'day is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 1, 3, 4, 9, 10)), 'minute'),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 9, 10)), 'minute'),
            true,
            'hour is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 2, 4, 9, 10)), 'minute'),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 9, 10)), 'minute'),
            true,
            'minute is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 9, 10)), 'minute'),
            false,
            'minute is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 0, 0)), 'minute'),
            false,
            'exact start of minute'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 59, 999)), 'minute'),
            false,
            'exact end of minute'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 0, 0)), 'minute'),
            true,
            'start of next minute'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 59, 999)), 'minute'),
            false,
            'end of previous minute'
        );
        assert.equal(
            m.isBefore(m, 'minute'),
            false,
            'same moments are not before the same minute'
        );
        assert.equal(+m, +mCopy, 'isBefore minute should not change moment');
    });

    test('is before second', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'second'),
            false,
            'second match'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'seconds'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'second'),
            true,
            'year is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'second'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'second'),
            true,
            'month is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'second'),
            true,
            'day is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'second'),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'second'),
            true,
            'hour is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'second'),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'second'),
            true,
            'minute is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'second'),
            false,
            'minute is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'second'),
            true,
            'second is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'second'),
            false,
            'second is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 0)), 'second'),
            false,
            'exact start of second'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 999)), 'second'),
            false,
            'exact end of second'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 0)), 'second'),
            true,
            'start of next second'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 999)), 'second'),
            false,
            'end of previous second'
        );
        assert.equal(
            m.isBefore(m, 'second'),
            false,
            'same moments are not before the same second'
        );
        assert.equal(+m, +mCopy, 'isBefore second should not change moment');
    });

    test('is before millisecond', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'),
            false,
            'millisecond match'
        );
        assert.equal(
            m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds'),
            false,
            'plural should work'
        );
        assert.equal(
            m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'),
            true,
            'year is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'),
            true,
            'month is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'),
            true,
            'day is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'),
            true,
            'hour is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'),
            true,
            'minute is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'),
            false,
            'minute is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'),
            true,
            'second is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'),
            false,
            'second is earlier'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'),
            true,
            'millisecond is later'
        );
        assert.equal(
            m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'),
            false,
            'millisecond is earlier'
        );
        assert.equal(
            m.isBefore(m, 'millisecond'),
            false,
            'same moments are not before the same millisecond'
        );
        assert.equal(+m, +mCopy, 'isBefore millisecond should not change moment');
    });

    test('is before invalid', function (assert) {
        var m = moment(),
            invalid = moment.invalid();
        assert.equal(
            m.isBefore(invalid),
            false,
            'valid moment is not before invalid moment'
        );
        assert.equal(
            invalid.isBefore(m),
            false,
            'invalid moment is not before valid moment'
        );
        assert.equal(m.isBefore(invalid, 'year'), false, 'invalid moment year');
        assert.equal(m.isBefore(invalid, 'month'), false, 'invalid moment month');
        assert.equal(m.isBefore(invalid, 'day'), false, 'invalid moment day');
        assert.equal(m.isBefore(invalid, 'hour'), false, 'invalid moment hour');
        assert.equal(m.isBefore(invalid, 'minute'), false, 'invalid moment minute');
        assert.equal(m.isBefore(invalid, 'second'), false, 'invalid moment second');
        assert.equal(
            m.isBefore(invalid, 'milliseconds'),
            false,
            'invalid moment milliseconds'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('is between');

    test('is between without units', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isBetween(
                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10))
            ),
            false,
            'year is later'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2013, 3, 2, 3, 4, 5, 10))
            ),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10))
            ),
            true,
            'year is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10))
            ),
            false,
            'month is later'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 5, 2, 3, 4, 5, 10))
            ),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 2, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 4, 2, 3, 4, 5, 10))
            ),
            true,
            'month is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 1, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10))
            ),
            false,
            'day is later'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 4, 3, 4, 5, 10))
            ),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 1, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 3, 3, 4, 5, 10))
            ),
            true,
            'day is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 1, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10))
            ),
            false,
            'hour is later'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 5, 4, 5, 10))
            ),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 2, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 4, 4, 5, 10))
            ),
            true,
            'hour is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 6, 5, 10))
            ),
            false,
            'minute is later'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 2, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10))
            ),
            false,
            'minute is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 3, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 5, 5, 10))
            ),
            true,
            'minute is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 7, 10))
            ),
            false,
            'second is later'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 3, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10))
            ),
            false,
            'second is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 4, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 6, 10))
            ),
            true,
            'second is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 12))
            ),
            false,
            'millisecond is later'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 8)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10))
            ),
            false,
            'millisecond is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 9)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 11))
            ),
            true,
            'millisecond is between'
        );
        assert.equal(
            m.isBetween(m, m),
            false,
            'moments are not between themselves'
        );
        assert.equal(+m, +mCopy, 'isBetween second should not change moment');
    });

    test('is between without units inclusivity', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10));
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                null,
                '()'
            ),
            false,
            'start and end are excluded, start is equal to moment'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                null,
                '()'
            ),
            false,
            'start and end are excluded, end is equal to moment'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                null,
                '()'
            ),
            true,
            'start and end are excluded, is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                null,
                '()'
            ),
            false,
            'start and end are excluded, is not between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                null,
                '()'
            ),
            false,
            'start and end are excluded, should fail on same start/end date.'
        );

        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                null,
                '(]'
            ),
            false,
            'start is excluded and end is included should fail on same start date'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                null,
                '(]'
            ),
            true,
            'start is excluded and end is included should succeed on end date'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                null,
                '(]'
            ),
            true,
            'start is excluded and end is included, is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                null,
                '(]'
            ),
            false,
            'start is excluded and end is included, is not between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                null,
                '(]'
            ),
            false,
            'start is excluded and end is included, should fail on same start/end date.'
        );

        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                null,
                '[)'
            ),
            true,
            'start is included and end is excluded should succeed on same start date'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                null,
                '[)'
            ),
            false,
            'start is included and end is excluded should fail on same end date'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                null,
                '[)'
            ),
            true,
            'start is included and end is excluded, is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                null,
                '[)'
            ),
            false,
            'start is included and end is excluded, is not between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                null,
                '[)'
            ),
            false,
            'start is included and end is excluded, should fail on same end and start date'
        );

        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                null,
                '[]'
            ),
            true,
            'start and end inclusive should succeed on same start date'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                null,
                '[]'
            ),
            true,
            'start and end inclusive should succeed on same end date'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                null,
                '[]'
            ),
            true,
            'start and end inclusive, is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                null,
                '[]'
            ),
            false,
            'start and end inclusive, is not between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                null,
                '[]'
            ),
            true,
            'start and end inclusive, should handle same end and start date'
        );
    });

    test('is between milliseconds inclusivity', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10));
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                'milliseconds'
            ),
            true,
            'options, no inclusive'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '()'
            ),
            false,
            'start and end are excluded, start is equal to moment'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '()'
            ),
            false,
            'start and end are excluded, end is equal to moment'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '()'
            ),
            true,
            'start and end are excluded, is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '()'
            ),
            false,
            'start and end are excluded, is not between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '()'
            ),
            false,
            'start and end are excluded, should fail on same start/end date.'
        );

        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '(]'
            ),
            false,
            'start is excluded and end is included should fail on same start date'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '(]'
            ),
            true,
            'start is excluded and end is included should succeed on end date'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '(]'
            ),
            true,
            'start is excluded and end is included, is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '(]'
            ),
            false,
            'start is excluded and end is included, is not between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '(]'
            ),
            false,
            'start is excluded and end is included, should fail on same start/end date.'
        );

        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '[)'
            ),
            true,
            'start is included and end is excluded should succeed on same start date'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '[)'
            ),
            false,
            'start is included and end is excluded should fail on same end date'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '[)'
            ),
            true,
            'start is included and end is excluded, is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '[)'
            ),
            false,
            'start is included and end is excluded, is not between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '[)'
            ),
            false,
            'start is included and end is excluded, should fail on same end and start date'
        );

        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '[]'
            ),
            true,
            'start and end inclusive should succeed on same start date'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '[]'
            ),
            true,
            'start and end inclusive should succeed on same end date'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '[]'
            ),
            true,
            'start and end inclusive, is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '[]'
            ),
            false,
            'start and end inclusive, is not between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                'milliseconds',
                '[]'
            ),
            true,
            'start and end inclusive, should handle same end and start date'
        );
    });

    test('is between year', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 5, 6, 7, 8, 9, 10)),
                moment(new Date(2011, 5, 6, 7, 8, 9, 10)),
                'year'
            ),
            false,
            'year match'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),
                moment(new Date(2012, 5, 6, 7, 8, 9, 10)),
                'years'
            ),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),
                moment(new Date(2012, 5, 6, 7, 8, 9, 10)),
                'year'
            ),
            true,
            'year is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 5, 6, 7, 8, 9, 10)),
                moment(new Date(2013, 5, 6, 7, 8, 9, 10)),
                'year'
            ),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),
                moment(new Date(2011, 5, 6, 7, 8, 9, 10)),
                'year'
            ),
            false,
            'year is later'
        );
        assert.equal(
            m.isBetween(m, m, 'year'),
            false,
            'same moments are not between the same year'
        );
        assert.equal(+m, +mCopy, 'isBetween year should not change moment');
    });

    test('is between month', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 6, 7, 8, 9, 10)),
                moment(new Date(2011, 1, 6, 7, 8, 9, 10)),
                'month'
            ),
            false,
            'month match'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 0, 6, 7, 8, 9, 10)),
                moment(new Date(2011, 2, 6, 7, 8, 9, 10)),
                'months'
            ),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 0, 31, 23, 59, 59, 999)),
                moment(new Date(2011, 2, 1, 0, 0, 0, 0)),
                'month'
            ),
            true,
            'month is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 6, 7, 8, 9, 10)),
                moment(new Date(2011, 2, 6, 7, 8, 9, 10)),
                'month'
            ),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 11, 6, 7, 8, 9, 10)),
                moment(new Date(2011, 1, 6, 7, 8, 9, 10)),
                'month'
            ),
            false,
            'month is later'
        );
        assert.equal(
            m.isBetween(m, m, 'month'),
            false,
            'same moments are not between the same month'
        );
        assert.equal(+m, +mCopy, 'isBetween month should not change moment');
    });

    test('is between day', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),
                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),
                'day'
            ),
            false,
            'day match'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),
                moment(new Date(2011, 1, 3, 7, 8, 9, 10)),
                'days'
            ),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),
                moment(new Date(2011, 1, 3, 7, 8, 9, 10)),
                'day'
            ),
            true,
            'day is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),
                moment(new Date(2011, 1, 4, 7, 8, 9, 10)),
                'day'
            ),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),
                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),
                'day'
            ),
            false,
            'day is later'
        );
        assert.equal(
            m.isBetween(m, m, 'day'),
            false,
            'same moments are not between the same day'
        );
        assert.equal(+m, +mCopy, 'isBetween day should not change moment');
    });

    test('is between hour', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 5, 9, 10)),
                moment(new Date(2011, 1, 2, 3, 9, 9, 10)),
                'hour'
            ),
            false,
            'hour match'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 1, 59, 59, 999)),
                moment(new Date(2011, 1, 2, 4, 0, 0, 0)),
                'hours'
            ),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 2, 59, 59, 999)),
                moment(new Date(2011, 1, 2, 4, 0, 0, 0)),
                'hour'
            ),
            true,
            'hour is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),
                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),
                'hour'
            ),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),
                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),
                'hour'
            ),
            false,
            'hour is later'
        );
        assert.equal(
            m.isBetween(m, m, 'hour'),
            false,
            'same moments are not between the same hour'
        );
        assert.equal(+m, +mCopy, 'isBetween hour should not change moment');
    });

    test('is between minute', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 4, 9, 10)),
                moment(new Date(2011, 1, 2, 3, 4, 9, 10)),
                'minute'
            ),
            false,
            'minute match'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 3, 9, 10)),
                moment(new Date(2011, 1, 2, 3, 5, 9, 10)),
                'minutes'
            ),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 3, 59, 999)),
                moment(new Date(2011, 1, 2, 3, 5, 0, 0)),
                'minute'
            ),
            true,
            'minute is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 5, 0, 0)),
                moment(new Date(2011, 1, 2, 3, 8, 9, 10)),
                'minute'
            ),
            false,
            'minute is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 2, 9, 10)),
                moment(new Date(2011, 1, 2, 3, 3, 59, 999)),
                'minute'
            ),
            false,
            'minute is later'
        );
        assert.equal(
            m.isBetween(m, m, 'minute'),
            false,
            'same moments are not between the same minute'
        );
        assert.equal(+m, +mCopy, 'isBetween minute should not change moment');
    });

    test('is between second', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 4, 5, 10)),
                moment(new Date(2011, 1, 2, 3, 4, 5, 10)),
                'second'
            ),
            false,
            'second match'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 4, 4, 10)),
                moment(new Date(2011, 1, 2, 3, 4, 6, 10)),
                'seconds'
            ),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 4, 4, 999)),
                moment(new Date(2011, 1, 2, 3, 4, 6, 0)),
                'second'
            ),
            true,
            'second is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 4, 6, 0)),
                moment(new Date(2011, 1, 2, 3, 4, 7, 10)),
                'second'
            ),
            false,
            'second is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 4, 3, 10)),
                moment(new Date(2011, 1, 2, 3, 4, 4, 999)),
                'second'
            ),
            false,
            'second is later'
        );
        assert.equal(
            m.isBetween(m, m, 'second'),
            false,
            'same moments are not between the same second'
        );
        assert.equal(+m, +mCopy, 'isBetween second should not change moment');
    });

    test('is between millisecond', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
                moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
                'millisecond'
            ),
            false,
            'millisecond match'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 4, 5, 5)),
                moment(new Date(2011, 1, 2, 3, 4, 5, 7)),
                'milliseconds'
            ),
            true,
            'plural should work'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 4, 5, 5)),
                moment(new Date(2011, 1, 2, 3, 4, 5, 7)),
                'millisecond'
            ),
            true,
            'millisecond is between'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 4, 5, 7)),
                moment(new Date(2011, 1, 2, 3, 4, 5, 10)),
                'millisecond'
            ),
            false,
            'millisecond is earlier'
        );
        assert.equal(
            m.isBetween(
                moment(new Date(2011, 1, 2, 3, 4, 5, 4)),
                moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
                'millisecond'
            ),
            false,
            'millisecond is later'
        );
        assert.equal(
            m.isBetween(m, m, 'millisecond'),
            false,
            'same moments are not between the same millisecond'
        );
        assert.equal(+m, +mCopy, 'isBetween millisecond should not change moment');
    });

    test('is between invalid', function (assert) {
        var invalid = moment(NaN),
            valid = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            validFrom = moment(new Date(2010, 1, 2, 3, 4, 5, 6)),
            validTo = moment(new Date(2012, 1, 2, 3, 4, 5, 6));
        assert.equal(
            invalid.isBetween(validFrom, validTo),
            false,
            'this instance invalid'
        );
        assert.equal(
            invalid.isBetween(validFrom, validTo, '[]'),
            false,
            'this instance invalid []'
        );
        assert.equal(
            invalid.isBetween(validFrom, validTo, '[)'),
            false,
            'this instance invalid [)'
        );
        assert.equal(
            invalid.isBetween(validFrom, validTo, '(]'),
            false,
            'this instance invalid (]'
        );
        assert.equal(
            invalid.isBetween(validFrom, validTo, '()'),
            false,
            'this instance invalid ()'
        );

        assert.equal(
            valid.isBetween(invalid, validTo),
            false,
            'from invalid moment'
        );
        assert.equal(
            valid.isBetween(invalid, validTo, '[]'),
            false,
            'from invalid moment []'
        );
        assert.equal(
            valid.isBetween(invalid, validTo, '[)'),
            false,
            'from invalid moment [)'
        );
        assert.equal(
            valid.isBetween(invalid, validTo, '(]'),
            false,
            'from invalid moment (]'
        );
        assert.equal(
            valid.isBetween(invalid, validTo, '()'),
            false,
            'from invalid moment ()'
        );

        assert.equal(
            valid.isBetween(validFrom, invalid),
            false,
            'to invalid moment'
        );
        assert.equal(
            valid.isBetween(validFrom, invalid, '[]'),
            false,
            'to invalid moment []'
        );
        assert.equal(
            valid.isBetween(validFrom, invalid, '[)'),
            false,
            'to invalid moment [)'
        );
        assert.equal(
            valid.isBetween(validFrom, invalid, '(]'),
            false,
            'to invalid moment (]'
        );
        assert.equal(
            valid.isBetween(validFrom, invalid, '()'),
            false,
            'to invalid moment ()'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('is date');

    test('isDate recognizes Date objects', function (assert) {
        assert.ok(moment.isDate(new Date()), 'no args (now)');
        assert.ok(moment.isDate(new Date([2014, 2, 15])), 'array args');
        assert.ok(moment.isDate(new Date('2014-03-15')), 'string args');
        assert.ok(
            moment.isDate(new Date('does NOT look like a date')),
            'invalid date'
        );
    });

    test('isDate rejects non-Date objects', function (assert) {
        assert.ok(!moment.isDate(), 'nothing');
        assert.ok(!moment.isDate(undefined), 'undefined');
        assert.ok(!moment.isDate(null), 'string args');
        assert.ok(!moment.isDate(42), 'number');
        assert.ok(!moment.isDate('2014-03-15'), 'string');
        assert.ok(!moment.isDate([2014, 2, 15]), 'array');
        assert.ok(!moment.isDate({ year: 2014, month: 2, day: 15 }), 'object');
        assert.ok(
            !moment.isDate({
                toString: function () {
                    return '[object Date]';
                },
            }),
            'lying object'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('is moment');

    test('is moment object', function (assert) {
        var MyObj = function () {},
            extend = function (a, b) {
                var i;
                for (i in b) {
                    a[i] = b[i];
                }
                return a;
            };
        MyObj.prototype.toDate = function () {
            return new Date();
        };

        assert.ok(moment.isMoment(moment()), 'simple moment object');
        assert.ok(moment.isMoment(moment(null)), 'invalid moment object');
        assert.ok(
            moment.isMoment(extend({}, moment())),
            'externally cloned moments are moments'
        );
        assert.ok(
            moment.isMoment(extend({}, moment.utc())),
            'externally cloned utc moments are moments'
        );

        assert.ok(!moment.isMoment(new MyObj()), 'myObj is not moment object');
        assert.ok(!moment.isMoment(moment), 'moment function is not moment object');
        assert.ok(!moment.isMoment(new Date()), 'date object is not moment object');
        assert.ok(!moment.isMoment(Object), 'Object is not moment object');
        assert.ok(!moment.isMoment('foo'), 'string is not moment object');
        assert.ok(!moment.isMoment(1), 'number is not moment object');
        assert.ok(!moment.isMoment(NaN), 'NaN is not moment object');
        assert.ok(!moment.isMoment(null), 'null is not moment object');
        assert.ok(!moment.isMoment(undefined), 'undefined is not moment object');
    });

    test('is moment with hacked hasOwnProperty', function (assert) {
        var obj = {};
        // HACK to suppress linter warning about bad property name
        obj['hasOwnMoney'.replace('Money', 'Property')] = function () {
            return true;
        };

        assert.ok(
            !moment.isMoment(obj),
            'isMoment works even if passed object has a wrong hasOwnProperty implementation (ie8)'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function isNumber(input) {
        return (
            typeof input === 'number' ||
            Object.prototype.toString.call(input) === '[object Number]'
        );
    }

    test('isNumber recognizes numbers', function (assert) {
        assert.ok(isNumber(1), 'simple integer');
        assert.ok(isNumber(0), 'simple number');
        assert.ok(isNumber(-0), 'silly number');
        assert.ok(isNumber(1010010293029), 'large number');
        assert.ok(isNumber(Infinity), 'largest number');
        assert.ok(isNumber(-Infinity), 'smallest number');
        assert.ok(isNumber(NaN), 'not number');
        assert.ok(isNumber(1.10039383), 'decimal numbers');
        assert.ok(isNumber(Math.LN2), 'natural log of two');
        assert.ok(isNumber(Math.PI), 'delicious number');
        assert.ok(isNumber(5e10), 'scientifically notated number');
        assert.ok(isNumber(new Number(1)), 'number primitive wrapped in an object');
    });

    test('isNumber rejects non-numbers', function (assert) {
        assert.ok(!isNumber(), 'nothing');
        assert.ok(!isNumber(undefined), 'undefined');
        assert.ok(!isNumber(null), 'null');
        assert.ok(!isNumber([1]), 'array');
        assert.ok(!isNumber('[1,2,3]'), 'string');
        assert.ok(!isNumber(new Date()), 'date');
        assert.ok(!isNumber({ a: 1, b: 2 }), 'object');
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('is same or after');

    test('is same or after without units', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrAfter(moment(new Date(2012, 3, 2, 3, 5, 5, 10))),
            false,
            'year is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2010, 3, 2, 3, 3, 5, 10))),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10))),
            false,
            'month is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10))),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10))),
            false,
            'day is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 3, 1, 3, 4, 5, 10))),
            true,
            'day is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10))),
            false,
            'hour is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 3, 2, 2, 4, 5, 10))),
            true,
            'hour is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10))),
            false,
            'minute is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10))),
            true,
            'minute is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10))),
            false,
            'second is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 11))),
            true,
            'second is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10))),
            true,
            'millisecond match'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 11))),
            false,
            'millisecond is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 9))),
            true,
            'millisecond is earlier'
        );
        assert.equal(
            m.isSameOrAfter(m),
            true,
            'moments are the same as themselves'
        );
        assert.equal(+m, +mCopy, 'isSameOrAfter second should not change moment');
    });

    test('is same or after year', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'),
            true,
            'year match'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'),
            false,
            'year is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'),
            true,
            'exact start of year'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 11, 31, 23, 59, 59, 999)),
                'year'
            ),
            true,
            'exact end of year'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'),
            false,
            'start of next year'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2010, 11, 31, 23, 59, 59, 999)),
                'year'
            ),
            true,
            'end of previous year'
        );
        assert.equal(
            m.isSameOrAfter(m, 'year'),
            true,
            'same moments are in the same year'
        );
        assert.equal(+m, +mCopy, 'isSameOrAfter year should not change moment');
    });

    test('is same or after month', function (assert) {
        var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'),
            true,
            'month match'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'),
            false,
            'year is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'),
            false,
            'month is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'),
            true,
            'exact start of month'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 2, 31, 23, 59, 59, 999)),
                'month'
            ),
            true,
            'exact end of month'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'),
            false,
            'start of next month'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 1, 27, 23, 59, 59, 999)),
                'month'
            ),
            true,
            'end of previous month'
        );
        assert.equal(
            m.isSameOrAfter(m, 'month'),
            true,
            'same moments are in the same month'
        );
        assert.equal(+m, +mCopy, 'isSameOrAfter month should not change moment');
    });

    test('is same or after day', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'),
            true,
            'day match'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'),
            false,
            'year is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2010, 1, 2, 7, 8, 9, 10)), 'day'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'),
            false,
            'month is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2010, 12, 2, 7, 8, 9, 10)), 'day'),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'),
            false,
            'day is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 1, 7, 8, 9, 10)), 'day'),
            true,
            'day is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'),
            true,
            'exact start of day'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'),
            true,
            'exact end of day'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'),
            false,
            'start of next day'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'),
            true,
            'end of previous day'
        );
        assert.equal(
            m.isSameOrAfter(m, 'day'),
            true,
            'same moments are in the same day'
        );
        assert.equal(+m, +mCopy, 'isSameOrAfter day should not change moment');
    });

    test('is same or after hour', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'),
            true,
            'hour match'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'year is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 8, 9, 10)), 'hour'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'month is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 8, 9, 10)), 'hour'),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'),
            false,
            'day is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 8, 9, 10)), 'hour'),
            true,
            'day is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'),
            false,
            'hour is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 8, 9, 10)), 'hour'),
            true,
            'hour is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'),
            true,
            'exact start of hour'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'),
            true,
            'exact end of hour'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'),
            false,
            'start of next hour'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'),
            true,
            'end of previous hour'
        );
        assert.equal(
            m.isSameOrAfter(m, 'hour'),
            true,
            'same moments are in the same hour'
        );
        assert.equal(+m, +mCopy, 'isSameOrAfter hour should not change moment');
    });

    test('is same or after minute', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'),
            true,
            'minute match'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'),
            false,
            'year is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 4, 9, 10)), 'minute'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'),
            false,
            'month is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 4, 9, 10)), 'minute'),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'),
            false,
            'day is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 4, 9, 10)), 'minute'),
            true,
            'day is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'),
            false,
            'hour is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 4, 9, 10)), 'minute'),
            true,
            'hour is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'),
            false,
            'minute is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 9, 10)), 'minute'),
            true,
            'minute is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'),
            true,
            'exact start of minute'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'),
            true,
            'exact end of minute'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'),
            false,
            'start of next minute'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'),
            true,
            'end of previous minute'
        );
        assert.equal(
            m.isSameOrAfter(m, 'minute'),
            true,
            'same moments are in the same minute'
        );
        assert.equal(+m, +mCopy, 'isSameOrAfter minute should not change moment');
    });

    test('is same or after second', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'),
            true,
            'second match'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'),
            false,
            'year is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 4, 5, 10)), 'second'),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'),
            false,
            'month is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 4, 5, 10)), 'second'),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'),
            false,
            'day is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 4, 5, 10)), 'second'),
            true,
            'day is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'),
            false,
            'hour is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 4, 5, 10)), 'second'),
            true,
            'hour is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'),
            false,
            'minute is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 5, 10)), 'second'),
            true,
            'minute is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'),
            false,
            'second is later'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 4, 10)), 'second'),
            true,
            'second is earlier'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'),
            true,
            'exact start of second'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'),
            true,
            'exact end of second'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'),
            false,
            'start of next second'
        );
        assert.equal(
            m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'),
            true,
            'end of previous second'
        );
        assert.equal(
            m.isSameOrAfter(m, 'second'),
            true,
            'same moments are in the same second'
        );
        assert.equal(+m, +mCopy, 'isSameOrAfter second should not change moment');
    });

    test('is same or after millisecond', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                'millisecond'
            ),
            true,
            'millisecond match'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                'milliseconds'
            ),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                'millisecond'
            ),
            false,
            'year is later'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                'millisecond'
            ),
            true,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 4, 2, 3, 4, 5, 10)),
                'millisecond'
            ),
            false,
            'month is later'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 2, 2, 3, 4, 5, 10)),
                'millisecond'
            ),
            true,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 3, 3, 3, 4, 5, 10)),
                'millisecond'
            ),
            false,
            'day is later'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 3, 1, 1, 4, 5, 10)),
                'millisecond'
            ),
            true,
            'day is earlier'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 3, 2, 4, 4, 5, 10)),
                'millisecond'
            ),
            false,
            'hour is later'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 3, 1, 4, 1, 5, 10)),
                'millisecond'
            ),
            true,
            'hour is earlier'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 3, 2, 3, 5, 5, 10)),
                'millisecond'
            ),
            false,
            'minute is later'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 3, 2, 3, 3, 5, 10)),
                'millisecond'
            ),
            true,
            'minute is earlier'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 3, 2, 3, 4, 6, 10)),
                'millisecond'
            ),
            false,
            'second is later'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 3, 2, 3, 4, 4, 5)),
                'millisecond'
            ),
            true,
            'second is earlier'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 3, 2, 3, 4, 6, 11)),
                'millisecond'
            ),
            false,
            'millisecond is later'
        );
        assert.equal(
            m.isSameOrAfter(
                moment(new Date(2011, 3, 2, 3, 4, 4, 9)),
                'millisecond'
            ),
            true,
            'millisecond is earlier'
        );
        assert.equal(
            m.isSameOrAfter(m, 'millisecond'),
            true,
            'same moments are in the same millisecond'
        );
        assert.equal(
            +m,
            +mCopy,
            'isSameOrAfter millisecond should not change moment'
        );
    });

    test('is same or after with utc offset moments', function (assert) {
        assert.ok(
            moment
                .parseZone('2013-02-01T00:00:00-05:00')
                .isSameOrAfter(moment('2013-02-01'), 'year'),
            'zoned vs local moment'
        );
        assert.ok(
            moment('2013-02-01').isSameOrAfter(
                moment('2013-02-01').utcOffset('-05:00'),
                'year'
            ),
            'local vs zoned moment'
        );
        assert.ok(
            moment
                .parseZone('2013-02-01T00:00:00-05:00')
                .isSameOrAfter(
                    moment.parseZone('2013-02-01T00:00:00-06:30'),
                    'year'
                ),
            'zoned vs (differently) zoned moment'
        );
    });

    test('is same or after with invalid moments', function (assert) {
        var m = moment(),
            invalid = moment.invalid();
        assert.equal(
            invalid.isSameOrAfter(invalid),
            false,
            'invalid moments are not considered equal'
        );
        assert.equal(
            m.isSameOrAfter(invalid),
            false,
            'valid moment is not after invalid moment'
        );
        assert.equal(
            invalid.isSameOrAfter(m),
            false,
            'invalid moment is not after valid moment'
        );
        assert.equal(
            m.isSameOrAfter(invalid, 'year'),
            false,
            'invalid moment year'
        );
        assert.equal(
            m.isSameOrAfter(invalid, 'month'),
            false,
            'invalid moment month'
        );
        assert.equal(m.isSameOrAfter(invalid, 'day'), false, 'invalid moment day');
        assert.equal(
            m.isSameOrAfter(invalid, 'hour'),
            false,
            'invalid moment hour'
        );
        assert.equal(
            m.isSameOrAfter(invalid, 'minute'),
            false,
            'invalid moment minute'
        );
        assert.equal(
            m.isSameOrAfter(invalid, 'second'),
            false,
            'invalid moment second'
        );
        assert.equal(
            m.isSameOrAfter(invalid, 'milliseconds'),
            false,
            'invalid moment milliseconds'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('is same or before');

    test('is same or before without units', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrBefore(moment(new Date(2012, 3, 2, 3, 5, 5, 10))),
            true,
            'year is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2010, 3, 2, 3, 3, 5, 10))),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10))),
            true,
            'month is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10))),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10))),
            true,
            'day is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 3, 1, 3, 4, 5, 10))),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10))),
            true,
            'hour is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 3, 2, 2, 4, 5, 10))),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10))),
            true,
            'minute is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10))),
            false,
            'minute is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10))),
            true,
            'second is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 11))),
            false,
            'second is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10))),
            true,
            'millisecond match'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 11))),
            true,
            'millisecond is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 9))),
            false,
            'millisecond is earlier'
        );
        assert.equal(
            m.isSameOrBefore(m),
            true,
            'moments are the same as themselves'
        );
        assert.equal(+m, +mCopy, 'isSameOrBefore second should not change moment');
    });

    test('is same or before year', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'),
            true,
            'year match'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'),
            true,
            'year is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'),
            true,
            'exact start of year'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 11, 31, 23, 59, 59, 999)),
                'year'
            ),
            true,
            'exact end of year'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'),
            true,
            'start of next year'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2010, 11, 31, 23, 59, 59, 999)),
                'year'
            ),
            false,
            'end of previous year'
        );
        assert.equal(
            m.isSameOrBefore(m, 'year'),
            true,
            'same moments are in the same year'
        );
        assert.equal(+m, +mCopy, 'isSameOrBefore year should not change moment');
    });

    test('is same or before month', function (assert) {
        var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'),
            true,
            'month match'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'),
            true,
            'year is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'),
            true,
            'month is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'),
            true,
            'exact start of month'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 2, 31, 23, 59, 59, 999)),
                'month'
            ),
            true,
            'exact end of month'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'),
            true,
            'start of next month'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 1, 27, 23, 59, 59, 999)),
                'month'
            ),
            false,
            'end of previous month'
        );
        assert.equal(
            m.isSameOrBefore(m, 'month'),
            true,
            'same moments are in the same month'
        );
        assert.equal(+m, +mCopy, 'isSameOrBefore month should not change moment');
    });

    test('is same or before day', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'),
            true,
            'day match'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'),
            true,
            'year is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2010, 1, 2, 7, 8, 9, 10)), 'day'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'),
            true,
            'month is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2010, 12, 2, 7, 8, 9, 10)), 'day'),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'),
            true,
            'day is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 1, 7, 8, 9, 10)), 'day'),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'),
            true,
            'exact start of day'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'),
            true,
            'exact end of day'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'),
            true,
            'start of next day'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'),
            false,
            'end of previous day'
        );
        assert.equal(
            m.isSameOrBefore(m, 'day'),
            true,
            'same moments are in the same day'
        );
        assert.equal(+m, +mCopy, 'isSameOrBefore day should not change moment');
    });

    test('is same or before hour', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'),
            true,
            'hour match'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'),
            true,
            'year is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'),
            true,
            'month is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'),
            true,
            'day is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 8, 9, 10)), 'hour'),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'),
            true,
            'hour is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 8, 9, 10)), 'hour'),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'),
            true,
            'exact start of hour'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'),
            true,
            'exact end of hour'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'),
            true,
            'start of next hour'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'),
            false,
            'end of previous hour'
        );
        assert.equal(
            m.isSameOrBefore(m, 'hour'),
            true,
            'same moments are in the same hour'
        );
        assert.equal(+m, +mCopy, 'isSameOrBefore hour should not change moment');
    });

    test('is same or before minute', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'),
            true,
            'minute match'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'),
            true,
            'year is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 4, 9, 10)), 'minute'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'),
            true,
            'month is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 4, 9, 10)), 'minute'),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'),
            true,
            'day is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 4, 9, 10)), 'minute'),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'),
            true,
            'hour is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 4, 9, 10)), 'minute'),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'),
            true,
            'minute is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 9, 10)), 'minute'),
            false,
            'minute is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'),
            true,
            'exact start of minute'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'),
            true,
            'exact end of minute'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'),
            true,
            'start of next minute'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'),
            false,
            'end of previous minute'
        );
        assert.equal(
            m.isSameOrBefore(m, 'minute'),
            true,
            'same moments are in the same minute'
        );
        assert.equal(+m, +mCopy, 'isSameOrBefore minute should not change moment');
    });

    test('is same or before second', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'),
            true,
            'second match'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'),
            true,
            'year is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 4, 5, 10)), 'second'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'),
            true,
            'month is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 4, 5, 10)), 'second'),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'),
            true,
            'day is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 4, 5, 10)), 'second'),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'),
            true,
            'hour is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 4, 5, 10)), 'second'),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'),
            true,
            'minute is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 5, 10)), 'second'),
            false,
            'minute is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'),
            true,
            'second is later'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 4, 10)), 'second'),
            false,
            'second is earlier'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'),
            true,
            'exact start of second'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'),
            true,
            'exact end of second'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'),
            true,
            'start of next second'
        );
        assert.equal(
            m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'),
            false,
            'end of previous second'
        );
        assert.equal(
            m.isSameOrBefore(m, 'second'),
            true,
            'same moments are in the same second'
        );
        assert.equal(+m, +mCopy, 'isSameOrBefore second should not change moment');
    });

    test('is same or before millisecond', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                'millisecond'
            ),
            true,
            'millisecond match'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
                'milliseconds'
            ),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2012, 3, 2, 3, 4, 5, 10)),
                'millisecond'
            ),
            true,
            'year is later'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),
                'millisecond'
            ),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 4, 2, 3, 4, 5, 10)),
                'millisecond'
            ),
            true,
            'month is later'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 2, 2, 3, 4, 5, 10)),
                'millisecond'
            ),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 3, 3, 3, 4, 5, 10)),
                'millisecond'
            ),
            true,
            'day is later'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 3, 1, 1, 4, 5, 10)),
                'millisecond'
            ),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 3, 2, 4, 4, 5, 10)),
                'millisecond'
            ),
            true,
            'hour is later'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 3, 1, 4, 1, 5, 10)),
                'millisecond'
            ),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 3, 2, 3, 5, 5, 10)),
                'millisecond'
            ),
            true,
            'minute is later'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 3, 2, 3, 3, 5, 10)),
                'millisecond'
            ),
            false,
            'minute is earlier'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 3, 2, 3, 4, 6, 10)),
                'millisecond'
            ),
            true,
            'second is later'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 3, 2, 3, 4, 4, 5)),
                'millisecond'
            ),
            false,
            'second is earlier'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 3, 2, 3, 4, 6, 11)),
                'millisecond'
            ),
            true,
            'millisecond is later'
        );
        assert.equal(
            m.isSameOrBefore(
                moment(new Date(2011, 3, 2, 3, 4, 4, 9)),
                'millisecond'
            ),
            false,
            'millisecond is earlier'
        );
        assert.equal(
            m.isSameOrBefore(m, 'millisecond'),
            true,
            'same moments are in the same millisecond'
        );
        assert.equal(
            +m,
            +mCopy,
            'isSameOrBefore millisecond should not change moment'
        );
    });

    test('is same with utc offset moments', function (assert) {
        assert.ok(
            moment
                .parseZone('2013-02-01T00:00:00-05:00')
                .isSameOrBefore(moment('2013-02-01'), 'year'),
            'zoned vs local moment'
        );
        assert.ok(
            moment('2013-02-01').isSameOrBefore(
                moment('2013-02-01').utcOffset('-05:00'),
                'year'
            ),
            'local vs zoned moment'
        );
        assert.ok(
            moment
                .parseZone('2013-02-01T00:00:00-05:00')
                .isSameOrBefore(
                    moment.parseZone('2013-02-01T00:00:00-06:30'),
                    'year'
                ),
            'zoned vs (differently) zoned moment'
        );
    });

    test('is same with invalid moments', function (assert) {
        var m = moment(),
            invalid = moment.invalid();
        assert.equal(
            invalid.isSameOrBefore(invalid),
            false,
            'invalid moments are not considered equal'
        );
        assert.equal(
            m.isSameOrBefore(invalid),
            false,
            'valid moment is not before invalid moment'
        );
        assert.equal(
            invalid.isSameOrBefore(m),
            false,
            'invalid moment is not before valid moment'
        );
        assert.equal(
            m.isSameOrBefore(invalid, 'year'),
            false,
            'invalid moment year'
        );
        assert.equal(
            m.isSameOrBefore(invalid, 'month'),
            false,
            'invalid moment month'
        );
        assert.equal(m.isSameOrBefore(invalid, 'day'), false, 'invalid moment day');
        assert.equal(
            m.isSameOrBefore(invalid, 'hour'),
            false,
            'invalid moment hour'
        );
        assert.equal(
            m.isSameOrBefore(invalid, 'minute'),
            false,
            'invalid moment minute'
        );
        assert.equal(
            m.isSameOrBefore(invalid, 'second'),
            false,
            'invalid moment second'
        );
        assert.equal(
            m.isSameOrBefore(invalid, 'milliseconds'),
            false,
            'invalid moment milliseconds'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('is same');

    test('is same without units', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isSame(moment(new Date(2012, 3, 2, 3, 5, 5, 10))),
            false,
            'year is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2010, 3, 2, 3, 3, 5, 10))),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 4, 2, 3, 4, 5, 10))),
            false,
            'month is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10))),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 3, 3, 4, 5, 10))),
            false,
            'day is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 1, 3, 4, 5, 10))),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 4, 4, 5, 10))),
            false,
            'hour is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 2, 4, 5, 10))),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 5, 5, 10))),
            false,
            'minute is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 3, 5, 10))),
            false,
            'minute is earlier'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 10))),
            false,
            'second is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 11))),
            false,
            'second is earlier'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10))),
            true,
            'millisecond match'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 11))),
            false,
            'millisecond is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 9))),
            false,
            'millisecond is earlier'
        );
        assert.equal(m.isSame(m), true, 'moments are the same as themselves');
        assert.equal(+m, +mCopy, 'isSame second should not change moment');
    });

    test('is same year', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'),
            true,
            'year match'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSame(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'),
            false,
            'year mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'),
            true,
            'exact start of year'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'),
            true,
            'exact end of year'
        );
        assert.equal(
            m.isSame(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'),
            false,
            'start of next year'
        );
        assert.equal(
            m.isSame(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'),
            false,
            'end of previous year'
        );
        assert.equal(
            m.isSame(m, 'year'),
            true,
            'same moments are in the same year'
        );
        assert.equal(+m, +mCopy, 'isSame year should not change moment');
    });

    test('is same month', function (assert) {
        var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)),
            mCopy = moment(m);
        assert.equal(
            m.isSame(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'),
            true,
            'month match'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSame(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'),
            false,
            'year mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'),
            false,
            'month mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'),
            true,
            'exact start of month'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'),
            true,
            'exact end of month'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'),
            false,
            'start of next month'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'),
            false,
            'end of previous month'
        );
        assert.equal(
            m.isSame(m, 'month'),
            true,
            'same moments are in the same month'
        );
        assert.equal(+m, +mCopy, 'isSame month should not change moment');
    });

    test('is same day', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'),
            true,
            'day match'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSame(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'),
            false,
            'year mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'),
            false,
            'month mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'),
            false,
            'day mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'),
            true,
            'exact start of day'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'),
            true,
            'exact end of day'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'),
            false,
            'start of next day'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'),
            false,
            'end of previous day'
        );
        assert.equal(m.isSame(m, 'day'), true, 'same moments are in the same day');
        assert.equal(+m, +mCopy, 'isSame day should not change moment');
    });

    test('is same hour', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'),
            true,
            'hour match'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSame(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'year mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'),
            false,
            'month mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'),
            false,
            'day mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'),
            false,
            'hour mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'),
            true,
            'exact start of hour'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'),
            true,
            'exact end of hour'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'),
            false,
            'start of next hour'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'),
            false,
            'end of previous hour'
        );
        assert.equal(
            m.isSame(m, 'hour'),
            true,
            'same moments are in the same hour'
        );
        assert.equal(+m, +mCopy, 'isSame hour should not change moment');
    });

    test('is same minute', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'),
            true,
            'minute match'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSame(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'),
            false,
            'year mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'),
            false,
            'month mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'),
            false,
            'day mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'),
            false,
            'hour mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'),
            false,
            'minute mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'),
            true,
            'exact start of minute'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'),
            true,
            'exact end of minute'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'),
            false,
            'start of next minute'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'),
            false,
            'end of previous minute'
        );
        assert.equal(
            m.isSame(m, 'minute'),
            true,
            'same moments are in the same minute'
        );
        assert.equal(+m, +mCopy, 'isSame minute should not change moment');
    });

    test('is same second', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)),
            mCopy = moment(m);
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'),
            true,
            'second match'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSame(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'),
            false,
            'year mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'),
            false,
            'month mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'),
            false,
            'day mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'),
            false,
            'hour mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'),
            false,
            'minute mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'),
            false,
            'second mismatch'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'),
            true,
            'exact start of second'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'),
            true,
            'exact end of second'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'),
            false,
            'start of next second'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'),
            false,
            'end of previous second'
        );
        assert.equal(
            m.isSame(m, 'second'),
            true,
            'same moments are in the same second'
        );
        assert.equal(+m, +mCopy, 'isSame second should not change moment');
    });

    test('is same millisecond', function (assert) {
        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)),
            mCopy = moment(m);
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'),
            true,
            'millisecond match'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'),
            true,
            'plural should work'
        );
        assert.equal(
            m.isSame(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'),
            false,
            'year is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'),
            false,
            'year is earlier'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'),
            false,
            'month is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'),
            false,
            'month is earlier'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'),
            false,
            'day is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'),
            false,
            'day is earlier'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'),
            false,
            'hour is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'),
            false,
            'hour is earlier'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'),
            false,
            'minute is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'),
            false,
            'minute is earlier'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'),
            false,
            'second is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'),
            false,
            'second is earlier'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'),
            false,
            'millisecond is later'
        );
        assert.equal(
            m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'),
            false,
            'millisecond is earlier'
        );
        assert.equal(
            m.isSame(m, 'millisecond'),
            true,
            'same moments are in the same millisecond'
        );
        assert.equal(+m, +mCopy, 'isSame millisecond should not change moment');
    });

    test('is same with utc offset moments', function (assert) {
        assert.ok(
            moment
                .parseZone('2013-02-01T00:00:00-05:00')
                .isSame(moment('2013-02-01'), 'year'),
            'zoned vs local moment'
        );
        assert.ok(
            moment('2013-02-01').isSame(
                moment('2013-02-01').utcOffset('-05:00'),
                'year'
            ),
            'local vs zoned moment'
        );
        assert.ok(
            moment
                .parseZone('2013-02-01T00:00:00-05:00')
                .isSame(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),
            'zoned vs (differently) zoned moment'
        );
    });

    test('is same with invalid moments', function (assert) {
        assert.equal(
            moment.invalid().isSame(moment.invalid()),
            false,
            'invalid moments are not considered equal'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('is valid');

    test('array bad month', function (assert) {
        assert.equal(moment([2010, -1]).isValid(), false, 'month -1 invalid');
        assert.equal(moment([2100, 12]).isValid(), false, 'month 12 invalid');
    });

    test('array good month', function (assert) {
        for (var i = 0; i < 12; i++) {
            assert.equal(moment([2010, i]).isValid(), true, 'month ' + i);
            assert.equal(moment.utc([2010, i]).isValid(), true, 'month ' + i);
        }
    });

    test('Feb 29 0000 is valid', function (assert) {
        // https://github.com/moment/moment/issues/3358
        assert.ok(
            moment({ year: 0, month: 1, date: 29 }).isValid(),
            'Feb 29 0000 must be valid'
        );
        assert.ok(
            moment({ year: 0, month: 1, date: 28 }).add(1, 'd').isValid(),
            'Feb 28 0000 + 1 day must be valid'
        );
    });

    test('array bad date', function (assert) {
        var tests = [
            moment([2010, 0, 0]),
            moment([2100, 0, 32]),
            moment.utc([2010, 0, 0]),
            moment.utc([2100, 0, 32]),
        ];

        each(tests, function (m) {
            assert.equal(m.isValid(), false);
        });
    });

    test('h/hh with hour > 12', function (assert) {
        assert.ok(
            moment('06/20/2014 11:51 PM', 'MM/DD/YYYY hh:mm A', true).isValid(),
            '11 for hh'
        );
        assert.ok(
            moment('06/20/2014 11:51 AM', 'MM/DD/YYYY hh:mm A', true).isValid(),
            '11 for hh'
        );
        assert.ok(
            moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A').isValid(),
            'non-strict validity 23 for hh'
        );
        assert.ok(
            moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A').parsingFlags()
                .bigHour,
            'non-strict bigHour 23 for hh'
        );
        assert.ok(
            !moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A', true).isValid(),
            'validity 23 for hh'
        );
        assert.ok(
            moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A', true).parsingFlags()
                .bigHour,
            'bigHour 23 for hh'
        );
    });

    test('array bad date leap year', function (assert) {
        assert.equal(moment([2010, 1, 29]).isValid(), false, '2010 feb 29');
        assert.equal(moment([2100, 1, 29]).isValid(), false, '2100 feb 29');
        assert.equal(moment([2008, 1, 30]).isValid(), false, '2008 feb 30');
        assert.equal(moment([2000, 1, 30]).isValid(), false, '2000 feb 30');

        assert.equal(moment.utc([2010, 1, 29]).isValid(), false, 'utc 2010 feb 29');
        assert.equal(moment.utc([2100, 1, 29]).isValid(), false, 'utc 2100 feb 29');
        assert.equal(moment.utc([2008, 1, 30]).isValid(), false, 'utc 2008 feb 30');
        assert.equal(moment.utc([2000, 1, 30]).isValid(), false, 'utc 2000 feb 30');
    });

    test('string + formats bad date', function (assert) {
        assert.equal(
            moment('2020-00-00', []).isValid(),
            false,
            'invalid on empty array'
        );
        assert.equal(
            moment('2020-00-00', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(),
            false,
            'invalid on all in array'
        );
        assert.equal(
            moment('2020-00-00', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(),
            false,
            'invalid on all in array'
        );
        assert.equal(
            moment('2020-01-01', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(),
            true,
            'valid on first'
        );
        assert.equal(
            moment('2020-01-01', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(),
            true,
            'valid on last'
        );
        assert.equal(
            moment('2020-01-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(),
            true,
            'valid on both'
        );
        assert.equal(
            moment('2020-13-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(),
            true,
            'valid on last'
        );

        assert.equal(
            moment('12-13-2012', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(),
            false,
            'month rollover'
        );
        assert.equal(
            moment('12-13-2012', ['DD-MM-YYYY', 'DD-MM-YYYY']).isValid(),
            false,
            'month rollover'
        );
        assert.equal(
            moment('38-12-2012', ['DD-MM-YYYY']).isValid(),
            false,
            'day rollover'
        );
    });

    test('string nonsensical with format', function (assert) {
        assert.equal(
            moment('fail', 'MM-DD-YYYY').isValid(),
            false,
            "string 'fail' with format 'MM-DD-YYYY'"
        );
        assert.equal(
            moment('xx-xx-2001', 'DD-MM-YYY').isValid(),
            true,
            "string 'xx-xx-2001' with format 'MM-DD-YYYY'"
        );
    });

    test('string with bad month name', function (assert) {
        assert.equal(
            moment('01-Nam-2012', 'DD-MMM-YYYY').isValid(),
            false,
            "'Nam' is an invalid month"
        );
        assert.equal(
            moment('01-Aug-2012', 'DD-MMM-YYYY').isValid(),
            true,
            "'Aug' is a valid month"
        );
    });

    test('string with spaceless format', function (assert) {
        assert.equal(
            moment('10Sep2001', 'DDMMMYYYY').isValid(),
            true,
            'Parsing 10Sep2001 should result in a valid date'
        );
    });

    test('invalid string iso 8601', function (assert) {
        var tests = [
                '2010-00-00',
                '2010-01-00',
                '2010-01-40',
                '2010-01-01T24:01', // 24:00:00 is actually valid
                '2010-01-01T23:60',
                '2010-01-01T23:59:60',
            ],
            i;

        for (i = 0; i < tests.length; i++) {
            assert.equal(
                moment(tests[i], moment.ISO_8601).isValid(),
                false,
                tests[i] + ' should be invalid'
            );
            assert.equal(
                moment.utc(tests[i], moment.ISO_8601).isValid(),
                false,
                tests[i] + ' should be invalid'
            );
        }
    });

    test('invalid string iso 8601 + timezone', function (assert) {
        var tests = [
                '2010-00-00T+00:00',
                '2010-01-00T+00:00',
                '2010-01-40T+00:00',
                '2010-01-40T24:01+00:00',
                '2010-01-40T23:60+00:00',
                '2010-01-40T23:59:60+00:00',
                '2010-01-40T23:59:59.9999+00:00',
                '2010-01-40T23:59:59,9999+00:00',
            ],
            i;

        for (i = 0; i < tests.length; i++) {
            assert.equal(
                moment(tests[i], moment.ISO_8601).isValid(),
                false,
                tests[i] + ' should be invalid'
            );
            assert.equal(
                moment.utc(tests[i], moment.ISO_8601).isValid(),
                false,
                tests[i] + ' should be invalid'
            );
        }
    });

    test('valid string iso 8601 - not strict', function (assert) {
        var tests = [
                '2010-01-30 00:00:00,000Z',
                '20100101',
                '20100130',
                '20100130T23+00:00',
                '20100130T2359+0000',
                '20100130T235959+0000',
                '20100130T235959,999+0000',
                '20100130T235959,999-0700',
                '20100130T000000,000+0700',
                '20100130 000000,000Z',
            ],
            i;

        for (i = 0; i < tests.length; i++) {
            assert.equal(
                moment(tests[i]).isValid(),
                true,
                tests[i] + ' should be valid in normal'
            );
            assert.equal(
                moment.utc(tests[i]).isValid(),
                true,
                tests[i] + ' should be valid in normal'
            );
        }
    });

    test('valid string iso 8601 + timezone', function (assert) {
        var tests = [
                '2010-01-01',
                '2010-01-30',
                '2010-01-30T23+00:00',
                '2010-01-30T23:59+00:00',
                '2010-01-30T23:59:59+00:00',
                '2010-01-30T23:59:59.999+00:00',
                '2010-01-30T23:59:59.999-07:00',
                '2010-01-30T00:00:00.000+07:00',
                '2010-01-30T23:59:59.999-07',
                '2010-01-30T00:00:00.000+07',
                '2010-01-30 00:00:00.000Z',
            ],
            i;

        for (i = 0; i < tests.length; i++) {
            assert.equal(
                moment(tests[i]).isValid(),
                true,
                tests[i] + ' should be valid in normal'
            );
            assert.equal(
                moment.utc(tests[i]).isValid(),
                true,
                tests[i] + ' should be valid in normal'
            );
            assert.equal(
                moment(tests[i], moment.ISO_8601, true).isValid(),
                true,
                tests[i] + ' should be valid in strict'
            );
            assert.equal(
                moment.utc(tests[i], moment.ISO_8601, true).isValid(),
                true,
                tests[i] + ' should be valid in strict'
            );
        }
    });

    test('invalidAt', function (assert) {
        assert.equal(
            moment([2000, 12]).invalidAt(),
            1,
            'month 12 is invalid: 0-11'
        );
        assert.equal(
            moment([2000, 1, 30]).invalidAt(),
            2,
            '30 is not a valid february day'
        );
        assert.equal(
            moment([2000, 1, 29, 25]).invalidAt(),
            3,
            '25 is invalid hour'
        );
        assert.equal(
            moment([2000, 1, 29, 24, 1]).invalidAt(),
            3,
            '24:01 is invalid hour'
        );
        assert.equal(
            moment([2000, 1, 29, 23, 60]).invalidAt(),
            4,
            '60 is invalid minute'
        );
        assert.equal(
            moment([2000, 1, 29, 23, 59, 60]).invalidAt(),
            5,
            '60 is invalid second'
        );
        assert.equal(
            moment([2000, 1, 29, 23, 59, 59, 1000]).invalidAt(),
            6,
            '1000 is invalid millisecond'
        );
        assert.equal(
            moment([2000, 1, 29, 23, 59, 59, 999]).invalidAt(),
            -1,
            '-1 if everything is fine'
        );
    });

    test('valid Unix timestamp', function (assert) {
        assert.equal(moment(1371065286, 'X').isValid(), true, 'number integer');
        assert.equal(moment(1379066897.0, 'X').isValid(), true, 'number whole 1dp');
        assert.equal(moment(1379066897.7, 'X').isValid(), true, 'number 1dp');
        assert.equal(moment(1379066897.0, 'X').isValid(), true, 'number whole 2dp');
        assert.equal(moment(1379066897.07, 'X').isValid(), true, 'number 2dp');
        assert.equal(moment(1379066897.17, 'X').isValid(), true, 'number 2dp');
        assert.equal(moment(1379066897.0, 'X').isValid(), true, 'number whole 3dp');
        assert.equal(moment(1379066897.007, 'X').isValid(), true, 'number 3dp');
        assert.equal(moment(1379066897.017, 'X').isValid(), true, 'number 3dp');
        assert.equal(moment(1379066897.157, 'X').isValid(), true, 'number 3dp');
        assert.equal(moment('1371065286', 'X').isValid(), true, 'string integer');
        assert.equal(
            moment('1379066897.', 'X').isValid(),
            true,
            'string trailing .'
        );
        assert.equal(
            moment('1379066897.0', 'X').isValid(),
            true,
            'string whole 1dp'
        );
        assert.equal(moment('1379066897.7', 'X').isValid(), true, 'string 1dp');
        assert.equal(
            moment('1379066897.00', 'X').isValid(),
            true,
            'string whole 2dp'
        );
        assert.equal(moment('1379066897.07', 'X').isValid(), true, 'string 2dp');
        assert.equal(moment('1379066897.17', 'X').isValid(), true, 'string 2dp');
        assert.equal(
            moment('1379066897.000', 'X').isValid(),
            true,
            'string whole 3dp'
        );
        assert.equal(moment('1379066897.007', 'X').isValid(), true, 'string 3dp');
        assert.equal(moment('1379066897.017', 'X').isValid(), true, 'string 3dp');
        assert.equal(moment('1379066897.157', 'X').isValid(), true, 'string 3dp');
    });

    test('invalid Unix timestamp', function (assert) {
        assert.equal(moment(undefined, 'X').isValid(), false, 'undefined');
        assert.equal(moment('undefined', 'X').isValid(), false, 'string undefined');
        try {
            assert.equal(moment(null, 'X').isValid(), false, 'null');
        } catch (e) {
            assert.ok(true, 'null');
        }

        assert.equal(moment('null', 'X').isValid(), false, 'string null');
        assert.equal(moment([], 'X').isValid(), false, 'array');
        assert.equal(moment('{}', 'X').isValid(), false, 'object');
        try {
            assert.equal(moment('', 'X').isValid(), false, 'string empty');
        } catch (e) {
            assert.ok(true, 'string empty');
        }

        assert.equal(moment(' ', 'X').isValid(), false, 'string space');
    });

    test('valid Unix offset milliseconds', function (assert) {
        assert.equal(moment(1234567890123, 'x').isValid(), true, 'number integer');
        assert.equal(
            moment('1234567890123', 'x').isValid(),
            true,
            'string integer'
        );
    });

    test('invalid Unix offset milliseconds', function (assert) {
        assert.equal(moment(undefined, 'x').isValid(), false, 'undefined');
        assert.equal(moment('undefined', 'x').isValid(), false, 'string undefined');
        try {
            assert.equal(moment(null, 'x').isValid(), false, 'null');
        } catch (e) {
            assert.ok(true, 'null');
        }

        assert.equal(moment('null', 'x').isValid(), false, 'string null');
        assert.equal(moment([], 'x').isValid(), false, 'array');
        assert.equal(moment('{}', 'x').isValid(), false, 'object');
        try {
            assert.equal(moment('', 'x').isValid(), false, 'string empty');
        } catch (e) {
            assert.ok(true, 'string empty');
        }

        assert.equal(moment(' ', 'x').isValid(), false, 'string space');
    });

    test('empty', function (assert) {
        assert.equal(moment(null).isValid(), false, 'null');
        assert.equal(moment('').isValid(), false, 'empty string');
        assert.equal(moment(null, 'YYYY').isValid(), false, 'format + null');
        assert.equal(moment('', 'YYYY').isValid(), false, 'format + empty string');
        assert.equal(
            moment(' ', 'YYYY').isValid(),
            false,
            'format + empty when trimmed'
        );
    });

    test('days of the year', function (assert) {
        assert.equal(
            moment('2010 300', 'YYYY DDDD').isValid(),
            true,
            'day 300 of year valid'
        );
        assert.equal(
            moment('2010 365', 'YYYY DDDD').isValid(),
            true,
            'day 365 of year valid'
        );
        assert.equal(
            moment('2010 366', 'YYYY DDDD').isValid(),
            false,
            'day 366 of year invalid'
        );
        assert.equal(
            moment('2012 365', 'YYYY DDDD').isValid(),
            true,
            'day 365 of leap year valid'
        );
        assert.equal(
            moment('2012 366', 'YYYY DDDD').isValid(),
            true,
            'day 366 of leap year valid'
        );
        assert.equal(
            moment('2012 367', 'YYYY DDDD').isValid(),
            false,
            'day 367 of leap year invalid'
        );
    });

    test('24:00:00.000 is valid', function (assert) {
        assert.equal(
            moment('2014-01-01 24', 'YYYY-MM-DD HH').isValid(),
            true,
            '24 is valid'
        );
        assert.equal(
            moment('2014-01-01 24:00', 'YYYY-MM-DD HH:mm').isValid(),
            true,
            '24:00 is valid'
        );
        assert.equal(
            moment('2014-01-01 24:01', 'YYYY-MM-DD HH:mm').isValid(),
            false,
            '24:01 is not valid'
        );
    });

    test('oddball permissiveness', function (assert) {
        // https://github.com/moment/moment/issues/1128
        assert.ok(
            moment('2010-10-3199', [
                'MM/DD/YYYY',
                'MM-DD-YYYY',
                'YYYY-MM-DD',
            ]).isValid()
        );

        // https://github.com/moment/moment/issues/1122
        assert.ok(moment('3:25', ['h:mma', 'hh:mma', 'H:mm', 'HH:mm']).isValid());
    });

    test('0 hour is invalid in strict', function (assert) {
        assert.equal(
            moment('00:01', 'hh:mm', true).isValid(),
            false,
            '00 hour is invalid in strict'
        );
        assert.equal(
            moment('00:01', 'hh:mm').isValid(),
            true,
            '00 hour is valid in normal'
        );
        assert.equal(
            moment('0:01', 'h:mm', true).isValid(),
            false,
            '0 hour is invalid in strict'
        );
        assert.equal(
            moment('0:01', 'h:mm').isValid(),
            true,
            '0 hour is valid in normal'
        );
    });

    test('format locale', function (assert) {
        var a = [
                ['uto 15.05.2018', 'dd DD.MM.YYYY', 'bs'],
                ['dt 15.05.2018', 'dd DD.MM.YYYY', 'ca'],
                ['Di 15.05.2018', 'dd DD.MM.YYYY', 'de-dt'],
                ['Di 15.05.2018', 'dd DD.MM.YYYY', 'de'],
                ['mar 15.05.2018', 'dd DD.MM.YYYY', 'es-do'],
                ['mar 15.05.2018', 'dd DD.MM.YYYY', 'es-us'],
                ['Di 15.05.2018', 'dd DD.MM.YYYY', 'es'],
                ['ar 15.05.2018', 'dd DD.MM.YYYY', 'eu'],
                ['mar 15.05.2018', 'dd DD.MM.YYYY', 'fr-ca'],
                ['mar 15.05.2018', 'dd DD.MM.YYYY', 'fr-ch'],
                ['mar 15.05.2018', 'dd DD.MM.YYYY', 'fr'],
                ['ti 15.05.2018', 'dd DD.MM.YYYY', 'fy'],
                ['mar 15.05.2018', 'dd DD.MM.YYYY', 'gl'],
                ['मंगळ 15.05.2018', 'dd DD.MM.YYYY', 'gom-deva'],
                ['Mon 15.05.2018', 'dd DD.MM.YYYY', 'gom-latn'],
                ['uto 15.05.2018', 'dd DD.MM.YYYY', 'hr'],
                ['Dë 15.05.2018', 'dd DD.MM.YYYY', 'lb'],
                ['uto 15.05.2018', 'dd DD.MM.YYYY', 'me'],
                ['ti 15.05.2018', 'dd DD.MM.YYYY', 'nb'],
                ['मङ्गल 15.05.2018', 'dd DD.MM.YYYY', 'ne'],
                ['di 15.05.2018', 'dd DD.MM.YYYY', 'nl-be'],
                ['di 15.05.2018', 'dd DD.MM.YYYY', 'nl'],
                ['ty 15.05.2018', 'dd DD.MM.YYYY', 'nn'],
                ['dm 15.05.2018', 'dd DD.MM.YYYY', 'oc-lnc'],
                ['tor 15.05.2018', 'dd DD.MM.YYYY', 'sl'],
                ['уто 15.05.2018', 'dd DD.MM.YYYY', 'sr-cyrl'],
                ['uto 15.05.2018', 'dd DD.MM.YYYY', 'sr'],
                ['uto 15.05.2018', 'dd DD.MM.YYYY', 'sr'],
            ],
            i;
        for (i = 0; i < a.length; i++) {
            assert.ok(moment(a[i][0], a[i][1], a[i][2]).isValid());
        }
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    function isLeapYear(year) {
        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
    }

    module('is leap year');

    test('leap years', function (assert) {
        var tests = [
            { year: 1, expected: false, description: '1 was not a leap year' },
            { year: 4, expected: true, description: '4 was a leap year' },
            { year: 100, expected: false, description: '100 was not a leap year' },
            { year: 400, expected: true, description: '400 was a leap year' },
            {
                year: 1700,
                expected: false,
                description:
                    '1700 was a leap year in the Julian calendar, but not Gregorian',
            },
            {
                year: 1900,
                expected: false,
                description:
                    '1900 was not a leap year, but this is a well known Microsoft Excel bug',
            },
            { year: 1904, expected: true, description: '1904 was a leap year' },
            { year: 2000, expected: true, description: '2000 was a leap year' },
            { year: 2008, expected: true, description: '2008 was a leap year' },
            {
                year: 2010,
                expected: false,
                description: '2010 was not a leap year',
            },
            { year: 2024, expected: true, description: '2024 will be a leap year' },
            { year: 3448, expected: true, description: '3448 will be a leap year' },
            { year: 4000, expected: true, description: '4000 will be a leap year' },
            {
                year: NaN,
                expected: false,
                description:
                    'NaN returns false explicitly, as math operations on non-numbers yields NaN',
            },
            {
                year: '2000',
                expected: true,
                description:
                    'The string literal "2000" yields true as it is parsed as the number 2000',
            },
            {
                year: Infinity,
                expected: false,
                description:
                    'Non-finite years are technically not years and definitely not leap years',
            },
            {
                year: 3.14,
                expected: false,
                description:
                    'Non-integer years are technically not years and definitely not leap years',
            },
            {
                year: 0,
                expected: true,
                description:
                    'While unclear whether this case is exceptional, it is a leap year based on existing formula',
            },
            {
                year: -400,
                expected: true,
                description:
                    'While unclear whether this case is exceptional, it is a leap year based on existing formula',
            },
            {
                year: {},
                expected: false,
                description: 'Objects are not a number, so not a leap year',
            },
            {
                year: [],
                expected: true,
                description:
                    'An empty array is equivalent to 0, which is a leap year',
            },
        ];

        each(tests, function (testCase) {
            var actual = isLeapYear(testCase.year);
            assert.equal(actual, testCase.expected, testCase.description);
        });
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('leap year');

    test('leap year', function (assert) {
        assert.equal(moment([2010, 0, 1]).isLeapYear(), false, '2010');
        assert.equal(moment([2100, 0, 1]).isLeapYear(), false, '2100');
        assert.equal(moment([2008, 0, 1]).isLeapYear(), true, '2008');
        assert.equal(moment([2000, 0, 1]).isLeapYear(), true, '2000');
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('listers');

    test('default', function (assert) {
        assert.deepEqual(moment.months(), [
            'January',
            'February',
            'March',
            'April',
            'May',
            'June',
            'July',
            'August',
            'September',
            'October',
            'November',
            'December',
        ]);
        assert.deepEqual(moment.monthsShort(), [
            'Jan',
            'Feb',
            'Mar',
            'Apr',
            'May',
            'Jun',
            'Jul',
            'Aug',
            'Sep',
            'Oct',
            'Nov',
            'Dec',
        ]);
        assert.deepEqual(moment.weekdays(), [
            'Sunday',
            'Monday',
            'Tuesday',
            'Wednesday',
            'Thursday',
            'Friday',
            'Saturday',
        ]);
        assert.deepEqual(moment.weekdaysShort(), [
            'Sun',
            'Mon',
            'Tue',
            'Wed',
            'Thu',
            'Fri',
            'Sat',
        ]);
        assert.deepEqual(moment.weekdaysMin(), [
            'Su',
            'Mo',
            'Tu',
            'We',
            'Th',
            'Fr',
            'Sa',
        ]);
    });

    test('index', function (assert) {
        assert.equal(moment.months(0), 'January');
        assert.equal(moment.months(2), 'March');
        assert.equal(moment.monthsShort(0), 'Jan');
        assert.equal(moment.monthsShort(2), 'Mar');
        assert.equal(moment.weekdays(0), 'Sunday');
        assert.equal(moment.weekdays(2), 'Tuesday');
        assert.equal(moment.weekdaysShort(0), 'Sun');
        assert.equal(moment.weekdaysShort(2), 'Tue');
        assert.equal(moment.weekdaysMin(0), 'Su');
        assert.equal(moment.weekdaysMin(2), 'Tu');
    });

    test('localized', function (assert) {
        var months = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split(
                '_'
            ),
            monthsShort = 'on_tw_th_fo_fi_si_se_ei_ni_te_el_tw'.split('_'),
            weekdays = 'one_two_three_four_five_six_seven'.split('_'),
            weekdaysShort = 'on_tw_th_fo_fi_si_se'.split('_'),
            weekdaysMin = '1_2_3_4_5_6_7'.split('_'),
            weekdaysLocale = 'four_five_six_seven_one_two_three'.split('_'),
            weekdaysShortLocale = 'fo_fi_si_se_on_tw_th'.split('_'),
            weekdaysMinLocale = '4_5_6_7_1_2_3'.split('_'),
            week = {
                dow: 3,
                doy: 6,
            };

        moment.locale('numerologists', {
            months: months,
            monthsShort: monthsShort,
            weekdays: weekdays,
            weekdaysShort: weekdaysShort,
            weekdaysMin: weekdaysMin,
            week: week,
        });

        assert.deepEqual(moment.months(), months);
        assert.deepEqual(moment.monthsShort(), monthsShort);
        assert.deepEqual(moment.weekdays(), weekdays);
        assert.deepEqual(moment.weekdaysShort(), weekdaysShort);
        assert.deepEqual(moment.weekdaysMin(), weekdaysMin);

        assert.equal(moment.months(0), 'one');
        assert.equal(moment.monthsShort(0), 'on');
        assert.equal(moment.weekdays(0), 'one');
        assert.equal(moment.weekdaysShort(0), 'on');
        assert.equal(moment.weekdaysMin(0), '1');

        assert.equal(moment.months(2), 'three');
        assert.equal(moment.monthsShort(2), 'th');
        assert.equal(moment.weekdays(2), 'three');
        assert.equal(moment.weekdaysShort(2), 'th');
        assert.equal(moment.weekdaysMin(2), '3');

        assert.deepEqual(moment.weekdays(true), weekdaysLocale);
        assert.deepEqual(moment.weekdaysShort(true), weekdaysShortLocale);
        assert.deepEqual(moment.weekdaysMin(true), weekdaysMinLocale);

        assert.equal(moment.weekdays(true, 0), 'four');
        assert.equal(moment.weekdaysShort(true, 0), 'fo');
        assert.equal(moment.weekdaysMin(true, 0), '4');

        assert.equal(moment.weekdays(false, 2), 'three');
        assert.equal(moment.weekdaysShort(false, 2), 'th');
        assert.equal(moment.weekdaysMin(false, 2), '3');
    });

    test('with functions', function (assert) {
        var monthsShort = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split(
                '_'
            ),
            monthsShortWeird = 'onesy_twosy_threesy_foursy_fivesy_sixsy_sevensy_eightsy_ninesy_tensy_elevensy_twelvesy'.split(
                '_'
            );

        moment.locale('difficult', {
            monthsShort: function (m, format) {
                var arr = format.match(/-MMM-/) ? monthsShortWeird : monthsShort;
                return arr[m.month()];
            },
        });

        assert.deepEqual(moment.monthsShort(), monthsShort);
        assert.deepEqual(moment.monthsShort('MMM'), monthsShort);
        assert.deepEqual(moment.monthsShort('-MMM-'), monthsShortWeird);

        assert.deepEqual(moment.monthsShort('MMM', 2), 'three');
        assert.deepEqual(moment.monthsShort('-MMM-', 2), 'threesy');
        assert.deepEqual(moment.monthsShort(2), 'three');
    });

    test('with locale data', function (assert) {
        var months = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split(
                '_'
            ),
            monthsShort = 'on_tw_th_fo_fi_si_se_ei_ni_te_el_tw'.split('_'),
            weekdays = 'one_two_three_four_five_six_seven'.split('_'),
            weekdaysShort = 'on_tw_th_fo_fi_si_se'.split('_'),
            weekdaysMin = '1_2_3_4_5_6_7'.split('_'),
            customLocale = moment.localeData('numerologists');

        assert.deepEqual(customLocale.months(), months);
        assert.deepEqual(customLocale.monthsShort(), monthsShort);
        assert.deepEqual(customLocale.weekdays(), weekdays);
        assert.deepEqual(customLocale.weekdaysShort(), weekdaysShort);
        assert.deepEqual(customLocale.weekdaysMin(), weekdaysMin);
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('locale inheritance');

    test('calendar', function (assert) {
        moment.defineLocale('base-cal', {
            calendar: {
                sameDay: '[Today at] HH:mm',
                nextDay: '[Tomorrow at] HH:mm',
                nextWeek: '[Next week at] HH:mm',
                lastDay: '[Yesterday at] HH:mm',
                lastWeek: '[Last week at] HH:mm',
                sameElse: '[whatever]',
            },
        });
        moment.defineLocale('child-cal', {
            parentLocale: 'base-cal',
            calendar: {
                sameDay: '[Today] HH:mm',
                nextDay: '[Tomorrow] HH:mm',
                nextWeek: '[Next week] HH:mm',
            },
        });

        moment.locale('child-cal');
        var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);
        assert.equal(
            anchor.clone().add(3, 'hours').calendar(anchor),
            'Today 15:00',
            'today uses child version'
        );
        assert.equal(
            anchor.clone().add(1, 'day').calendar(anchor),
            'Tomorrow 12:00',
            'tomorrow uses child version'
        );
        assert.equal(
            anchor.clone().add(3, 'days').calendar(anchor),
            'Next week 12:00',
            'next week uses child version'
        );

        assert.equal(
            anchor.clone().subtract(1, 'day').calendar(anchor),
            'Yesterday at 12:00',
            'yesterday uses parent version'
        );
        assert.equal(
            anchor.clone().subtract(3, 'days').calendar(anchor),
            'Last week at 12:00',
            'last week uses parent version'
        );
        assert.equal(
            anchor.clone().subtract(7, 'days').calendar(anchor),
            'whatever',
            'sameElse uses parent version -'
        );
        assert.equal(
            anchor.clone().add(7, 'days').calendar(anchor),
            'whatever',
            'sameElse uses parent version +'
        );
    });

    test('missing', function (assert) {
        moment.defineLocale('base-cal-2', {
            calendar: {
                sameDay: '[Today at] HH:mm',
                nextDay: '[Tomorrow at] HH:mm',
                nextWeek: '[Next week at] HH:mm',
                lastDay: '[Yesterday at] HH:mm',
                lastWeek: '[Last week at] HH:mm',
                sameElse: '[whatever]',
            },
        });
        moment.defineLocale('child-cal-2', {
            parentLocale: 'base-cal-2',
        });
        moment.locale('child-cal-2');
        var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);
        assert.equal(
            anchor.clone().add(3, 'hours').calendar(anchor),
            'Today at 15:00',
            'today uses parent version'
        );
        assert.equal(
            anchor.clone().add(1, 'day').calendar(anchor),
            'Tomorrow at 12:00',
            'tomorrow uses parent version'
        );
        assert.equal(
            anchor.clone().add(3, 'days').calendar(anchor),
            'Next week at 12:00',
            'next week uses parent version'
        );
        assert.equal(
            anchor.clone().subtract(1, 'day').calendar(anchor),
            'Yesterday at 12:00',
            'yesterday uses parent version'
        );
        assert.equal(
            anchor.clone().subtract(3, 'days').calendar(anchor),
            'Last week at 12:00',
            'last week uses parent version'
        );
        assert.equal(
            anchor.clone().subtract(7, 'days').calendar(anchor),
            'whatever',
            'sameElse uses parent version -'
        );
        assert.equal(
            anchor.clone().add(7, 'days').calendar(anchor),
            'whatever',
            'sameElse uses parent version +'
        );
    });

    // Test function vs obj both directions

    test('long date format', function (assert) {
        moment.defineLocale('base-ldf', {
            longDateFormat: {
                LTS: 'h:mm:ss A',
                LT: 'h:mm A',
                L: 'MM/DD/YYYY',
                LL: 'MMMM D, YYYY',
                LLL: 'MMMM D, YYYY h:mm A',
                LLLL: 'dddd, MMMM D, YYYY h:mm A',
            },
        });
        moment.defineLocale('child-ldf', {
            parentLocale: 'base-ldf',
            longDateFormat: {
                LLL: '[SUMMER child] MMMM D, YYYY h:mm A',
                LLLL: '[SUMMER child] dddd, MMMM D, YYYY h:mm A',
            },
        });

        moment.locale('child-ldf');
        var anchor = moment.utc('2015-09-06T12:34:56', moment.ISO_8601);
        assert.equal(anchor.format('LTS'), '12:34:56 PM', 'LTS uses base');
        assert.equal(anchor.format('LT'), '12:34 PM', 'LT uses base');
        assert.equal(anchor.format('L'), '09/06/2015', 'L uses base');
        assert.equal(anchor.format('l'), '9/6/2015', 'l uses base');
        assert.equal(anchor.format('LL'), 'September 6, 2015', 'LL uses base');
        assert.equal(anchor.format('ll'), 'Sep 6, 2015', 'll uses base');
        assert.equal(
            anchor.format('LLL'),
            'SUMMER child September 6, 2015 12:34 PM',
            'LLL uses child'
        );
        assert.equal(
            anchor.format('lll'),
            'SUMMER child Sep 6, 2015 12:34 PM',
            'lll uses child'
        );
        assert.equal(
            anchor.format('LLLL'),
            'SUMMER child Sunday, September 6, 2015 12:34 PM',
            'LLLL uses child'
        );
        assert.equal(
            anchor.format('llll'),
            'SUMMER child Sun, Sep 6, 2015 12:34 PM',
            'llll uses child'
        );
    });

    test('ordinal', function (assert) {
        moment.defineLocale('base-ordinal-1', {
            ordinal: '%dx',
        });
        moment.defineLocale('child-ordinal-1', {
            parentLocale: 'base-ordinal-1',
            ordinal: '%dy',
        });

        assert.equal(
            moment.utc('2015-02-03', moment.ISO_8601).format('Do'),
            '3y',
            'ordinal uses child string'
        );

        moment.defineLocale('base-ordinal-2', {
            ordinal: '%dx',
        });
        moment.defineLocale('child-ordinal-2', {
            parentLocale: 'base-ordinal-2',
            ordinal: function (num) {
                return num + 'y';
            },
        });

        assert.equal(
            moment.utc('2015-02-03', moment.ISO_8601).format('Do'),
            '3y',
            'ordinal uses child function'
        );

        moment.defineLocale('base-ordinal-3', {
            ordinal: function (num) {
                return num + 'x';
            },
        });
        moment.defineLocale('child-ordinal-3', {
            parentLocale: 'base-ordinal-3',
            ordinal: '%dy',
        });

        assert.equal(
            moment.utc('2015-02-03', moment.ISO_8601).format('Do'),
            '3y',
            'ordinal uses child string (overwrite parent function)'
        );
    });

    test('ordinal parse', function (assert) {
        moment.defineLocale('base-ordinal-parse-1', {
            dayOfMonthOrdinalParse: /\d{1,2}x/,
        });
        moment.defineLocale('child-ordinal-parse-1', {
            parentLocale: 'base-ordinal-parse-1',
            dayOfMonthOrdinalParse: /\d{1,2}y/,
        });

        assert.ok(
            moment.utc('2015-01-1y', 'YYYY-MM-Do', true).isValid(),
            'ordinal parse uses child'
        );

        moment.defineLocale('base-ordinal-parse-2', {
            dayOfMonthOrdinalParse: /\d{1,2}x/,
        });
        moment.defineLocale('child-ordinal-parse-2', {
            parentLocale: 'base-ordinal-parse-2',
            dayOfMonthOrdinalParse: /\d{1,2}/,
        });

        assert.ok(
            moment.utc('2015-01-1', 'YYYY-MM-Do', true).isValid(),
            'ordinal parse uses child (default)'
        );
    });

    test('months', function (assert) {
        moment.defineLocale('base-months', {
            months: 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split(
                '_'
            ),
        });
        moment.defineLocale('child-months', {
            parentLocale: 'base-months',
            months: 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelfth '.split(
                '_'
            ),
        });
        assert.ok(
            moment.utc('2015-01-01', 'YYYY-MM-DD').format('MMMM'),
            'First',
            'months uses child'
        );
    });

    test('define child locale before parent', function (assert) {
        moment.defineLocale('months-x', null);
        moment.defineLocale('base-months-x', null);

        moment.defineLocale('months-x', {
            parentLocale: 'base-months-x',
            months: 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelfth '.split(
                '_'
            ),
        });
        assert.equal(
            moment.locale(),
            'en',
            'failed to set a locale requiring missing parent'
        );

        assert.equal(
            moment(
                '00:00:00 01/January/2017',
                'HH:mm:ss DD/MMM/YYYY',
                'months-x'
            ).locale(),
            'en',
            'creating moment using child with undefined parent defaults to global'
        );

        moment.defineLocale('base-months-x', {
            months: 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split(
                '_'
            ),
        });
        assert.equal(
            moment.locale(),
            'base-months-x',
            'defineLocale should also set the locale (regardless of child locales)'
        );

        assert.equal(
            moment().locale('months-x').month(0).format('MMMM'),
            'First',
            'loading child before parent locale works'
        );
    });

    test('lazy load parentLocale', function (assert) {
        moment.defineLocale('de_test', {
            parentLocale: 'de',
            monthsShort: [
                'M1',
                'M2',
                'M3',
                'M4',
                'M5',
                'M6',
                'M7',
                'M8',
                'M9',
                'M10',
                'M11',
                'M12',
            ],
        });
        assert.equal(
            moment.locale(),
            'de_test',
            'failed to lazy load parentLocale'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('locale update');

    test('calendar', function (assert) {
        moment.defineLocale('cal', null);
        moment.defineLocale('cal', {
            calendar: {
                sameDay: '[Today at] HH:mm',
                nextDay: '[Tomorrow at] HH:mm',
                nextWeek: '[Next week at] HH:mm',
                lastDay: '[Yesterday at] HH:mm',
                lastWeek: '[Last week at] HH:mm',
                sameElse: '[whatever]',
            },
        });
        moment.updateLocale('cal', {
            calendar: {
                sameDay: '[Today] HH:mm',
                nextDay: '[Tomorrow] HH:mm',
                nextWeek: '[Next week] HH:mm',
            },
        });

        moment.locale('cal');
        var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);
        assert.equal(
            anchor.clone().add(3, 'hours').calendar(anchor),
            'Today 15:00',
            'today uses child version'
        );
        assert.equal(
            anchor.clone().add(1, 'day').calendar(anchor),
            'Tomorrow 12:00',
            'tomorrow uses child version'
        );
        assert.equal(
            anchor.clone().add(3, 'days').calendar(anchor),
            'Next week 12:00',
            'next week uses child version'
        );

        assert.equal(
            anchor.clone().subtract(1, 'day').calendar(anchor),
            'Yesterday at 12:00',
            'yesterday uses parent version'
        );
        assert.equal(
            anchor.clone().subtract(3, 'days').calendar(anchor),
            'Last week at 12:00',
            'last week uses parent version'
        );
        assert.equal(
            anchor.clone().subtract(7, 'days').calendar(anchor),
            'whatever',
            'sameElse uses parent version -'
        );
        assert.equal(
            anchor.clone().add(7, 'days').calendar(anchor),
            'whatever',
            'sameElse uses parent version +'
        );
    });

    test('missing', function (assert) {
        moment.defineLocale('cal-2', null);
        moment.defineLocale('cal-2', {
            calendar: {
                sameDay: '[Today at] HH:mm',
                nextDay: '[Tomorrow at] HH:mm',
                nextWeek: '[Next week at] HH:mm',
                lastDay: '[Yesterday at] HH:mm',
                lastWeek: '[Last week at] HH:mm',
                sameElse: '[whatever]',
            },
        });
        moment.updateLocale('cal-2', {});
        moment.locale('cal-2');
        var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);
        assert.equal(
            anchor.clone().add(3, 'hours').calendar(anchor),
            'Today at 15:00',
            'today uses parent version'
        );
        assert.equal(
            anchor.clone().add(1, 'day').calendar(anchor),
            'Tomorrow at 12:00',
            'tomorrow uses parent version'
        );
        assert.equal(
            anchor.clone().add(3, 'days').calendar(anchor),
            'Next week at 12:00',
            'next week uses parent version'
        );
        assert.equal(
            anchor.clone().subtract(1, 'day').calendar(anchor),
            'Yesterday at 12:00',
            'yesterday uses parent version'
        );
        assert.equal(
            anchor.clone().subtract(3, 'days').calendar(anchor),
            'Last week at 12:00',
            'last week uses parent version'
        );
        assert.equal(
            anchor.clone().subtract(7, 'days').calendar(anchor),
            'whatever',
            'sameElse uses parent version -'
        );
        assert.equal(
            anchor.clone().add(7, 'days').calendar(anchor),
            'whatever',
            'sameElse uses parent version +'
        );
    });

    // Test function vs obj both directions

    test('long date format', function (assert) {
        moment.defineLocale('ldf', null);
        moment.defineLocale('ldf', {
            longDateFormat: {
                LTS: 'h:mm:ss A',
                LT: 'h:mm A',
                L: 'MM/DD/YYYY',
                LL: 'MMMM D, YYYY',
                LLL: 'MMMM D, YYYY h:mm A',
                LLLL: 'dddd, MMMM D, YYYY h:mm A',
            },
        });
        moment.updateLocale('ldf', {
            longDateFormat: {
                LLL: '[child] MMMM D, YYYY h:mm A',
                LLLL: '[child] dddd, MMMM D, YYYY h:mm A',
            },
        });

        moment.locale('ldf');
        var anchor = moment.utc('2015-09-06T12:34:56', moment.ISO_8601);
        assert.equal(anchor.format('LTS'), '12:34:56 PM', 'LTS uses base');
        assert.equal(anchor.format('LT'), '12:34 PM', 'LT uses base');
        assert.equal(anchor.format('L'), '09/06/2015', 'L uses base');
        assert.equal(anchor.format('l'), '9/6/2015', 'l uses base');
        assert.equal(anchor.format('LL'), 'September 6, 2015', 'LL uses base');
        assert.equal(anchor.format('ll'), 'Sep 6, 2015', 'll uses base');
        assert.equal(
            anchor.format('LLL'),
            'child September 6, 2015 12:34 PM',
            'LLL uses child'
        );
        assert.equal(
            anchor.format('lll'),
            'child Sep 6, 2015 12:34 PM',
            'lll uses child'
        );
        assert.equal(
            anchor.format('LLLL'),
            'child Sunday, September 6, 2015 12:34 PM',
            'LLLL uses child'
        );
        assert.equal(
            anchor.format('llll'),
            'child Sun, Sep 6, 2015 12:34 PM',
            'llll uses child'
        );
    });

    test('ordinal', function (assert) {
        moment.defineLocale('ordinal-1', null);
        moment.defineLocale('ordinal-1', {
            ordinal: '%dx',
        });
        moment.updateLocale('ordinal-1', {
            ordinal: '%dy',
        });

        assert.equal(
            moment.utc('2015-02-03', moment.ISO_8601).format('Do'),
            '3y',
            'ordinal uses child string'
        );

        moment.defineLocale('ordinal-2', null);
        moment.defineLocale('ordinal-2', {
            ordinal: '%dx',
        });
        moment.updateLocale('ordinal-2', {
            ordinal: function (num) {
                return num + 'y';
            },
        });

        assert.equal(
            moment.utc('2015-02-03', moment.ISO_8601).format('Do'),
            '3y',
            'ordinal uses child function'
        );

        moment.defineLocale('ordinal-3', null);
        moment.defineLocale('ordinal-3', {
            ordinal: function (num) {
                return num + 'x';
            },
        });
        moment.updateLocale('ordinal-3', {
            ordinal: '%dy',
        });

        assert.equal(
            moment.utc('2015-02-03', moment.ISO_8601).format('Do'),
            '3y',
            'ordinal uses child string (overwrite parent function)'
        );
    });

    test('ordinal parse', function (assert) {
        moment.defineLocale('ordinal-parse-1', null);
        moment.defineLocale('ordinal-parse-1', {
            dayOfMonthOrdinalParse: /\d{1,2}x/,
        });
        moment.updateLocale('ordinal-parse-1', {
            dayOfMonthOrdinalParse: /\d{1,2}y/,
        });

        assert.ok(
            moment.utc('2015-01-1y', 'YYYY-MM-Do', true).isValid(),
            'ordinal parse uses child'
        );

        moment.defineLocale('ordinal-parse-2', null);
        moment.defineLocale('ordinal-parse-2', {
            dayOfMonthOrdinalParse: /\d{1,2}x/,
        });
        moment.updateLocale('ordinal-parse-2', {
            dayOfMonthOrdinalParse: /\d{1,2}/,
        });

        assert.ok(
            moment.utc('2015-01-1', 'YYYY-MM-Do', true).isValid(),
            'ordinal parse uses child (default)'
        );
    });

    test('months', function (assert) {
        moment.defineLocale('months', null);
        moment.defineLocale('months', {
            months: 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split(
                '_'
            ),
        });
        moment.updateLocale('months', {
            parentLocale: 'base-months',
            months: 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelfth '.split(
                '_'
            ),
        });
        assert.ok(
            moment.utc('2015-01-01', 'YYYY-MM-DD').format('MMMM'),
            'First',
            'months uses child'
        );
    });

    test('update existing locale', function (assert) {
        moment.updateLocale('de', {
            monthsShort: [
                'JAN',
                'FEB',
                'MÄR',
                'APR',
                'MAI',
                'JUN',
                'JUL',
                'AUG',
                'SEP',
                'OKT',
                'NOV',
                'DEZ',
            ],
        });
        assert.equal(
            moment('2017-02-01').format('YYYY MMM MMMM'),
            '2017 FEB Februar'
        );
        moment.updateLocale('de', null);
    });

    test('update non-existing locale', function (assert) {
        moment.locale('en');
        moment.updateLocale('dude', { months: ['Movember'] });
        assert.equal(moment.locale(), 'dude');
        assert.equal(moment().locale('dude').locale(), 'dude');
        moment.defineLocale('dude', null);
    });

    test('reset locale', function (assert) {
        moment.locale('de');
        var resultBeforeUpdate = moment('2017-02-01').format('YYYY MMM MMMM');
        moment.updateLocale('de', {
            monthsShort: [
                'JAN',
                'FEB',
                'MÄR',
                'APR',
                'MAI',
                'JUN',
                'JUL',
                'AUG',
                'SEP',
                'OKT',
                'NOV',
                'DEZ',
            ],
        });
        moment.updateLocale('de', null);
        assert.equal(
            moment('2017-02-01').format('YYYY MMM MMMM'),
            resultBeforeUpdate
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    var indexOf;

    if (Array.prototype.indexOf) {
        indexOf = Array.prototype.indexOf;
    } else {
        indexOf = function (o) {
            // I know
            var i;
            for (i = 0; i < this.length; ++i) {
                if (this[i] === o) {
                    return i;
                }
            }
            return -1;
        };
    }

    module('locale', {
        setup: function () {
            // TODO: Remove once locales are switched to ES6
            each(
                [
                    {
                        name: 'en-gb',
                        data: {},
                    },
                    {
                        name: 'en-ca',
                        data: {},
                    },
                    {
                        name: 'es',
                        data: {
                            relativeTime: {
                                past: 'hace %s',
                                s: 'unos segundos',
                                d: 'un día',
                            },
                            months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split(
                                '_'
                            ),
                        },
                    },
                    {
                        name: 'fr',
                        data: {},
                    },
                    {
                        name: 'fr-ca',
                        data: {},
                    },
                    {
                        name: 'it',
                        data: {},
                    },
                    {
                        name: 'zh-cn',
                        data: {
                            months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(
                                '_'
                            ),
                        },
                    },
                ],
                function (locale) {
                    if (moment.locale(locale.name) !== locale.name) {
                        moment.defineLocale(locale.name, locale.data);
                    }
                }
            );
            moment.locale('en');
        },
    });

    test('library getters and setters', function (assert) {
        var r = moment.locale('en');

        assert.equal(r, 'en', 'locale should return en by default');
        assert.equal(moment.locale(), 'en', 'locale should return en by default');

        moment.locale('fr');
        assert.equal(
            moment.locale(),
            'fr',
            'locale should return the changed locale'
        );

        moment.locale('en-gb');
        assert.equal(
            moment.locale(),
            'en-gb',
            'locale should return the changed locale'
        );

        moment.locale('en');
        assert.equal(moment.locale(), 'en', 'locale should reset');

        moment.locale('does-not-exist');
        assert.equal(moment.locale(), 'en', 'locale should reset');

        moment.locale('EN');
        assert.equal(moment.locale(), 'en', 'Normalize locale key case');

        moment.locale('EN_gb');
        assert.equal(moment.locale(), 'en-gb', 'Normalize locale key underscore');
    });

    test('library setter array of locales', function (assert) {
        assert.equal(
            moment.locale(['non-existent', 'fr', 'also-non-existent']),
            'fr',
            'passing an array uses the first valid locale'
        );
        assert.equal(
            moment.locale(['es', 'fr', 'also-non-existent']),
            'es',
            'passing an array uses the first valid locale'
        );
    });

    test('library setter locale substrings', function (assert) {
        assert.equal(moment.locale('fr-crap'), 'fr', 'use substrings');
        assert.equal(
            moment.locale('fr-does-not-exist'),
            'fr',
            'uses deep substrings'
        );
        assert.equal(
            moment.locale('fr-CA-does-not-exist'),
            'fr-ca',
            'uses deepest substring'
        );
    });

    test('library getter locale array and substrings', function (assert) {
        assert.equal(
            moment.locale(['en-CH', 'fr']),
            'en',
            'prefer root locale to shallower ones'
        );
        assert.equal(
            moment.locale(['en-gb-leeds', 'en-CA']),
            'en-gb',
            'prefer root locale to shallower ones'
        );
        assert.equal(
            moment.locale(['en-fake', 'en-CA']),
            'en-ca',
            'prefer alternatives with shared roots'
        );
        assert.equal(
            moment.locale(['en-fake', 'en-fake2', 'en-ca']),
            'en-ca',
            'prefer alternatives with shared roots'
        );
        assert.equal(
            moment.locale(['fake-CA', 'fake-MX', 'fr']),
            'fr',
            'always find something if possible'
        );
        assert.equal(
            moment.locale(['fake-CA', 'fake-MX', 'fr']),
            'fr',
            'always find something if possible'
        );
        assert.equal(
            moment.locale(['fake-CA', 'fake-MX', 'fr-fake-fake-fake']),
            'fr',
            'always find something if possible'
        );
        assert.equal(
            moment.locale(['en', 'en-CA']),
            'en',
            'prefer earlier if it works'
        );
    });

    test('library ensure inheritance', function (assert) {
        moment.locale('made-up', {
            // I put them out of order
            months: 'February_March_April_May_June_July_August_September_October_November_December_January'.split(
                '_'
            ),
            // the rest of the properties should be inherited.
        });

        assert.equal(
            moment([2012, 5, 6]).format('MMMM'),
            'July',
            'Override some of the configs'
        );
        assert.equal(
            moment([2012, 5, 6]).format('MMM'),
            'Jun',
            'But not all of them'
        );
    });

    test('library ensure inheritance LT L LL LLL LLLL', function (assert) {
        var locale = 'test-inherit-lt';

        moment.defineLocale(locale, {
            longDateFormat: {
                LT: '-[LT]-',
                L: '-[L]-',
                LL: '-[LL]-',
                LLL: '-[LLL]-',
                LLLL: '-[LLLL]-',
            },
            calendar: {
                sameDay: '[sameDay] LT',
                nextDay: '[nextDay] L',
                nextWeek: '[nextWeek] LL',
                lastDay: '[lastDay] LLL',
                lastWeek: '[lastWeek] LLLL',
                sameElse: 'L',
            },
        });

        moment.locale('es');

        assert.equal(
            moment().locale(locale).calendar(),
            'sameDay -LT-',
            'Should use instance locale in LT formatting'
        );
        assert.equal(
            moment().add(1, 'days').locale(locale).calendar(),
            'nextDay -L-',
            'Should use instance locale in L formatting'
        );
        assert.equal(
            moment().add(-1, 'days').locale(locale).calendar(),
            'lastDay -LLL-',
            'Should use instance locale in LL formatting'
        );
        assert.equal(
            moment().add(4, 'days').locale(locale).calendar(),
            'nextWeek -LL-',
            'Should use instance locale in LLL formatting'
        );
        assert.equal(
            moment().add(-4, 'days').locale(locale).calendar(),
            'lastWeek -LLLL-',
            'Should use instance locale in LLLL formatting'
        );
    });

    test('library localeData', function (assert) {
        moment.locale('en');

        var jan = moment([2000, 0]);

        assert.equal(
            moment.localeData().months(jan),
            'January',
            'no arguments returns global'
        );
        assert.equal(
            moment.localeData('zh-cn').months(jan),
            '一月',
            'a string returns the locale based on key'
        );
        assert.equal(
            moment.localeData(moment().locale('es')).months(jan),
            'enero',
            "if you pass in a moment it uses the moment's locale"
        );
    });

    test('library deprecations', function (assert) {
        test.expectedDeprecations('moment.lang');
        moment.lang('dude', { months: ['Movember'] });
        assert.equal(moment.locale(), 'dude', 'setting the lang sets the locale');
        assert.equal(moment.lang(), moment.locale());
        assert.equal(
            moment.langData(),
            moment.localeData(),
            'langData is localeData'
        );
        moment.defineLocale('dude', null);
    });

    test('defineLocale', function (assert) {
        moment.locale('en');
        moment.defineLocale('dude', { months: ['Movember'] });
        assert.equal(moment().locale(), 'dude', 'defineLocale also sets it');
        assert.equal(
            moment().locale('dude').locale(),
            'dude',
            'defineLocale defines a locale'
        );
        moment.defineLocale('dude', null);
    });

    test('locales', function (assert) {
        moment.defineLocale('dude', { months: ['Movember'] });
        assert.equal(
            true,
            !!~indexOf.call(moment.locales(), 'dude'),
            'locales returns an array of defined locales'
        );
        assert.equal(
            true,
            !!~indexOf.call(moment.locales(), 'en'),
            'locales should always include english'
        );
        moment.defineLocale('dude', null);
    });

    test('library convenience', function (assert) {
        moment.locale('something', { week: { dow: 3 } });
        moment.locale('something');
        assert.equal(
            moment.locale(),
            'something',
            'locale can be used to create the locale too'
        );
        moment.defineLocale('something', null);
    });

    test('firstDayOfWeek firstDayOfYear locale getters', function (assert) {
        moment.locale('something', { week: { dow: 3, doy: 4 } });
        moment.locale('something');
        assert.equal(moment.localeData().firstDayOfWeek(), 3, 'firstDayOfWeek');
        assert.equal(moment.localeData().firstDayOfYear(), 4, 'firstDayOfYear');
        moment.defineLocale('something', null);
    });

    test('instance locale method', function (assert) {
        moment.locale('en');

        assert.equal(
            moment([2012, 5, 6]).format('MMMM'),
            'June',
            'Normally default to global'
        );
        assert.equal(
            moment([2012, 5, 6]).locale('es').format('MMMM'),
            'junio',
            'Use the instance specific locale'
        );
        assert.equal(
            moment([2012, 5, 6]).format('MMMM'),
            'June',
            'Using an instance specific locale does not affect other moments'
        );
    });

    test('instance locale method with array', function (assert) {
        var m = moment().locale(['non-existent', 'fr', 'also-non-existent']);
        assert.equal(
            m.locale(),
            'fr',
            'passing an array uses the first valid locale'
        );
        m = moment().locale(['es', 'fr', 'also-non-existent']);
        assert.equal(
            m.locale(),
            'es',
            'passing an array uses the first valid locale'
        );
    });

    test('instance getter locale substrings', function (assert) {
        var m = moment();

        m.locale('fr-crap');
        assert.equal(m.locale(), 'fr', 'use substrings');

        m.locale('fr-does-not-exist');
        assert.equal(m.locale(), 'fr', 'uses deep substrings');
    });

    test('instance locale persists with manipulation', function (assert) {
        moment.locale('en');

        assert.equal(
            moment([2012, 5, 6]).locale('es').add({ days: 1 }).format('MMMM'),
            'junio',
            'With addition'
        );
        assert.equal(
            moment([2012, 5, 6]).locale('es').day(0).format('MMMM'),
            'junio',
            'With day getter'
        );
        assert.equal(
            moment([2012, 5, 6]).locale('es').endOf('day').format('MMMM'),
            'junio',
            'With endOf'
        );
    });

    test('instance locale persists with cloning', function (assert) {
        moment.locale('en');

        var a = moment([2012, 5, 6]).locale('es'),
            b = a.clone();

        assert.equal(b.format('MMMM'), 'junio', 'using moment.fn.clone()');
        assert.equal(b.format('MMMM'), 'junio', 'using moment()');
    });

    test('duration locale method', function (assert) {
        moment.locale('en');

        assert.equal(
            moment.duration({ seconds: 44 }).humanize(),
            'a few seconds',
            'Normally default to global'
        );
        assert.equal(
            moment.duration({ seconds: 44 }).locale('es').humanize(),
            'unos segundos',
            'Use the instance specific locale'
        );
        assert.equal(
            moment.duration({ seconds: 44 }).humanize(),
            'a few seconds',
            'Using an instance specific locale does not affect other durations'
        );
    });

    test('duration locale persists with cloning', function (assert) {
        moment.locale('en');

        var a = moment.duration({ seconds: 44 }).locale('es'),
            b = moment.duration(a);

        assert.equal(b.humanize(), 'unos segundos', 'using moment.duration()');
    });

    test("changing the global locale doesn't affect existing duration instances", function (assert) {
        var mom = moment.duration();
        moment.locale('fr');
        assert.equal('en', mom.locale());
    });

    test('duration deprecations', function (assert) {
        test.expectedDeprecations('moment().lang()');
        assert.equal(
            moment.duration().lang(),
            moment.duration().localeData(),
            'duration.lang is the same as duration.localeData'
        );
    });

    test('from and fromNow with invalid date', function (assert) {
        assert.equal(
            moment(NaN).from(),
            'Invalid date',
            'moment.from with invalid moment'
        );
        assert.equal(
            moment(NaN).fromNow(),
            'Invalid date',
            'moment.fromNow with invalid moment'
        );
    });

    test('from relative time future', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ s: 44 })),
            'in a few seconds',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ s: 45 })),
            'in a minute',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ s: 89 })),
            'in a minute',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ s: 90 })),
            'in 2 minutes',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ m: 44 })),
            'in 44 minutes',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ m: 45 })),
            'in an hour',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ m: 89 })),
            'in an hour',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ m: 90 })),
            'in 2 hours',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ h: 5 })),
            'in 5 hours',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ h: 21 })),
            'in 21 hours',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ h: 22 })),
            'in a day',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ h: 35 })),
            'in a day',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ h: 36 })),
            'in 2 days',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 1 })),
            'in a day',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 5 })),
            'in 5 days',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 25 })),
            'in 25 days',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 26 })),
            'in a month',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 30 })),
            'in a month',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 45 })),
            'in a month',
            '45 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 47 })),
            'in 2 months',
            '47 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 74 })),
            'in 2 months',
            '74 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 78 })),
            'in 3 months',
            '78 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ M: 1 })),
            'in a month',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ M: 5 })),
            'in 5 months',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 315 })),
            'in 10 months',
            '315 days = 10 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 344 })),
            'in a year',
            '344 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 345 })),
            'in a year',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ d: 548 })),
            'in 2 years',
            '548 days = in 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ y: 1 })),
            'in a year',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).subtract({ y: 5 })),
            'in 5 years',
            '5 years = 5 years'
        );
    });

    test('from relative time past', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 44 })),
            'a few seconds ago',
            '44 seconds = a few seconds'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 45 })),
            'a minute ago',
            '45 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 89 })),
            'a minute ago',
            '89 seconds = a minute'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 })),
            '2 minutes ago',
            '90 seconds = 2 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 44 })),
            '44 minutes ago',
            '44 minutes = 44 minutes'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 45 })),
            'an hour ago',
            '45 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 89 })),
            'an hour ago',
            '89 minutes = an hour'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ m: 90 })),
            '2 hours ago',
            '90 minutes = 2 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 5 })),
            '5 hours ago',
            '5 hours = 5 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 21 })),
            '21 hours ago',
            '21 hours = 21 hours'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 22 })),
            'a day ago',
            '22 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 35 })),
            'a day ago',
            '35 hours = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ h: 36 })),
            '2 days ago',
            '36 hours = 2 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 1 })),
            'a day ago',
            '1 day = a day'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 5 })),
            '5 days ago',
            '5 days = 5 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 25 })),
            '25 days ago',
            '25 days = 25 days'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 26 })),
            'a month ago',
            '26 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 30 })),
            'a month ago',
            '30 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 43 })),
            'a month ago',
            '43 days = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 46 })),
            '2 months ago',
            '46 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 74 })),
            '2 months ago',
            '75 days = 2 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 76 })),
            '3 months ago',
            '76 days = 3 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 1 })),
            'a month ago',
            '1 month = a month'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ M: 5 })),
            '5 months ago',
            '5 months = 5 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 315 })),
            '10 months ago',
            '315 days = 10 months'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 344 })),
            'a year ago',
            '344 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 345 })),
            'a year ago',
            '345 days = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ d: 548 })),
            '2 years ago',
            '548 days = 2 years'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 1 })),
            'a year ago',
            '1 year = a year'
        );
        assert.equal(
            start.from(moment([2007, 1, 28]).add({ y: 5 })),
            '5 years ago',
            '5 years = 5 years'
        );
    });

    test('instance locale used with from', function (assert) {
        moment.locale('en');

        var a = moment([2012, 5, 6]).locale('es'),
            b = moment([2012, 5, 7]);

        assert.equal(a.from(b), 'hace un día', 'preserve locale of first moment');
        assert.equal(
            b.from(a),
            'in a day',
            'do not preserve locale of second moment'
        );
    });

    test('instance localeData', function (assert) {
        moment.defineLocale('dude', { week: { dow: 3 } });
        assert.equal(moment().locale('dude').localeData()._week.dow, 3);
        moment.defineLocale('dude', null);
    });

    test('month name callback function', function (assert) {
        function fakeReplace(m, format) {
            if (/test/.test(format)) {
                return 'test';
            }
            if (m.date() === 1) {
                return 'date';
            }
            return 'default';
        }

        moment.locale('made-up-2', {
            months: fakeReplace,
            monthsShort: fakeReplace,
            weekdays: fakeReplace,
            weekdaysShort: fakeReplace,
            weekdaysMin: fakeReplace,
        });

        assert.equal(
            moment().format('[test] dd ddd dddd MMM MMMM'),
            'test test test test test test',
            'format month name function should be able to access the format string'
        );
        assert.equal(
            moment([2011, 0, 1]).format('dd ddd dddd MMM MMMM'),
            'date date date date date',
            'format month name function should be able to access the moment object'
        );
        assert.equal(
            moment([2011, 0, 2]).format('dd ddd dddd MMM MMMM'),
            'default default default default default',
            'format month name function should be able to access the moment object'
        );
    });

    test('changing parts of a locale config', function (assert) {
        test.expectedDeprecations('defineLocaleOverride');

        moment.locale('partial-lang', {
            months: 'a b c d e f g h i j k l'.split(' '),
        });

        assert.equal(
            moment([2011, 0, 1]).format('MMMM'),
            'a',
            'should be able to set locale values when creating the localeuage'
        );

        moment.locale('partial-lang', {
            monthsShort: 'A B C D E F G H I J K L'.split(' '),
        });

        assert.equal(
            moment([2011, 0, 1]).format('MMMM MMM'),
            'a A',
            'should be able to set locale values after creating the localeuage'
        );

        moment.defineLocale('partial-lang', null);
    });

    test('start/endOf week feature for first-day-is-monday locales', function (assert) {
        moment.locale('monday-lang', {
            week: {
                dow: 1, // Monday is the first day of the week
            },
        });

        moment.locale('monday-lang');
        assert.equal(
            moment([2013, 0, 1]).startOf('week').day(),
            1,
            'for locale monday-lang first day of the week should be monday'
        );
        assert.equal(
            moment([2013, 0, 1]).endOf('week').day(),
            0,
            'for locale monday-lang last day of the week should be sunday'
        );
        moment.defineLocale('monday-lang', null);
    });

    test('meridiem parsing', function (assert) {
        moment.locale('meridiem-parsing', {
            meridiemParse: /[bd]/i,
            isPM: function (input) {
                return input === 'b';
            },
        });

        moment.locale('meridiem-parsing');
        assert.equal(
            moment('2012-01-01 3b', 'YYYY-MM-DD ha').hour(),
            15,
            'Custom parsing of meridiem should work'
        );
        assert.equal(
            moment('2012-01-01 3d', 'YYYY-MM-DD ha').hour(),
            3,
            'Custom parsing of meridiem should work'
        );
        moment.defineLocale('meridiem-parsing', null);
    });

    test('invalid date formatting', function (assert) {
        moment.locale('has-invalid', {
            invalidDate: 'KHAAAAAAAAAAAN!',
        });

        assert.equal(moment.invalid().format(), 'KHAAAAAAAAAAAN!');
        assert.equal(moment.invalid().format('YYYY-MM-DD'), 'KHAAAAAAAAAAAN!');
        moment.defineLocale('has-invalid', null);
    });

    test('return locale name', function (assert) {
        var registered = moment.locale('return-this', {});

        assert.equal(registered, 'return-this', 'returns the locale configured');
        moment.defineLocale('return-this', null);
    });

    test("changing the global locale doesn't affect existing instances", function (assert) {
        var mom = moment();
        moment.locale('fr');
        assert.equal('en', mom.locale());
    });

    test('setting a language on instance returns the original moment for chaining', function (assert) {
        test.expectedDeprecations('moment().lang()');
        var mom = moment();

        assert.equal(
            mom.lang('fr'),
            mom,
            'setting the language (lang) returns the original moment for chaining'
        );
        assert.equal(
            mom.locale('it'),
            mom,
            'setting the language (locale) returns the original moment for chaining'
        );
    });

    test('lang(key) changes the language of the instance', function (assert) {
        test.expectedDeprecations('moment().lang()');
        var m = moment().month(0);
        m.lang('fr');
        assert.equal(m.locale(), 'fr', 'm.lang(key) changes instance locale');
    });

    test('moment#locale(false) resets to global locale', function (assert) {
        var m = moment();

        moment.locale('fr');
        m.locale('it');

        assert.equal(moment.locale(), 'fr', 'global locale is it');
        assert.equal(m.locale(), 'it', 'instance locale is it');
        m.locale(false);
        assert.equal(m.locale(), 'fr', 'instance locale reset to global locale');
    });

    test("moment().locale with missing key doesn't change locale", function (assert) {
        assert.equal(
            moment().locale('boo').localeData(),
            moment.localeData(),
            'preserve global locale in case of bad locale id'
        );
    });

    test("moment().lang with missing key doesn't change locale", function (assert) {
        test.expectedDeprecations('moment().lang()');
        assert.equal(
            moment().lang('boo').localeData(),
            moment.localeData(),
            'preserve global locale in case of bad locale id'
        );
    });

    test('when in strict mode with inexact parsing, treat periods in short weekdays literally, not as the regex-period', function (assert) {
        moment.defineLocale('periods-in-short-weekdays', {
            weekdays: 'Monday_Tuesday_Wednesday_Thursday_Friday_Saturday_Sunday'.split(
                '_'
            ),
            weekdaysShort: 'mon_t...s_wed_thurs_fri_sat_sun'.split('_'),
            weekdaysParseExact: false,
        });

        moment().locale('periods-in-short-weekdays');
        assert.equal(moment('thurs', 'ddd', true).format('dddd'), 'Thursday');
    });

    test('when in strict mode with inexact parsing, treat periods in full weekdays literally, not as the regex-period', function (assert) {
        moment.defineLocale('periods-in-full-weekdays', {
            weekdays: 'Monday_T....day_Wednesday_Thursday_Friday_Saturday_Sunday'.split(
                '_'
            ),
            weekdaysShort: 'mon_tues_wed_thurs_fri_sat_sun'.split('_'),
            weekdaysParseExact: false,
        });

        moment().locale('periods-in-full-weekdays');
        assert.equal(moment('Thursday', 'dddd', true).format('ddd'), 'thurs');
    });

    test('when in strict mode with inexact parsing, treat periods in min-weekdays literally, not as the regex-period', function (assert) {
        moment.defineLocale('periods-in-min-weekdays', {
            weekdays: 'Monday_Tuesday_Wednesday_Thursday_Friday_Saturday_Sunday'.split(
                '_'
            ),
            weekdaysMin: 'mon_t...s_wed_thurs_fri_sat_sun'.split('_'),
            weekdaysParseExact: false,
        });

        moment().locale('periods-in-min-weekdays');
        assert.equal(moment('thurs', 'dd', true).format('dddd'), 'Thursday');
    });

    // TODO: Enable this after fixing pl months parse hack hack
    // test('monthsParseExact', function (assert) {
    //     var locale = 'test-months-parse-exact';

    //     moment.defineLocale(locale, {
    //         monthsParseExact: true,
    //         months: 'A_AA_AAA_B_B B_BB  B_C_C-C_C,C2C_D_D+D_D`D*D'.split('_'),
    //         monthsShort: 'E_EE_EEE_F_FF_FFF_G_GG_GGG_H_HH_HHH'.split('_')
    //     });

    //     assert.equal(moment('A', 'MMMM', true).month(), 0, 'parse long month 0 with MMMM');
    //     assert.equal(moment('AA', 'MMMM', true).month(), 1, 'parse long month 1 with MMMM');
    //     assert.equal(moment('AAA', 'MMMM', true).month(), 2, 'parse long month 2 with MMMM');
    //     assert.equal(moment('B B', 'MMMM', true).month(), 4, 'parse long month 4 with MMMM');
    //     assert.equal(moment('BB  B', 'MMMM', true).month(), 5, 'parse long month 5 with MMMM');
    //     assert.equal(moment('C-C', 'MMMM', true).month(), 7, 'parse long month 7 with MMMM');
    //     assert.equal(moment('C,C2C', 'MMMM', true).month(), 8, 'parse long month 8 with MMMM');
    //     assert.equal(moment('D+D', 'MMMM', true).month(), 10, 'parse long month 10 with MMMM');
    //     assert.equal(moment('D`D*D', 'MMMM', true).month(), 11, 'parse long month 11 with MMMM');

    //     assert.equal(moment('E', 'MMM', true).month(), 0, 'parse long month 0 with MMM');
    //     assert.equal(moment('EE', 'MMM', true).month(), 1, 'parse long month 1 with MMM');
    //     assert.equal(moment('EEE', 'MMM', true).month(), 2, 'parse long month 2 with MMM');

    //     assert.equal(moment('A', 'MMM').month(), 0, 'non-strict parse long month 0 with MMM');
    //     assert.equal(moment('AA', 'MMM').month(), 1, 'non-strict parse long month 1 with MMM');
    //     assert.equal(moment('AAA', 'MMM').month(), 2, 'non-strict parse long month 2 with MMM');
    //     assert.equal(moment('E', 'MMMM').month(), 0, 'non-strict parse short month 0 with MMMM');
    //     assert.equal(moment('EE', 'MMMM').month(), 1, 'non-strict parse short month 1 with MMMM');
    //     assert.equal(moment('EEE', 'MMMM').month(), 2, 'non-strict parse short month 2 with MMMM');
    // });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('min max');

    test('min', function (assert) {
        var now = moment(),
            future = now.clone().add(1, 'month'),
            past = now.clone().subtract(1, 'month'),
            invalid = moment.invalid();

        assert.equal(moment.min(now, future, past), past, 'min(now, future, past)');
        assert.equal(moment.min(future, now, past), past, 'min(future, now, past)');
        assert.equal(moment.min(future, past, now), past, 'min(future, past, now)');
        assert.equal(moment.min(past, future, now), past, 'min(past, future, now)');
        assert.equal(moment.min(now, past), past, 'min(now, past)');
        assert.equal(moment.min(past, now), past, 'min(past, now)');
        assert.equal(moment.min(now), now, 'min(now, past)');

        assert.equal(
            moment.min([now, future, past]),
            past,
            'min([now, future, past])'
        );
        assert.equal(moment.min([now, past]), past, 'min(now, past)');
        assert.equal(moment.min([now]), now, 'min(now)');

        assert.equal(moment.min([now, invalid]), invalid, 'min(now, invalid)');
        assert.equal(moment.min([invalid, now]), invalid, 'min(invalid, now)');
    });

    test('max', function (assert) {
        var now = moment(),
            future = now.clone().add(1, 'month'),
            past = now.clone().subtract(1, 'month'),
            invalid = moment.invalid();

        assert.equal(
            moment.max(now, future, past),
            future,
            'max(now, future, past)'
        );
        assert.equal(
            moment.max(future, now, past),
            future,
            'max(future, now, past)'
        );
        assert.equal(
            moment.max(future, past, now),
            future,
            'max(future, past, now)'
        );
        assert.equal(
            moment.max(past, future, now),
            future,
            'max(past, future, now)'
        );
        assert.equal(moment.max(now, past), now, 'max(now, past)');
        assert.equal(moment.max(past, now), now, 'max(past, now)');
        assert.equal(moment.max(now), now, 'max(now, past)');

        assert.equal(
            moment.max([now, future, past]),
            future,
            'max([now, future, past])'
        );
        assert.equal(moment.max([now, past]), now, 'max(now, past)');
        assert.equal(moment.max([now]), now, 'max(now)');

        assert.equal(moment.max([now, invalid]), invalid, 'max(now, invalid)');
        assert.equal(moment.max([invalid, now]), invalid, 'max(invalid, now)');
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('mutable');

    test('manipulation methods', function (assert) {
        var m = moment();

        assert.equal(m, m.year(2011), 'year() should be mutable');
        assert.equal(m, m.month(1), 'month() should be mutable');
        assert.equal(m, m.hours(7), 'hours() should be mutable');
        assert.equal(m, m.minutes(33), 'minutes() should be mutable');
        assert.equal(m, m.seconds(44), 'seconds() should be mutable');
        assert.equal(m, m.milliseconds(55), 'milliseconds() should be mutable');
        assert.equal(m, m.day(2), 'day() should be mutable');
        assert.equal(m, m.startOf('week'), 'startOf() should be mutable');
        assert.equal(m, m.add(1, 'days'), 'add() should be mutable');
        assert.equal(m, m.subtract(2, 'years'), 'subtract() should be mutable');
        assert.equal(m, m.local(), 'local() should be mutable');
        assert.equal(m, m.utc(), 'utc() should be mutable');
    });

    test('non mutable methods', function (assert) {
        var m = moment();
        assert.notEqual(m, m.clone(), 'clone() should not be mutable');
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('normalize units');

    test('normalize units', function (assert) {
        var fullKeys = [
                'year',
                'quarter',
                'month',
                'isoWeek',
                'week',
                'day',
                'hour',
                'minute',
                'second',
                'millisecond',
                'date',
                'dayOfYear',
                'weekday',
                'isoWeekday',
                'weekYear',
                'isoWeekYear',
            ],
            aliases = [
                'y',
                'Q',
                'M',
                'W',
                'w',
                'd',
                'h',
                'm',
                's',
                'ms',
                'D',
                'DDD',
                'e',
                'E',
                'gg',
                'GG',
            ],
            length = fullKeys.length,
            fullKey,
            fullKeyCaps,
            fullKeyPlural,
            fullKeyCapsPlural,
            alias,
            index;

        for (index = 0; index < length; index += 1) {
            fullKey = fullKeys[index];
            fullKeyCaps = fullKey.toUpperCase();
            fullKeyPlural = fullKey + 's';
            fullKeyCapsPlural = fullKeyCaps + 's';
            alias = aliases[index];
            assert.equal(
                moment.normalizeUnits(fullKey),
                fullKey,
                'Testing full key ' + fullKey
            );
            assert.equal(
                moment.normalizeUnits(fullKeyCaps),
                fullKey,
                'Testing full key capitalised ' + fullKey
            );
            assert.equal(
                moment.normalizeUnits(fullKeyPlural),
                fullKey,
                'Testing full key plural ' + fullKey
            );
            assert.equal(
                moment.normalizeUnits(fullKeyCapsPlural),
                fullKey,
                'Testing full key capitalised and plural ' + fullKey
            );
            assert.equal(
                moment.normalizeUnits(alias),
                fullKey,
                'Testing alias ' + fullKey
            );
        }
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('now');

    test('now', function (assert) {
        var startOfTest = new Date().valueOf(),
            momentNowTime = moment.now(),
            afterMomentCreationTime = new Date().valueOf();

        assert.ok(
            startOfTest <= momentNowTime,
            'moment now() time should be now, not in the past'
        );
        assert.ok(
            momentNowTime <= afterMomentCreationTime,
            'moment now() time should be now, not in the future'
        );
    });

    test('now - Date mocked', function (assert) {
        var RealDate = Date,
            customTimeMs = moment('2015-01-01T01:30:00.000Z').valueOf();

        function MockDate() {
            return new RealDate(customTimeMs);
        }

        MockDate.now = function () {
            return new MockDate().valueOf();
        };

        MockDate.prototype = RealDate.prototype;

        // eslint-disable-next-line
        Date = MockDate;

        try {
            assert.equal(
                moment().valueOf(),
                customTimeMs,
                'moment now() time should use the global Date object'
            );
        } finally {
            // eslint-disable-next-line
            Date = RealDate;
        }
    });

    test('now - custom value', function (assert) {
        var customTimeStr = '2015-01-01T01:30:00.000Z',
            customTime = moment(customTimeStr, moment.ISO_8601).valueOf(),
            oldFn = moment.now;

        moment.now = function () {
            return customTime;
        };

        try {
            assert.equal(
                moment().toISOString(),
                customTimeStr,
                'moment() constructor should use the function defined by moment.now, but it did not'
            );
            assert.equal(
                moment.utc().toISOString(),
                customTimeStr,
                'moment() constructor should use the function defined by moment.now, but it did not'
            );
        } finally {
            moment.now = oldFn;
        }
    });

    test('empty object, empty array', function (assert) {
        function assertIsNow(gen, msg) {
            var before = +new Date(),
                mid = gen(),
                after = +new Date();
            assert.ok(before <= +mid && +mid <= after, 'should be now : ' + msg);
        }
        assertIsNow(function () {
            return moment();
        }, 'moment()');
        assertIsNow(function () {
            return moment([]);
        }, 'moment([])');
        assertIsNow(function () {
            return moment({});
        }, 'moment({})');
        assertIsNow(function () {
            return moment.utc();
        }, 'moment.utc()');
        assertIsNow(function () {
            return moment.utc([]);
        }, 'moment.utc([])');
        assertIsNow(function () {
            return moment.utc({});
        }, 'moment.utc({})');
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('parsing flags');

    function flags() {
        return moment.apply(null, arguments).parsingFlags();
    }

    test('overflow with array', function (assert) {
        //months
        assert.equal(flags([2010, 0]).overflow, -1, 'month 0 valid');
        assert.equal(flags([2010, 1]).overflow, -1, 'month 1 valid');
        assert.equal(flags([2010, -1]).overflow, 1, 'month -1 invalid');
        assert.equal(flags([2100, 12]).overflow, 1, 'month 12 invalid');

        //days
        assert.equal(flags([2010, 1, 16]).overflow, -1, 'date valid');
        assert.equal(flags([2010, 1, -1]).overflow, 2, 'date -1 invalid');
        assert.equal(flags([2010, 1, 0]).overflow, 2, 'date 0 invalid');
        assert.equal(flags([2010, 1, 32]).overflow, 2, 'date 32 invalid');
        assert.equal(flags([2012, 1, 29]).overflow, -1, 'date leap year valid');
        assert.equal(flags([2010, 1, 29]).overflow, 2, 'date leap year invalid');

        //hours
        assert.equal(flags([2010, 1, 1, 8]).overflow, -1, 'hour valid');
        assert.equal(flags([2010, 1, 1, 0]).overflow, -1, 'hour 0 valid');
        assert.equal(flags([2010, 1, 1, -1]).overflow, 3, 'hour -1 invalid');
        assert.equal(flags([2010, 1, 1, 25]).overflow, 3, 'hour 25 invalid');
        assert.equal(flags([2010, 1, 1, 24, 1]).overflow, 3, 'hour 24:01 invalid');

        //minutes
        assert.equal(flags([2010, 1, 1, 8, 15]).overflow, -1, 'minute valid');
        assert.equal(flags([2010, 1, 1, 8, 0]).overflow, -1, 'minute 0 valid');
        assert.equal(flags([2010, 1, 1, 8, -1]).overflow, 4, 'minute -1 invalid');
        assert.equal(flags([2010, 1, 1, 8, 60]).overflow, 4, 'minute 60 invalid');

        //seconds
        assert.equal(flags([2010, 1, 1, 8, 15, 12]).overflow, -1, 'second valid');
        assert.equal(flags([2010, 1, 1, 8, 15, 0]).overflow, -1, 'second 0 valid');
        assert.equal(
            flags([2010, 1, 1, 8, 15, -1]).overflow,
            5,
            'second -1 invalid'
        );
        assert.equal(
            flags([2010, 1, 1, 8, 15, 60]).overflow,
            5,
            'second 60 invalid'
        );

        //milliseconds
        assert.equal(
            flags([2010, 1, 1, 8, 15, 12, 345]).overflow,
            -1,
            'millisecond valid'
        );
        assert.equal(
            flags([2010, 1, 1, 8, 15, 12, 0]).overflow,
            -1,
            'millisecond 0 valid'
        );
        assert.equal(
            flags([2010, 1, 1, 8, 15, 12, -1]).overflow,
            6,
            'millisecond -1 invalid'
        );
        assert.equal(
            flags([2010, 1, 1, 8, 15, 12, 1000]).overflow,
            6,
            'millisecond 1000 invalid'
        );

        // 24 hrs
        assert.equal(
            flags([2010, 1, 1, 24, 0, 0, 0]).overflow,
            -1,
            '24:00:00.000 is fine'
        );
        assert.equal(
            flags([2010, 1, 1, 24, 1, 0, 0]).overflow,
            3,
            '24:01:00.000 is wrong hour'
        );
        assert.equal(
            flags([2010, 1, 1, 24, 0, 1, 0]).overflow,
            3,
            '24:00:01.000 is wrong hour'
        );
        assert.equal(
            flags([2010, 1, 1, 24, 0, 0, 1]).overflow,
            3,
            '24:00:00.001 is wrong hour'
        );
    });

    test('overflow without format', function (assert) {
        //months
        assert.equal(flags('2001-01', 'YYYY-MM').overflow, -1, 'month 1 valid');
        assert.equal(flags('2001-12', 'YYYY-MM').overflow, -1, 'month 12 valid');
        assert.equal(flags('2001-13', 'YYYY-MM').overflow, 1, 'month 13 invalid');

        //days
        assert.equal(
            flags('2010-01-16', 'YYYY-MM-DD').overflow,
            -1,
            'date 16 valid'
        );
        assert.equal(
            flags('2010-01-0', 'YYYY-MM-DD').overflow,
            2,
            'date 0 invalid'
        );
        assert.equal(
            flags('2010-01-32', 'YYYY-MM-DD').overflow,
            2,
            'date 32 invalid'
        );
        assert.equal(
            flags('2012-02-29', 'YYYY-MM-DD').overflow,
            -1,
            'date leap year valid'
        );
        assert.equal(
            flags('2010-02-29', 'YYYY-MM-DD').overflow,
            2,
            'date leap year invalid'
        );

        //days of the year
        assert.equal(
            flags('2010 300', 'YYYY DDDD').overflow,
            -1,
            'day 300 of year valid'
        );
        assert.equal(
            flags('2010 365', 'YYYY DDDD').overflow,
            -1,
            'day 365 of year valid'
        );
        assert.equal(
            flags('2010 366', 'YYYY DDDD').overflow,
            2,
            'day 366 of year invalid'
        );
        assert.equal(
            flags('2012 366', 'YYYY DDDD').overflow,
            -1,
            'day 366 of leap year valid'
        );
        assert.equal(
            flags('2012 367', 'YYYY DDDD').overflow,
            2,
            'day 367 of leap year invalid'
        );

        //hours
        assert.equal(flags('08', 'HH').overflow, -1, 'hour valid');
        assert.equal(flags('00', 'HH').overflow, -1, 'hour 0 valid');
        assert.equal(flags('25', 'HH').overflow, 3, 'hour 25 invalid');
        assert.equal(flags('24:01', 'HH:mm').overflow, 3, 'hour 24:01 invalid');

        //minutes
        assert.equal(flags('08:15', 'HH:mm').overflow, -1, 'minute valid');
        assert.equal(flags('08:00', 'HH:mm').overflow, -1, 'minute 0 valid');
        assert.equal(flags('08:60', 'HH:mm').overflow, 4, 'minute 60 invalid');

        //seconds
        assert.equal(flags('08:15:12', 'HH:mm:ss').overflow, -1, 'second valid');
        assert.equal(flags('08:15:00', 'HH:mm:ss').overflow, -1, 'second 0 valid');
        assert.equal(
            flags('08:15:60', 'HH:mm:ss').overflow,
            5,
            'second 60 invalid'
        );

        //milliseconds
        assert.equal(
            flags('08:15:12:345', 'HH:mm:ss:SSSS').overflow,
            -1,
            'millisecond valid'
        );
        assert.equal(
            flags('08:15:12:000', 'HH:mm:ss:SSSS').overflow,
            -1,
            'millisecond 0 valid'
        );

        //this is OK because we don't match the last digit, so it's 100 ms
        assert.equal(
            flags('08:15:12:1000', 'HH:mm:ss:SSSS').overflow,
            -1,
            'millisecond 1000 actually valid'
        );
    });

    test('extra tokens', function (assert) {
        assert.deepEqual(
            flags('1982-05-25', 'YYYY-MM-DD').unusedTokens,
            [],
            'nothing extra'
        );
        assert.deepEqual(
            flags('1982-05', 'YYYY-MM-DD').unusedTokens,
            ['DD'],
            'extra formatting token'
        );
        assert.deepEqual(
            flags('1982', 'YYYY-MM-DD').unusedTokens,
            ['MM', 'DD'],
            'multiple extra formatting tokens'
        );
        assert.deepEqual(
            flags('1982-05', 'YYYY-MM-').unusedTokens,
            [],
            'extra non-formatting token'
        );
        assert.deepEqual(
            flags('1982-05-', 'YYYY-MM-DD').unusedTokens,
            ['DD'],
            'non-extra non-formatting token'
        );
        assert.deepEqual(
            flags('1982 05 1982', 'YYYY-MM-DD').unusedTokens,
            [],
            'different non-formatting token'
        );
    });

    test('extra tokens strict', function (assert) {
        assert.deepEqual(
            flags('1982-05-25', 'YYYY-MM-DD', true).unusedTokens,
            [],
            'nothing extra'
        );
        assert.deepEqual(
            flags('1982-05', 'YYYY-MM-DD', true).unusedTokens,
            ['-', 'DD'],
            'extra formatting token'
        );
        assert.deepEqual(
            flags('1982', 'YYYY-MM-DD', true).unusedTokens,
            ['-', 'MM', '-', 'DD'],
            'multiple extra formatting tokens'
        );
        assert.deepEqual(
            flags('1982-05', 'YYYY-MM-', true).unusedTokens,
            ['-'],
            'extra non-formatting token'
        );
        assert.deepEqual(
            flags('1982-05-', 'YYYY-MM-DD', true).unusedTokens,
            ['DD'],
            'non-extra non-formatting token'
        );
        assert.deepEqual(
            flags('1982 05 1982', 'YYYY-MM-DD', true).unusedTokens,
            ['-', '-'],
            'different non-formatting token'
        );
    });

    test('unused input', function (assert) {
        assert.deepEqual(
            flags('1982-05-25', 'YYYY-MM-DD').unusedInput,
            [],
            'normal input'
        );
        assert.deepEqual(
            flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').unusedInput,
            [' this is more stuff'],
            'trailing nonsense'
        );
        assert.deepEqual(
            flags('1982-05-25 09:30', 'YYYY-MM-DD').unusedInput,
            [' 09:30'],
            ['trailing legit-looking input']
        );
        assert.deepEqual(
            flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]').unusedInput,
            [],
            'junk that actually gets matched'
        );
        assert.deepEqual(
            flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').unusedInput,
            ['stuff at beginning '],
            'leading junk'
        );
        assert.deepEqual(
            flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD')
                .unusedInput,
            ['junk ', ' more junk ', ' yet more junk'],
            'interstitial junk'
        );
    });

    test('unused input strict', function (assert) {
        assert.deepEqual(
            flags('1982-05-25', 'YYYY-MM-DD', true).unusedInput,
            [],
            'normal input'
        );
        assert.deepEqual(
            flags('1982-05-25 this is more stuff', 'YYYY-MM-DD', true).unusedInput,
            [' this is more stuff'],
            'trailing nonsense'
        );
        assert.deepEqual(
            flags('1982-05-25 09:30', 'YYYY-MM-DD', true).unusedInput,
            [' 09:30'],
            ['trailing legit-looking input']
        );
        assert.deepEqual(
            flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]', true)
                .unusedInput,
            [],
            'junk that actually gets matched'
        );
        assert.deepEqual(
            flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD', true).unusedInput,
            ['stuff at beginning '],
            'leading junk'
        );
        assert.deepEqual(
            flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD', true)
                .unusedInput,
            ['junk ', ' more junk ', ' yet more junk'],
            'interstitial junk'
        );
    });

    test('chars left over', function (assert) {
        assert.equal(
            flags('1982-05-25', 'YYYY-MM-DD').charsLeftOver,
            0,
            'normal input'
        );
        assert.equal(
            flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').charsLeftOver,
            ' this is more stuff'.length,
            'trailing nonsense'
        );
        assert.equal(
            flags('1982-05-25 09:30', 'YYYY-MM-DD').charsLeftOver,
            ' 09:30'.length,
            'trailing legit-looking input'
        );
        assert.equal(
            flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').charsLeftOver,
            'stuff at beginning '.length,
            'leading junk'
        );
        assert.equal(
            flags('1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver,
            [' junk ', ' more junk'].join('').length,
            'interstitial junk'
        );
        assert.equal(
            flags('stuff at beginning 1982 junk 05 more junk25', 'YYYY-MM-DD')
                .charsLeftOver,
            ['stuff at beginning ', ' junk ', ' more junk'].join('').length,
            'leading and interstitial junk'
        );
    });

    test('empty', function (assert) {
        assert.equal(
            flags('1982-05-25', 'YYYY-MM-DD').empty,
            false,
            'normal input'
        );
        assert.equal(
            flags('nothing here', 'YYYY-MM-DD').empty,
            true,
            'pure garbage'
        );
        assert.equal(
            flags('junk but has the number 2000 in it', 'YYYY-MM-DD').empty,
            false,
            'only mostly garbage'
        );
        assert.equal(flags('', 'YYYY-MM-DD').empty, true, 'empty string');
        assert.equal(flags('', 'YYYY-MM-DD').empty, true, 'blank string');
    });

    test('null', function (assert) {
        assert.equal(
            flags('1982-05-25', 'YYYY-MM-DD').nullInput,
            false,
            'normal input'
        );
        assert.equal(flags(null).nullInput, true, 'just null');
        assert.equal(flags(null, 'YYYY-MM-DD').nullInput, true, 'null with format');
    });

    test('invalid month', function (assert) {
        assert.equal(
            flags('1982 May', 'YYYY MMMM').invalidMonth,
            null,
            'normal input'
        );
        assert.equal(
            flags('1982 Laser', 'YYYY MMMM').invalidMonth,
            'Laser',
            'bad month name'
        );
    });

    test('empty format array', function (assert) {
        assert.equal(
            flags('1982 May', ['YYYY MMM']).invalidFormat,
            false,
            'empty format array'
        );
        assert.equal(
            flags('1982 May', []).invalidFormat,
            true,
            'empty format array'
        );
    });

    test('weekday mismatch', function (assert) {
        // string with format
        assert.equal(
            flags('Wed 08-10-2017', 'ddd MM-DD-YYYY').weekdayMismatch,
            true,
            'day of week does not match date'
        );
        assert.equal(
            flags('Thu 08-10-2017', 'ddd MM-DD-YYYY').weekdayMismatch,
            false,
            'day of week matches date'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    var symbolMap = {
            1: '!',
            2: '@',
            3: '#',
            4: '$',
            5: '%',
            6: '^',
            7: '&',
            8: '*',
            9: '(',
            0: ')',
        },
        numberMap = {
            '!': '1',
            '@': '2',
            '#': '3',
            $: '4',
            '%': '5',
            '^': '6',
            '&': '7',
            '*': '8',
            '(': '9',
            ')': '0',
        };

    module('preparse and postformat', {
        setup: function () {
            moment.locale('symbol', {
                preparse: function (string) {
                    return string.replace(/[!@#$%\^&*()]/g, function (match) {
                        return numberMap[match];
                    });
                },

                postformat: function (string) {
                    return string.replace(/\d/g, function (match) {
                        return symbolMap[match];
                    });
                },
            });
        },
        teardown: function () {
            moment.defineLocale('symbol', null);
        },
    });

    test('transform', function (assert) {
        assert.equal(
            moment.utc('@)!@-)*-@&', 'YYYY-MM-DD').unix(),
            1346025600,
            'preparse string + format'
        );
        assert.equal(
            moment.utc('@)!@-)*-@&').unix(),
            1346025600,
            'preparse ISO8601 string'
        );
        assert.equal(
            moment.unix(1346025600).utc().format('YYYY-MM-DD'),
            '@)!@-)*-@&',
            'postformat'
        );
    });

    test('transform from', function (assert) {
        var start = moment([2007, 1, 28]);

        assert.equal(
            start.from(moment([2007, 1, 28]).add({ s: 90 }), true),
            '@ minutes',
            'postformat should work on moment.fn.from'
        );
        assert.equal(
            moment().add(6, 'd').fromNow(true),
            '^ days',
            'postformat should work on moment.fn.fromNow'
        );
        assert.equal(
            moment.duration(10, 'h').humanize(),
            '!) hours',
            'postformat should work on moment.duration.fn.humanize'
        );
    });

    test('calendar day', function (assert) {
        var a = moment().hours(12).minutes(0).seconds(0);

        assert.equal(
            moment(a).calendar(),
            'Today at !@:)) PM',
            'today at the same time'
        );
        assert.equal(
            moment(a).add({ m: 25 }).calendar(),
            'Today at !@:@% PM',
            'Now plus 25 min'
        );
        assert.equal(
            moment(a).add({ h: 1 }).calendar(),
            'Today at !:)) PM',
            'Now plus 1 hour'
        );
        assert.equal(
            moment(a).add({ d: 1 }).calendar(),
            'Tomorrow at !@:)) PM',
            'tomorrow at the same time'
        );
        assert.equal(
            moment(a).subtract({ h: 1 }).calendar(),
            'Today at !!:)) AM',
            'Now minus 1 hour'
        );
        assert.equal(
            moment(a).subtract({ d: 1 }).calendar(),
            'Yesterday at !@:)) PM',
            'yesterday at the same time'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('quarter');

    test('library quarter getter', function (assert) {
        assert.equal(moment([1985, 1, 4]).quarter(), 1, 'Feb  4 1985 is Q1');
        assert.equal(moment([2029, 8, 18]).quarter(), 3, 'Sep 18 2029 is Q3');
        assert.equal(moment([2013, 3, 24]).quarter(), 2, 'Apr 24 2013 is Q2');
        assert.equal(moment([2015, 2, 5]).quarter(), 1, 'Mar  5 2015 is Q1');
        assert.equal(moment([1970, 0, 2]).quarter(), 1, 'Jan  2 1970 is Q1');
        assert.equal(moment([2001, 11, 12]).quarter(), 4, 'Dec 12 2001 is Q4');
        assert.equal(moment([2000, 0, 2]).quarter(), 1, 'Jan  2 2000 is Q1');
    });

    test('quarter setter singular', function (assert) {
        var m = moment([2014, 4, 11]);
        assert.equal(m.quarter(2).month(), 4, 'set same quarter');
        assert.equal(m.quarter(3).month(), 7, 'set 3rd quarter');
        assert.equal(m.quarter(1).month(), 1, 'set 1st quarter');
        assert.equal(m.quarter(4).month(), 10, 'set 4th quarter');
    });

    test('quarter setter plural', function (assert) {
        var m = moment([2014, 4, 11]);
        assert.equal(m.quarters(2).month(), 4, 'set same quarter');
        assert.equal(m.quarters(3).month(), 7, 'set 3rd quarter');
        assert.equal(m.quarters(1).month(), 1, 'set 1st quarter');
        assert.equal(m.quarters(4).month(), 10, 'set 4th quarter');
    });

    test('quarter setter programmatic', function (assert) {
        var m = moment([2014, 4, 11]);
        assert.equal(m.set('quarter', 2).month(), 4, 'set same quarter');
        assert.equal(m.set('quarter', 3).month(), 7, 'set 3rd quarter');
        assert.equal(m.set('quarter', 1).month(), 1, 'set 1st quarter');
        assert.equal(m.set('quarter', 4).month(), 10, 'set 4th quarter');
    });

    test('quarter setter programmatic plural', function (assert) {
        var m = moment([2014, 4, 11]);
        assert.equal(m.set('quarters', 2).month(), 4, 'set same quarter');
        assert.equal(m.set('quarters', 3).month(), 7, 'set 3rd quarter');
        assert.equal(m.set('quarters', 1).month(), 1, 'set 1st quarter');
        assert.equal(m.set('quarters', 4).month(), 10, 'set 4th quarter');
    });

    test('quarter setter programmatic abbr', function (assert) {
        var m = moment([2014, 4, 11]);
        assert.equal(m.set('Q', 2).month(), 4, 'set same quarter');
        assert.equal(m.set('Q', 3).month(), 7, 'set 3rd quarter');
        assert.equal(m.set('Q', 1).month(), 1, 'set 1st quarter');
        assert.equal(m.set('Q', 4).month(), 10, 'set 4th quarter');
    });

    test('quarter setter only month changes', function (assert) {
        var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(4);
        assert.equal(m.year(), 2014, 'keep year');
        assert.equal(m.month(), 10, 'set month');
        assert.equal(m.date(), 11, 'keep date');
        assert.equal(m.hour(), 1, 'keep hour');
        assert.equal(m.minute(), 2, 'keep minutes');
        assert.equal(m.second(), 3, 'keep seconds');
        assert.equal(m.millisecond(), 4, 'keep milliseconds');
    });

    test('quarter setter bubble to next year', function (assert) {
        var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(7);
        assert.equal(m.year(), 2015, 'year bubbled');
        assert.equal(m.month(), 7, 'set month');
        assert.equal(m.date(), 11, 'keep date');
        assert.equal(m.hour(), 1, 'keep hour');
        assert.equal(m.minute(), 2, 'keep minutes');
        assert.equal(m.second(), 3, 'keep seconds');
        assert.equal(m.millisecond(), 4, 'keep milliseconds');
    });

    test('quarter diff', function (assert) {
        assert.equal(
            moment('2014-01-01').diff(moment('2014-04-01'), 'quarter'),
            -1,
            'diff -1 quarter'
        );
        assert.equal(
            moment('2014-04-01').diff(moment('2014-01-01'), 'quarter'),
            1,
            'diff 1 quarter'
        );
        assert.equal(
            moment('2014-05-01').diff(moment('2014-01-01'), 'quarter'),
            1,
            'diff 1 quarter'
        );
        assert.ok(
            Math.abs(
                4 / 3 -
                    moment('2014-05-01').diff(moment('2014-01-01'), 'quarter', true)
            ) < 0.00001,
            'diff 1 1/3 quarter'
        );
        assert.equal(
            moment('2015-01-01').diff(moment('2014-01-01'), 'quarter'),
            4,
            'diff 4 quarters'
        );
    });

    test('quarter setter bubble to previous year', function (assert) {
        var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(-3);
        assert.equal(m.year(), 2013, 'year bubbled');
        assert.equal(m.month(), 1, 'set month');
        assert.equal(m.date(), 11, 'keep date');
        assert.equal(m.hour(), 1, 'keep hour');
        assert.equal(m.minute(), 2, 'keep minutes');
        assert.equal(m.second(), 3, 'keep seconds');
        assert.equal(m.millisecond(), 4, 'keep milliseconds');
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('relative time');

    test('default thresholds fromNow', function (assert) {
        var a = moment();

        // Seconds to minutes threshold
        a.subtract(44, 'seconds');
        assert.equal(
            a.fromNow(),
            'a few seconds ago',
            'Below default seconds to minutes threshold'
        );
        a.subtract(1, 'seconds');
        assert.equal(
            a.fromNow(),
            'a minute ago',
            'Above default seconds to minutes threshold'
        );

        // Minutes to hours threshold
        a = moment();
        a.subtract(44, 'minutes');
        assert.equal(
            a.fromNow(),
            '44 minutes ago',
            'Below default minute to hour threshold'
        );
        a.subtract(1, 'minutes');
        assert.equal(
            a.fromNow(),
            'an hour ago',
            'Above default minute to hour threshold'
        );

        // Hours to days threshold
        a = moment();
        a.subtract(21, 'hours');
        assert.equal(
            a.fromNow(),
            '21 hours ago',
            'Below default hours to day threshold'
        );
        a.subtract(1, 'hours');
        assert.equal(
            a.fromNow(),
            'a day ago',
            'Above default hours to day threshold'
        );

        // Days to month threshold
        a = moment();
        a.subtract(25, 'days');
        assert.equal(
            a.fromNow(),
            '25 days ago',
            'Below default days to month (singular) threshold'
        );
        a.subtract(1, 'days');
        assert.equal(
            a.fromNow(),
            'a month ago',
            'Above default days to month (singular) threshold'
        );

        // months to year threshold
        a = moment();
        a.subtract(10, 'months');
        assert.equal(
            a.fromNow(),
            '10 months ago',
            'Below default days to years threshold'
        );
        a.subtract(1, 'month');
        assert.equal(
            a.fromNow(),
            'a year ago',
            'Above default days to years threshold'
        );
    });

    test('default thresholds toNow', function (assert) {
        var a = moment();

        // Seconds to minutes threshold
        a.subtract(44, 'seconds');
        assert.equal(
            a.toNow(),
            'in a few seconds',
            'Below default seconds to minutes threshold'
        );
        a.subtract(1, 'seconds');
        assert.equal(
            a.toNow(),
            'in a minute',
            'Above default seconds to minutes threshold'
        );

        // Minutes to hours threshold
        a = moment();
        a.subtract(44, 'minutes');
        assert.equal(
            a.toNow(),
            'in 44 minutes',
            'Below default minute to hour threshold'
        );
        a.subtract(1, 'minutes');
        assert.equal(
            a.toNow(),
            'in an hour',
            'Above default minute to hour threshold'
        );

        // Hours to days threshold
        a = moment();
        a.subtract(21, 'hours');
        assert.equal(
            a.toNow(),
            'in 21 hours',
            'Below default hours to day threshold'
        );
        a.subtract(1, 'hours');
        assert.equal(a.toNow(), 'in a day', 'Above default hours to day threshold');

        // Days to month threshold
        a = moment();
        a.subtract(25, 'days');
        assert.equal(
            a.toNow(),
            'in 25 days',
            'Below default days to month (singular) threshold'
        );
        a.subtract(1, 'days');
        assert.equal(
            a.toNow(),
            'in a month',
            'Above default days to month (singular) threshold'
        );

        // months to year threshold
        a = moment();
        a.subtract(10, 'months');
        assert.equal(
            a.toNow(),
            'in 10 months',
            'Below default days to years threshold'
        );
        a.subtract(1, 'month');
        assert.equal(
            a.toNow(),
            'in a year',
            'Above default days to years threshold'
        );
    });

    test('custom thresholds', function (assert) {
        var a, dd;

        // including weeks
        moment.relativeTimeThreshold('w', 4);
        dd = moment.relativeTimeThreshold('d');
        moment.relativeTimeThreshold('d', 7);
        // threshold for days to weeks with including weeks
        a = moment();
        a.subtract(6, 'days');
        assert.equal(a.fromNow(), '6 days ago', 'Below threshold days for weeks');
        a.subtract(1, 'days');
        assert.equal(a.fromNow(), 'a week ago', 'Above threshold days for weeks');

        // threshold for days to weeks with including weeks
        a = moment();
        a.subtract(3, 'weeks');
        assert.equal(
            a.fromNow(),
            '3 weeks ago',
            'Below threshold weeks for months'
        );
        a.subtract(1, 'week');
        assert.equal(
            a.fromNow(),
            'a month ago',
            'Above threshold weeks for months'
        );
        // moment.relativeTimeIncludeWeeks(false);
        moment.relativeTimeThreshold('w', null);
        moment.relativeTimeThreshold('d', dd);
        // Seconds to minute threshold, under 30
        moment.relativeTimeThreshold('s', 25);

        a = moment();
        a.subtract(24, 'seconds');
        assert.equal(
            a.fromNow(),
            'a few seconds ago',
            'Below custom seconds to minute threshold, s < 30'
        );
        a.subtract(1, 'seconds');
        assert.equal(
            a.fromNow(),
            'a minute ago',
            'Above custom seconds to minute threshold, s < 30'
        );

        // Seconds to minutes threshold
        moment.relativeTimeThreshold('s', 55);

        a = moment();
        a.subtract(54, 'seconds');
        assert.equal(
            a.fromNow(),
            'a few seconds ago',
            'Below custom seconds to minutes threshold'
        );
        a.subtract(1, 'seconds');
        assert.equal(
            a.fromNow(),
            'a minute ago',
            'Above custom seconds to minutes threshold'
        );

        moment.relativeTimeThreshold('s', 45);

        // A few seconds to seconds threshold
        moment.relativeTimeThreshold('ss', 3);

        a = moment();
        a.subtract(3, 'seconds');
        assert.equal(
            a.fromNow(),
            'a few seconds ago',
            'Below custom a few seconds to seconds threshold'
        );
        a.subtract(1, 'seconds');
        assert.equal(
            a.fromNow(),
            '4 seconds ago',
            'Above custom a few seconds to seconds threshold'
        );

        moment.relativeTimeThreshold('ss', 44);

        // Minutes to hours threshold
        moment.relativeTimeThreshold('m', 55);
        a = moment();
        a.subtract(54, 'minutes');
        assert.equal(
            a.fromNow(),
            '54 minutes ago',
            'Below custom minutes to hours threshold'
        );
        a.subtract(1, 'minutes');
        assert.equal(
            a.fromNow(),
            'an hour ago',
            'Above custom minutes to hours threshold'
        );
        moment.relativeTimeThreshold('m', 45);

        // Hours to days threshold
        moment.relativeTimeThreshold('h', 24);
        a = moment();
        a.subtract(23, 'hours');
        assert.equal(
            a.fromNow(),
            '23 hours ago',
            'Below custom hours to days threshold'
        );
        a.subtract(1, 'hours');
        assert.equal(
            a.fromNow(),
            'a day ago',
            'Above custom hours to days threshold'
        );
        moment.relativeTimeThreshold('h', 22);

        // Days to month threshold
        moment.relativeTimeThreshold('d', 28);
        a = moment();
        a.subtract(27, 'days');
        assert.equal(
            a.fromNow(),
            '27 days ago',
            'Below custom days to month (singular) threshold'
        );
        a.subtract(1, 'days');
        assert.equal(
            a.fromNow(),
            'a month ago',
            'Above custom days to month (singular) threshold'
        );
        moment.relativeTimeThreshold('d', 26);

        // months to years threshold
        moment.relativeTimeThreshold('M', 9);
        a = moment();
        a.subtract(8, 'months');
        assert.equal(
            a.fromNow(),
            '8 months ago',
            'Below custom days to years threshold'
        );
        a.subtract(1, 'months');
        assert.equal(
            a.fromNow(),
            'a year ago',
            'Above custom days to years threshold'
        );
        moment.relativeTimeThreshold('M', 11);

        // multiple thresholds
        moment.relativeTimeThreshold('ss', 3);
        a = moment();
        a.subtract(4, 'seconds');
        assert.equal(
            a.fromNow(),
            '4 seconds ago',
            'Before setting s relative time threshold'
        );
        moment.relativeTimeThreshold('s', 59);
        assert.equal(
            a.fromNow(),
            'a few seconds ago',
            'After setting s relative time threshold'
        );
        moment.relativeTimeThreshold('ss', 44);
        moment.relativeTimeThreshold('s', 45);
    });

    test('custom rounding', function (assert) {
        var roundingDefault = moment.relativeTimeRounding(),
            a,
            retainValue;

        // Round relative time evaluation down
        moment.relativeTimeRounding(Math.floor);

        moment.relativeTimeThreshold('s', 60);
        moment.relativeTimeThreshold('m', 60);
        moment.relativeTimeThreshold('h', 24);
        moment.relativeTimeThreshold('d', 27);
        moment.relativeTimeThreshold('M', 12);

        a = moment.utc();
        a.subtract({ minutes: 59, seconds: 59 });
        assert.equal(
            a.toNow(),
            'in 59 minutes',
            'Round down towards the nearest minute'
        );

        a = moment.utc();
        a.subtract({ hours: 23, minutes: 59, seconds: 59 });
        assert.equal(
            a.toNow(),
            'in 23 hours',
            'Round down towards the nearest hour'
        );

        a = moment.utc();
        a.subtract({ days: 26, hours: 23, minutes: 59 });
        assert.equal(
            a.toNow(),
            'in 26 days',
            'Round down towards the nearest day (just under)'
        );

        a = moment.utc();
        a.subtract({ days: 27 });
        assert.equal(
            a.toNow(),
            'in a month',
            'Round down towards the nearest day (just over)'
        );

        a = moment.utc();
        a.subtract({ days: 364 });
        assert.equal(
            a.toNow(),
            'in 11 months',
            'Round down towards the nearest month'
        );

        a = moment.utc();
        a.subtract({ years: 1, days: 364 });
        assert.equal(a.toNow(), 'in a year', 'Round down towards the nearest year');

        // Do not round relative time evaluation
        retainValue = function (value) {
            return value.toFixed(3);
        };
        moment.relativeTimeRounding(retainValue);

        a = moment.utc();
        a.subtract({ hours: 39 });
        assert.equal(
            a.toNow(),
            'in 1.625 days',
            'Round down towards the nearest year'
        );

        // Restore defaults
        moment.relativeTimeThreshold('s', 45);
        moment.relativeTimeThreshold('m', 45);
        moment.relativeTimeThreshold('h', 22);
        moment.relativeTimeThreshold('d', 26);
        moment.relativeTimeThreshold('M', 11);
        moment.relativeTimeRounding(roundingDefault);
    });

    test('retrieve rounding settings', function (assert) {
        moment.relativeTimeRounding(Math.round);
        var roundingFunction = moment.relativeTimeRounding();

        assert.equal(roundingFunction, Math.round, 'Can retrieve rounding setting');
    });

    test('retrieve threshold settings', function (assert) {
        moment.relativeTimeThreshold('m', 45);
        var minuteThreshold = moment.relativeTimeThreshold('m');

        assert.equal(minuteThreshold, 45, 'Can retrieve minute setting');
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('start and end of units');

    test('start of year', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('year'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('years'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('y');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 0, 'strip out the month');
        assert.equal(m.date(), 1, 'strip out the day');
        assert.equal(m.hours(), 0, 'strip out the hours');
        assert.equal(m.minutes(), 0, 'strip out the minutes');
        assert.equal(m.seconds(), 0, 'strip out the seconds');
        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');
    });

    test('end of year', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('year'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('years'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('y');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 11, 'set the month');
        assert.equal(m.date(), 31, 'set the day');
        assert.equal(m.hours(), 23, 'set the hours');
        assert.equal(m.minutes(), 59, 'set the minutes');
        assert.equal(m.seconds(), 59, 'set the seconds');
        assert.equal(m.milliseconds(), 999, 'set the seconds');
    });

    test('start of quarter', function (assert) {
        var m = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('quarter'),
            ms = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('quarters'),
            ma = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('Q');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.quarter(), 2, 'keep the quarter');
        assert.equal(m.month(), 3, 'strip out the month');
        assert.equal(m.date(), 1, 'strip out the day');
        assert.equal(m.hours(), 0, 'strip out the hours');
        assert.equal(m.minutes(), 0, 'strip out the minutes');
        assert.equal(m.seconds(), 0, 'strip out the seconds');
        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');
    });

    test('end of quarter', function (assert) {
        var m = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('quarter'),
            ms = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('quarters'),
            ma = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('Q');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.quarter(), 2, 'keep the quarter');
        assert.equal(m.month(), 5, 'set the month');
        assert.equal(m.date(), 30, 'set the day');
        assert.equal(m.hours(), 23, 'set the hours');
        assert.equal(m.minutes(), 59, 'set the minutes');
        assert.equal(m.seconds(), 59, 'set the seconds');
        assert.equal(m.milliseconds(), 999, 'set the seconds');
    });

    test('start of month', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('month'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('months'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('M');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.date(), 1, 'strip out the day');
        assert.equal(m.hours(), 0, 'strip out the hours');
        assert.equal(m.minutes(), 0, 'strip out the minutes');
        assert.equal(m.seconds(), 0, 'strip out the seconds');
        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');
    });

    test('end of month', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('month'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('months'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('M');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.date(), 28, 'set the day');
        assert.equal(m.hours(), 23, 'set the hours');
        assert.equal(m.minutes(), 59, 'set the minutes');
        assert.equal(m.seconds(), 59, 'set the seconds');
        assert.equal(m.milliseconds(), 999, 'set the seconds');
    });

    test('start of week', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('week'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('weeks'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('w');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 0, 'rolls back to January');
        assert.equal(m.day(), 0, 'set day of week');
        assert.equal(m.date(), 30, 'set correct date');
        assert.equal(m.hours(), 0, 'strip out the hours');
        assert.equal(m.minutes(), 0, 'strip out the minutes');
        assert.equal(m.seconds(), 0, 'strip out the seconds');
        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');
    });

    test('end of week', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('week'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('weeks'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('weeks');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.day(), 6, 'set the day of the week');
        assert.equal(m.date(), 5, 'set the day');
        assert.equal(m.hours(), 23, 'set the hours');
        assert.equal(m.minutes(), 59, 'set the minutes');
        assert.equal(m.seconds(), 59, 'set the seconds');
        assert.equal(m.milliseconds(), 999, 'set the seconds');
    });

    test('start of iso-week', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('isoWeek'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('isoWeeks'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('W');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 0, 'rollback to January');
        assert.equal(m.isoWeekday(), 1, 'set day of iso-week');
        assert.equal(m.date(), 31, 'set correct date');
        assert.equal(m.hours(), 0, 'strip out the hours');
        assert.equal(m.minutes(), 0, 'strip out the minutes');
        assert.equal(m.seconds(), 0, 'strip out the seconds');
        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');
    });

    test('end of iso-week', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('isoWeek'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('isoWeeks'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('W');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.isoWeekday(), 7, 'set the day of the week');
        assert.equal(m.date(), 6, 'set the day');
        assert.equal(m.hours(), 23, 'set the hours');
        assert.equal(m.minutes(), 59, 'set the minutes');
        assert.equal(m.seconds(), 59, 'set the seconds');
        assert.equal(m.milliseconds(), 999, 'set the seconds');
    });

    test('start of day', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('day'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('days'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('d');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.date(), 2, 'keep the day');
        assert.equal(m.hours(), 0, 'strip out the hours');
        assert.equal(m.minutes(), 0, 'strip out the minutes');
        assert.equal(m.seconds(), 0, 'strip out the seconds');
        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');
    });

    test('end of day', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('day'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('days'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('d');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.date(), 2, 'keep the day');
        assert.equal(m.hours(), 23, 'set the hours');
        assert.equal(m.minutes(), 59, 'set the minutes');
        assert.equal(m.seconds(), 59, 'set the seconds');
        assert.equal(m.milliseconds(), 999, 'set the seconds');
    });

    test('start of date', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('date'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('dates');

        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.date(), 2, 'keep the day');
        assert.equal(m.hours(), 0, 'strip out the hours');
        assert.equal(m.minutes(), 0, 'strip out the minutes');
        assert.equal(m.seconds(), 0, 'strip out the seconds');
        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');
    });

    test('end of date', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('date'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('dates');

        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.date(), 2, 'keep the day');
        assert.equal(m.hours(), 23, 'set the hours');
        assert.equal(m.minutes(), 59, 'set the minutes');
        assert.equal(m.seconds(), 59, 'set the seconds');
        assert.equal(m.milliseconds(), 999, 'set the seconds');
    });

    test('start of hour', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hour'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hours'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('h');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.date(), 2, 'keep the day');
        assert.equal(m.hours(), 3, 'keep the hours');
        assert.equal(m.minutes(), 0, 'strip out the minutes');
        assert.equal(m.seconds(), 0, 'strip out the seconds');
        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');
    });

    test('end of hour', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hour'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hours'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('h');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.date(), 2, 'keep the day');
        assert.equal(m.hours(), 3, 'keep the hours');
        assert.equal(m.minutes(), 59, 'set the minutes');
        assert.equal(m.seconds(), 59, 'set the seconds');
        assert.equal(m.milliseconds(), 999, 'set the seconds');
    });

    test('start of minute', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minute'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minutes'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('m');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.date(), 2, 'keep the day');
        assert.equal(m.hours(), 3, 'keep the hours');
        assert.equal(m.minutes(), 4, 'keep the minutes');
        assert.equal(m.seconds(), 0, 'strip out the seconds');
        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');
    });

    test('end of minute', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minute'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minutes'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('m');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.date(), 2, 'keep the day');
        assert.equal(m.hours(), 3, 'keep the hours');
        assert.equal(m.minutes(), 4, 'keep the minutes');
        assert.equal(m.seconds(), 59, 'set the seconds');
        assert.equal(m.milliseconds(), 999, 'set the seconds');
    });

    test('start of second', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('second'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('seconds'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('s');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.date(), 2, 'keep the day');
        assert.equal(m.hours(), 3, 'keep the hours');
        assert.equal(m.minutes(), 4, 'keep the minutes');
        assert.equal(m.seconds(), 5, 'keep the seconds');
        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');
    });

    test('end of second', function (assert) {
        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('second'),
            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('seconds'),
            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('s');
        assert.equal(+m, +ms, 'Plural or singular should work');
        assert.equal(+m, +ma, 'Full or abbreviated should work');
        assert.equal(m.year(), 2011, 'keep the year');
        assert.equal(m.month(), 1, 'keep the month');
        assert.equal(m.date(), 2, 'keep the day');
        assert.equal(m.hours(), 3, 'keep the hours');
        assert.equal(m.minutes(), 4, 'keep the minutes');
        assert.equal(m.seconds(), 5, 'keep the seconds');
        assert.equal(m.milliseconds(), 999, 'set the seconds');
    });

    test('startOf across DST +1', function (assert) {
        var oldUpdateOffset = moment.updateOffset,
            // Based on a real story somewhere in America/Los_Angeles
            dstAt = moment('2014-03-09T02:00:00-08:00').parseZone(),
            m;

        moment.updateOffset = function (mom, keepTime) {
            if (mom.isBefore(dstAt)) {
                mom.utcOffset(-8, keepTime);
            } else {
                mom.utcOffset(-7, keepTime);
            }
        };

        m = moment('2014-03-15T00:00:00-07:00').parseZone();
        m.startOf('y');
        assert.equal(
            m.format(),
            '2014-01-01T00:00:00-08:00',
            "startOf('year') across +1"
        );

        m = moment('2014-03-15T00:00:00-07:00').parseZone();
        m.startOf('M');
        assert.equal(
            m.format(),
            '2014-03-01T00:00:00-08:00',
            "startOf('month') across +1"
        );

        m = moment('2014-03-09T09:00:00-07:00').parseZone();
        m.startOf('d');
        assert.equal(
            m.format(),
            '2014-03-09T00:00:00-08:00',
            "startOf('day') across +1"
        );

        m = moment('2014-03-09T03:05:00-07:00').parseZone();
        m.startOf('h');
        assert.equal(
            m.format(),
            '2014-03-09T03:00:00-07:00',
            "startOf('hour') after +1"
        );

        m = moment('2014-03-09T01:35:00-08:00').parseZone();
        m.startOf('h');
        assert.equal(
            m.format(),
            '2014-03-09T01:00:00-08:00',
            "startOf('hour') before +1"
        );

        // There is no such time as 2:30-7 to try startOf('hour') across that

        moment.updateOffset = oldUpdateOffset;
    });

    test('startOf across DST -1', function (assert) {
        var oldUpdateOffset = moment.updateOffset,
            // Based on a real story somewhere in America/Los_Angeles
            dstAt = moment('2014-11-02T02:00:00-07:00').parseZone(),
            m;

        moment.updateOffset = function (mom, keepTime) {
            if (mom.isBefore(dstAt)) {
                mom.utcOffset(-7, keepTime);
            } else {
                mom.utcOffset(-8, keepTime);
            }
        };

        m = moment('2014-11-15T00:00:00-08:00').parseZone();
        m.startOf('y');
        assert.equal(
            m.format(),
            '2014-01-01T00:00:00-07:00',
            "startOf('year') across -1"
        );

        m = moment('2014-11-15T00:00:00-08:00').parseZone();
        m.startOf('M');
        assert.equal(
            m.format(),
            '2014-11-01T00:00:00-07:00',
            "startOf('month') across -1"
        );

        m = moment('2014-11-02T09:00:00-08:00').parseZone();
        m.startOf('d');
        assert.equal(
            m.format(),
            '2014-11-02T00:00:00-07:00',
            "startOf('day') across -1"
        );

        // note that utc offset is -8
        m = moment('2014-11-02T01:30:00-08:00').parseZone();
        m.startOf('h');
        assert.equal(
            m.format(),
            '2014-11-02T01:00:00-08:00',
            "startOf('hour') after +1"
        );

        // note that utc offset is -7
        m = moment('2014-11-02T01:30:00-07:00').parseZone();
        m.startOf('h');
        assert.equal(
            m.format(),
            '2014-11-02T01:00:00-07:00',
            "startOf('hour') before +1"
        );

        moment.updateOffset = oldUpdateOffset;
    });

    test('endOf millisecond and no-arg', function (assert) {
        var m = moment();
        assert.equal(
            +m,
            +m.clone().endOf(),
            'endOf without argument should change time'
        );
        assert.equal(
            +m,
            +m.clone().endOf('ms'),
            'endOf with ms argument should change time'
        );
        assert.equal(
            +m,
            +m.clone().endOf('millisecond'),
            'endOf with millisecond argument should change time'
        );
        assert.equal(
            +m,
            +m.clone().endOf('milliseconds'),
            'endOf with milliseconds argument should change time'
        );
    });

    test('startOf for year zero', function (assert) {
        var m = moment('0000-02-29T12:34:56.789Z').parseZone();
        assert.equal(
            m.clone().startOf('ms').toISOString(),
            '0000-02-29T12:34:56.789Z',
            'startOf millisecond should preserve year'
        );
        assert.equal(
            m.clone().startOf('s').toISOString(),
            '0000-02-29T12:34:56.000Z',
            'startOf second should preserve year'
        );
        assert.equal(
            m.clone().startOf('m').toISOString(),
            '0000-02-29T12:34:00.000Z',
            'startOf minute should preserve year'
        );
        assert.equal(
            m.clone().startOf('h').toISOString(),
            '0000-02-29T12:00:00.000Z',
            'startOf hour should preserve year'
        );
        assert.equal(
            m.clone().startOf('d').toISOString(),
            '0000-02-29T00:00:00.000Z',
            'startOf day should preserve year'
        );
        assert.equal(
            m.clone().startOf('M').toISOString(),
            '0000-02-01T00:00:00.000Z',
            'startOf month should preserve year'
        );
        assert.equal(
            m.clone().startOf('Q').toISOString(),
            '0000-01-01T00:00:00.000Z',
            'startOf quarter should preserve year'
        );
        assert.equal(
            m.clone().startOf('y').toISOString(),
            '0000-01-01T00:00:00.000Z',
            'startOf year should preserve year'
        );
    });

    test('endOf for year zero', function (assert) {
        var m = moment('0000-02-29T12:34:56.789Z').parseZone();
        assert.equal(
            m.clone().endOf('ms').toISOString(),
            '0000-02-29T12:34:56.789Z',
            'endOf millisecond should preserve year'
        );
        assert.equal(
            m.clone().endOf('s').toISOString(),
            '0000-02-29T12:34:56.999Z',
            'endOf second should preserve year'
        );
        assert.equal(
            m.clone().endOf('m').toISOString(),
            '0000-02-29T12:34:59.999Z',
            'endOf minute should preserve year'
        );
        assert.equal(
            m.clone().endOf('h').toISOString(),
            '0000-02-29T12:59:59.999Z',
            'endOf hour should preserve year'
        );
        assert.equal(
            m.clone().endOf('d').toISOString(),
            '0000-02-29T23:59:59.999Z',
            'endOf day should preserve year'
        );
        assert.equal(
            m.clone().endOf('M').toISOString(),
            '0000-02-29T23:59:59.999Z',
            'endOf month should preserve year'
        );
        assert.equal(
            m.clone().endOf('Q').toISOString(),
            '0000-03-31T23:59:59.999Z',
            'endOf quarter should preserve year'
        );
        assert.equal(
            m.clone().endOf('y').toISOString(),
            '0000-12-31T23:59:59.999Z',
            'endOf year should preserve year'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('string prototype');

    test('string prototype overrides call', function (assert) {
        var prior = String.prototype.call,
            b;
        String.prototype.call = function () {
            return null;
        };

        b = moment(new Date(2011, 7, 28, 15, 25, 50, 125));
        assert.equal(b.format('MMMM Do YYYY, h:mm a'), 'August 28th 2011, 3:25 pm');

        String.prototype.call = prior;
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('to type');

    test('toObject', function (assert) {
        var expected = {
            years: 2010,
            months: 3,
            date: 5,
            hours: 15,
            minutes: 10,
            seconds: 3,
            milliseconds: 123,
        };
        assert.deepEqual(moment(expected).toObject(), expected, 'toObject invalid');
    });

    test('toArray', function (assert) {
        var expected = [2014, 11, 26, 11, 46, 58, 17];
        assert.deepEqual(moment(expected).toArray(), expected, 'toArray invalid');
    });

    test('toDate returns a copy of the internal date', function (assert) {
        var m = moment(),
            d = m.toDate();
        m.year(0);
        assert.notEqual(d, m.toDate());
    });

    test('toJSON', function (assert) {
        if (Date.prototype.toISOString) {
            var expected = new Date().toISOString();
            assert.deepEqual(moment(expected).toJSON(), expected, 'toJSON invalid');
        } else {
            // IE8
            assert.expect(0);
        }
    });

    test('toJSON works when moment is frozen', function (assert) {
        if (Date.prototype.toISOString) {
            var expected = new Date().toISOString(),
                m = moment(expected);
            if (Object.freeze != null) {
                Object.freeze(m);
            }
            assert.deepEqual(m.toJSON(), expected, 'toJSON when frozen invalid');
        } else {
            // IE8
            assert.expect(0);
        }
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('utc offset');

    test('setter / getter blackbox', function (assert) {
        var m = moment([2010]);

        assert.equal(m.clone().utcOffset(0).utcOffset(), 0, 'utcOffset 0');

        assert.equal(m.clone().utcOffset(1).utcOffset(), 60, 'utcOffset 1 is 60');
        assert.equal(m.clone().utcOffset(60).utcOffset(), 60, 'utcOffset 60');
        assert.equal(
            m.clone().utcOffset('+01:00').utcOffset(),
            60,
            'utcOffset +01:00 is 60'
        );
        assert.equal(
            m.clone().utcOffset('+0100').utcOffset(),
            60,
            'utcOffset +0100 is 60'
        );

        assert.equal(
            m.clone().utcOffset(-1).utcOffset(),
            -60,
            'utcOffset -1 is -60'
        );
        assert.equal(m.clone().utcOffset(-60).utcOffset(), -60, 'utcOffset -60');
        assert.equal(
            m.clone().utcOffset('-01:00').utcOffset(),
            -60,
            'utcOffset -01:00 is -60'
        );
        assert.equal(
            m.clone().utcOffset('-0100').utcOffset(),
            -60,
            'utcOffset -0100 is -60'
        );

        assert.equal(
            m.clone().utcOffset(1.5).utcOffset(),
            90,
            'utcOffset 1.5 is 90'
        );
        assert.equal(
            m.clone().utcOffset(90).utcOffset(),
            90,
            'utcOffset 1.5 is 90'
        );
        assert.equal(
            m.clone().utcOffset('+01:30').utcOffset(),
            90,
            'utcOffset +01:30 is 90'
        );
        assert.equal(
            m.clone().utcOffset('+0130').utcOffset(),
            90,
            'utcOffset +0130 is 90'
        );

        assert.equal(m.clone().utcOffset(-1.5).utcOffset(), -90, 'utcOffset -1.5');
        assert.equal(m.clone().utcOffset(-90).utcOffset(), -90, 'utcOffset -90');
        assert.equal(
            m.clone().utcOffset('-01:30').utcOffset(),
            -90,
            'utcOffset +01:30 is 90'
        );
        assert.equal(
            m.clone().utcOffset('-0130').utcOffset(),
            -90,
            'utcOffset +0130 is 90'
        );
        assert.equal(
            m.clone().utcOffset('+00:10').utcOffset(),
            10,
            'utcOffset +00:10 is 10'
        );
        assert.equal(
            m.clone().utcOffset('-00:10').utcOffset(),
            -10,
            'utcOffset +00:10 is 10'
        );
        assert.equal(
            m.clone().utcOffset('+0010').utcOffset(),
            10,
            'utcOffset +0010 is 10'
        );
        assert.equal(
            m.clone().utcOffset('-0010').utcOffset(),
            -10,
            'utcOffset +0010 is 10'
        );
    });

    test('utcOffset shorthand hours -> minutes', function (assert) {
        var i;
        for (i = -15; i <= 15; ++i) {
            assert.equal(
                moment().utcOffset(i).utcOffset(),
                i * 60,
                '' + i + ' -> ' + i * 60
            );
        }
        assert.equal(moment().utcOffset(-16).utcOffset(), -16, '-16 -> -16');
        assert.equal(moment().utcOffset(16).utcOffset(), 16, '16 -> 16');
    });

    test('isLocal, isUtc, isUtcOffset', function (assert) {
        assert.ok(moment().isLocal(), 'moment() creates objects in local time');
        assert.ok(
            !moment.utc().isLocal(),
            'moment.utc creates objects NOT in local time'
        );
        assert.ok(
            moment.utc().local().isLocal(),
            'moment.fn.local() converts to local time'
        );
        assert.ok(
            !moment().utcOffset(5).isLocal(),
            'moment.fn.utcOffset(N) puts objects NOT in local time'
        );
        assert.ok(
            moment().utcOffset(5).local().isLocal(),
            'moment.fn.local() converts to local time'
        );

        assert.ok(moment.utc().isUtc(), 'moment.utc() creates objects in utc time');
        assert.ok(
            moment().utcOffset(0).isUtc(),
            'utcOffset(0) is equivalent to utc mode'
        );
        assert.ok(
            !moment().utcOffset(1).isUtc(),
            'utcOffset(1) is NOT equivalent to utc mode'
        );

        assert.ok(
            !moment().isUtcOffset(),
            'moment() creates objects NOT in utc-offset mode'
        );
        assert.ok(
            moment.utc().isUtcOffset(),
            'moment.utc() creates objects in utc-offset mode'
        );
        assert.ok(
            moment().utcOffset(3).isUtcOffset(),
            'utcOffset(N != 0) creates objects in utc-offset mode'
        );
        assert.ok(
            moment().utcOffset(0).isUtcOffset(),
            'utcOffset(0) creates objects in utc-offset mode'
        );
    });

    test('isUTC', function (assert) {
        assert.ok(moment.utc().isUTC(), 'moment.utc() creates objects in utc time');
        assert.ok(
            moment().utcOffset(0).isUTC(),
            'utcOffset(0) is equivalent to utc mode'
        );
        assert.ok(
            !moment().utcOffset(1).isUTC(),
            'utcOffset(1) is NOT equivalent to utc mode'
        );
    });

    test('change hours when changing the utc offset', function (assert) {
        var m = moment.utc([2000, 0, 1, 6]);
        assert.equal(m.hour(), 6, 'UTC 6AM should be 6AM at +0000');

        // sanity check
        m.utcOffset(0);
        assert.equal(m.hour(), 6, 'UTC 6AM should be 6AM at +0000');

        m.utcOffset(-60);
        assert.equal(m.hour(), 5, 'UTC 6AM should be 5AM at -0100');

        m.utcOffset(60);
        assert.equal(m.hour(), 7, 'UTC 6AM should be 7AM at +0100');
    });

    test('change minutes when changing the utc offset', function (assert) {
        var m = moment.utc([2000, 0, 1, 6, 31]);

        m.utcOffset(0);
        assert.equal(
            m.format('HH:mm'),
            '06:31',
            'UTC 6:31AM should be 6:31AM at +0000'
        );

        m.utcOffset(-30);
        assert.equal(
            m.format('HH:mm'),
            '06:01',
            'UTC 6:31AM should be 6:01AM at -0030'
        );

        m.utcOffset(30);
        assert.equal(
            m.format('HH:mm'),
            '07:01',
            'UTC 6:31AM should be 7:01AM at +0030'
        );

        m.utcOffset(-1380);
        assert.equal(
            m.format('HH:mm'),
            '07:31',
            'UTC 6:31AM should be 7:31AM at +1380'
        );
    });

    test('distance from the unix epoch', function (assert) {
        var zoneA = moment(),
            zoneB = moment(zoneA),
            zoneC = moment(zoneA),
            zoneD = moment(zoneA),
            zoneE = moment(zoneA);

        zoneB.utc();
        assert.equal(+zoneA, +zoneB, 'moment should equal moment.utc');

        zoneC.utcOffset(60);
        assert.equal(+zoneA, +zoneC, 'moment should equal moment.utcOffset(60)');

        zoneD.utcOffset(-480);
        assert.equal(+zoneA, +zoneD, 'moment should equal moment.utcOffset(-480)');

        zoneE.utcOffset(-1000);
        assert.equal(+zoneA, +zoneE, 'moment should equal moment.utcOffset(-1000)');
    });

    test('update offset after changing any values', function (assert) {
        var oldOffset = moment.updateOffset,
            m = moment.utc([2000, 6, 1]);

        moment.updateOffset = function (mom, keepTime) {
            if (mom.__doChange) {
                if (+mom > 962409600000) {
                    mom.utcOffset(-120, keepTime);
                } else {
                    mom.utcOffset(-60, keepTime);
                }
            }
        };

        assert.equal(m.format('ZZ'), '+0000', 'should be at +0000');
        assert.equal(
            m.format('HH:mm'),
            '00:00',
            'should start 12AM at +0000 timezone'
        );

        m.__doChange = true;
        m.add(1, 'h');

        assert.equal(m.format('ZZ'), '-0200', 'should be at -0200');
        assert.equal(
            m.format('HH:mm'),
            '23:00',
            '1AM at +0000 should be 11PM at -0200 timezone'
        );

        m.subtract(1, 'h');

        assert.equal(m.format('ZZ'), '-0100', 'should be at -0100');
        assert.equal(
            m.format('HH:mm'),
            '23:00',
            '12AM at +0000 should be 11PM at -0100 timezone'
        );

        moment.updateOffset = oldOffset;
    });

    //////////////////
    test('getters and setters', function (assert) {
        var a = moment([2011, 5, 20]);

        assert.equal(
            a.clone().utcOffset(-120).year(2012).year(),
            2012,
            'should get and set year correctly'
        );
        assert.equal(
            a.clone().utcOffset(-120).month(1).month(),
            1,
            'should get and set month correctly'
        );
        assert.equal(
            a.clone().utcOffset(-120).date(2).date(),
            2,
            'should get and set date correctly'
        );
        assert.equal(
            a.clone().utcOffset(-120).day(1).day(),
            1,
            'should get and set day correctly'
        );
        assert.equal(
            a.clone().utcOffset(-120).hour(1).hour(),
            1,
            'should get and set hour correctly'
        );
        assert.equal(
            a.clone().utcOffset(-120).minute(1).minute(),
            1,
            'should get and set minute correctly'
        );
    });

    test('getters', function (assert) {
        var a = moment.utc([2012, 0, 1, 0, 0, 0]);

        assert.equal(
            a.clone().utcOffset(-120).year(),
            2011,
            'should get year correctly'
        );
        assert.equal(
            a.clone().utcOffset(-120).month(),
            11,
            'should get month correctly'
        );
        assert.equal(
            a.clone().utcOffset(-120).date(),
            31,
            'should get date correctly'
        );
        assert.equal(
            a.clone().utcOffset(-120).hour(),
            22,
            'should get hour correctly'
        );
        assert.equal(
            a.clone().utcOffset(-120).minute(),
            0,
            'should get minute correctly'
        );

        assert.equal(
            a.clone().utcOffset(120).year(),
            2012,
            'should get year correctly'
        );
        assert.equal(
            a.clone().utcOffset(120).month(),
            0,
            'should get month correctly'
        );
        assert.equal(
            a.clone().utcOffset(120).date(),
            1,
            'should get date correctly'
        );
        assert.equal(
            a.clone().utcOffset(120).hour(),
            2,
            'should get hour correctly'
        );
        assert.equal(
            a.clone().utcOffset(120).minute(),
            0,
            'should get minute correctly'
        );

        assert.equal(
            a.clone().utcOffset(90).year(),
            2012,
            'should get year correctly'
        );
        assert.equal(
            a.clone().utcOffset(90).month(),
            0,
            'should get month correctly'
        );
        assert.equal(
            a.clone().utcOffset(90).date(),
            1,
            'should get date correctly'
        );
        assert.equal(
            a.clone().utcOffset(90).hour(),
            1,
            'should get hour correctly'
        );
        assert.equal(
            a.clone().utcOffset(90).minute(),
            30,
            'should get minute correctly'
        );
    });

    test('from', function (assert) {
        var zoneA = moment(),
            zoneB = moment(zoneA).utcOffset(-720),
            zoneC = moment(zoneA).utcOffset(-360),
            zoneD = moment(zoneA).utcOffset(690),
            other = moment(zoneA).add(35, 'm');

        assert.equal(
            zoneA.from(other),
            zoneB.from(other),
            'moment#from should be the same in all zones'
        );
        assert.equal(
            zoneA.from(other),
            zoneC.from(other),
            'moment#from should be the same in all zones'
        );
        assert.equal(
            zoneA.from(other),
            zoneD.from(other),
            'moment#from should be the same in all zones'
        );
    });

    test('diff', function (assert) {
        var zoneA = moment(),
            zoneB = moment(zoneA).utcOffset(-720),
            zoneC = moment(zoneA).utcOffset(-360),
            zoneD = moment(zoneA).utcOffset(690),
            other = moment(zoneA).add(35, 'm');

        assert.equal(
            zoneA.diff(other),
            zoneB.diff(other),
            'moment#diff should be the same in all zones'
        );
        assert.equal(
            zoneA.diff(other),
            zoneC.diff(other),
            'moment#diff should be the same in all zones'
        );
        assert.equal(
            zoneA.diff(other),
            zoneD.diff(other),
            'moment#diff should be the same in all zones'
        );

        assert.equal(
            zoneA.diff(other, 'minute', true),
            zoneB.diff(other, 'minute', true),
            'moment#diff should be the same in all zones'
        );
        assert.equal(
            zoneA.diff(other, 'minute', true),
            zoneC.diff(other, 'minute', true),
            'moment#diff should be the same in all zones'
        );
        assert.equal(
            zoneA.diff(other, 'minute', true),
            zoneD.diff(other, 'minute', true),
            'moment#diff should be the same in all zones'
        );

        assert.equal(
            zoneA.diff(other, 'hour', true),
            zoneB.diff(other, 'hour', true),
            'moment#diff should be the same in all zones'
        );
        assert.equal(
            zoneA.diff(other, 'hour', true),
            zoneC.diff(other, 'hour', true),
            'moment#diff should be the same in all zones'
        );
        assert.equal(
            zoneA.diff(other, 'hour', true),
            zoneD.diff(other, 'hour', true),
            'moment#diff should be the same in all zones'
        );
    });

    test('unix offset and timestamp', function (assert) {
        var zoneA = moment(),
            zoneB = moment(zoneA).utcOffset(-720),
            zoneC = moment(zoneA).utcOffset(-360),
            zoneD = moment(zoneA).utcOffset(690);

        assert.equal(
            zoneA.unix(),
            zoneB.unix(),
            'moment#unix should be the same in all zones'
        );
        assert.equal(
            zoneA.unix(),
            zoneC.unix(),
            'moment#unix should be the same in all zones'
        );
        assert.equal(
            zoneA.unix(),
            zoneD.unix(),
            'moment#unix should be the same in all zones'
        );

        assert.equal(
            +zoneA,
            +zoneB,
            'moment#valueOf should be the same in all zones'
        );
        assert.equal(
            +zoneA,
            +zoneC,
            'moment#valueOf should be the same in all zones'
        );
        assert.equal(
            +zoneA,
            +zoneD,
            'moment#valueOf should be the same in all zones'
        );
    });

    test('cloning', function (assert) {
        assert.equal(
            moment().utcOffset(-120).clone().utcOffset(),
            -120,
            'explicit cloning should retain the offset'
        );
        assert.equal(
            moment().utcOffset(120).clone().utcOffset(),
            120,
            'explicit cloning should retain the offset'
        );
        assert.equal(
            moment(moment().utcOffset(-120)).utcOffset(),
            -120,
            'implicit cloning should retain the offset'
        );
        assert.equal(
            moment(moment().utcOffset(120)).utcOffset(),
            120,
            'implicit cloning should retain the offset'
        );
    });

    test('start of / end of', function (assert) {
        var a = moment.utc([2010, 1, 2, 0, 0, 0]).utcOffset(-450);

        assert.equal(
            a.clone().startOf('day').hour(),
            0,
            'start of day should work on moments with utc offset'
        );
        assert.equal(
            a.clone().startOf('day').minute(),
            0,
            'start of day should work on moments with utc offset'
        );
        assert.equal(
            a.clone().startOf('hour').minute(),
            0,
            'start of hour should work on moments with utc offset'
        );

        assert.equal(
            a.clone().endOf('day').hour(),
            23,
            'end of day should work on moments with utc offset'
        );
        assert.equal(
            a.clone().endOf('day').minute(),
            59,
            'end of day should work on moments with utc offset'
        );
        assert.equal(
            a.clone().endOf('hour').minute(),
            59,
            'end of hour should work on moments with utc offset'
        );
    });

    test('reset offset with moment#utc', function (assert) {
        var a = moment.utc([2012]).utcOffset(-480);

        assert.equal(
            a.clone().hour(),
            16,
            'different utc offset should have different hour'
        );
        assert.equal(
            a.clone().utc().hour(),
            0,
            'calling moment#utc should reset the offset'
        );
    });

    test('reset offset with moment#local', function (assert) {
        var a = moment([2012]).utcOffset(-480);

        assert.equal(
            a.clone().local().hour(),
            0,
            'calling moment#local should reset the offset'
        );
    });

    test('toDate', function (assert) {
        var zoneA = new Date(),
            zoneB = moment(zoneA).utcOffset(-720).toDate(),
            zoneC = moment(zoneA).utcOffset(-360).toDate(),
            zoneD = moment(zoneA).utcOffset(690).toDate();

        assert.equal(
            +zoneA,
            +zoneB,
            'moment#toDate should output a date with the right unix timestamp'
        );
        assert.equal(
            +zoneA,
            +zoneC,
            'moment#toDate should output a date with the right unix timestamp'
        );
        assert.equal(
            +zoneA,
            +zoneD,
            'moment#toDate should output a date with the right unix timestamp'
        );
    });

    test('same / before / after', function (assert) {
        var zoneA = moment().utc(),
            zoneB = moment(zoneA).utcOffset(-120),
            zoneC = moment(zoneA).utcOffset(120);

        assert.ok(
            zoneA.isSame(zoneB),
            'two moments with different offsets should be the same'
        );
        assert.ok(
            zoneA.isSame(zoneC),
            'two moments with different offsets should be the same'
        );

        assert.ok(
            zoneA.isSame(zoneB, 'hour'),
            'two moments with different offsets should be the same hour'
        );
        assert.ok(
            zoneA.isSame(zoneC, 'hour'),
            'two moments with different offsets should be the same hour'
        );

        zoneA.add(1, 'hour');

        assert.ok(
            zoneA.isAfter(zoneB),
            'isAfter should work with two moments with different offsets'
        );
        assert.ok(
            zoneA.isAfter(zoneC),
            'isAfter should work with two moments with different offsets'
        );

        assert.ok(
            zoneA.isAfter(zoneB, 'hour'),
            'isAfter:hour should work with two moments with different offsets'
        );
        assert.ok(
            zoneA.isAfter(zoneC, 'hour'),
            'isAfter:hour should work with two moments with different offsets'
        );

        zoneA.subtract(2, 'hour');

        assert.ok(
            zoneA.isBefore(zoneB),
            'isBefore should work with two moments with different offsets'
        );
        assert.ok(
            zoneA.isBefore(zoneC),
            'isBefore should work with two moments with different offsets'
        );

        assert.ok(
            zoneA.isBefore(zoneB, 'hour'),
            'isBefore:hour should work with two moments with different offsets'
        );
        assert.ok(
            zoneA.isBefore(zoneC, 'hour'),
            'isBefore:hour should work with two moments with different offsets'
        );
    });

    test('add / subtract over dst', function (assert) {
        var oldOffset = moment.updateOffset,
            m = moment.utc([2000, 2, 31, 3]);

        moment.updateOffset = function (mom, keepTime) {
            if (mom.clone().utc().month() > 2) {
                mom.utcOffset(60, keepTime);
            } else {
                mom.utcOffset(0, keepTime);
            }
        };

        assert.equal(m.hour(), 3, 'should start at 00:00');

        m.add(24, 'hour');

        assert.equal(m.hour(), 4, 'adding 24 hours should disregard dst');

        m.subtract(24, 'hour');

        assert.equal(m.hour(), 3, 'subtracting 24 hours should disregard dst');

        m.add(1, 'day');

        assert.equal(m.hour(), 3, 'adding 1 day should have the same hour');

        m.subtract(1, 'day');

        assert.equal(m.hour(), 3, 'subtracting 1 day should have the same hour');

        m.add(1, 'month');

        assert.equal(m.hour(), 3, 'adding 1 month should have the same hour');

        m.subtract(1, 'month');

        assert.equal(m.hour(), 3, 'subtracting 1 month should have the same hour');

        moment.updateOffset = oldOffset;
    });

    test('isDST', function (assert) {
        var oldOffset = moment.updateOffset;

        moment.updateOffset = function (mom, keepTime) {
            if (mom.month() > 2 && mom.month() < 9) {
                mom.utcOffset(60, keepTime);
            } else {
                mom.utcOffset(0, keepTime);
            }
        };

        assert.ok(!moment().month(0).isDST(), 'Jan should not be summer dst');
        assert.ok(moment().month(6).isDST(), 'Jul should be summer dst');
        assert.ok(!moment().month(11).isDST(), 'Dec should not be summer dst');

        moment.updateOffset = function (mom) {
            if (mom.month() > 2 && mom.month() < 9) {
                mom.utcOffset(0);
            } else {
                mom.utcOffset(60);
            }
        };

        assert.ok(moment().month(0).isDST(), 'Jan should be winter dst');
        assert.ok(!moment().month(6).isDST(), 'Jul should not be winter dst');
        assert.ok(moment().month(11).isDST(), 'Dec should be winter dst');

        moment.updateOffset = oldOffset;
    });

    test('zone names', function (assert) {
        assert.equal(moment().zoneAbbr(), '', 'Local zone abbr should be empty');
        assert.equal(
            moment().format('z'),
            '',
            'Local zone formatted abbr should be empty'
        );
        assert.equal(moment().zoneName(), '', 'Local zone name should be empty');
        assert.equal(
            moment().format('zz'),
            '',
            'Local zone formatted name should be empty'
        );

        assert.equal(moment.utc().zoneAbbr(), 'UTC', 'UTC zone abbr should be UTC');
        assert.equal(
            moment.utc().format('z'),
            'UTC',
            'UTC zone formatted abbr should be UTC'
        );
        assert.equal(
            moment.utc().zoneName(),
            'Coordinated Universal Time',
            'UTC zone abbr should be Coordinated Universal Time'
        );
        assert.equal(
            moment.utc().format('zz'),
            'Coordinated Universal Time',
            'UTC zone formatted abbr should be Coordinated Universal Time'
        );
    });

    test('hours alignment with UTC', function (assert) {
        assert.equal(moment().utcOffset(-120).hasAlignedHourOffset(), true);
        assert.equal(moment().utcOffset(180).hasAlignedHourOffset(), true);
        assert.equal(moment().utcOffset(-90).hasAlignedHourOffset(), false);
        assert.equal(moment().utcOffset(90).hasAlignedHourOffset(), false);
    });

    test('hours alignment with other zone', function (assert) {
        var m = moment().utcOffset(-120);

        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), true);
        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), true);
        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-90)), false);
        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(90)), false);

        m = moment().utcOffset(-90);

        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), false);
        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), false);
        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-30)), true);
        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(30)), true);

        m = moment().utcOffset(60);

        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), true);
        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), true);
        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-90)), false);
        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(90)), false);

        m = moment().utcOffset(-25);

        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(35)), true);
        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-85)), true);

        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-35)), false);
        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(85)), false);
    });

    test('parse zone', function (assert) {
        var m = moment('2013-01-01T00:00:00-13:00').parseZone();
        assert.equal(m.utcOffset(), -13 * 60);
        assert.equal(m.hours(), 0);
    });

    test('parse UTC zone', function (assert) {
        var m = moment('2013-01-01T05:00:00+00:00').parseZone();
        assert.equal(m.utcOffset(), 0);
        assert.equal(m.hours(), 5);
    });

    test('parse zone static', function (assert) {
        var m = moment.parseZone('2013-01-01T00:00:00-13:00');
        assert.equal(m.utcOffset(), -13 * 60);
        assert.equal(m.hours(), 0);
    });

    test('parse zone with more arguments', function (assert) {
        var m;
        m = moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ');
        assert.equal(
            m.format(),
            '2013-01-01T05:00:00-13:00',
            'accept input and format'
        );
        m = moment.parseZone('2013-01-01-13:00', 'YYYY MM DD ZZ', true);
        assert.equal(m.isValid(), false, 'accept input, format and strict flag');
        m = moment.parseZone('2013-01-01-13:00', [
            'DD MM YYYY ZZ',
            'YYYY MM DD ZZ',
        ]);
        assert.equal(
            m.format(),
            '2013-01-01T00:00:00-13:00',
            'accept input and array of formats'
        );
    });

    test('parse zone with a timezone from the format string', function (assert) {
        var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY ZZ #####').parseZone();

        assert.equal(m.utcOffset(), -4 * 60);
    });

    test('parse zone without a timezone included in the format string', function (assert) {
        var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY').parseZone();

        assert.equal(m.utcOffset(), 11 * 60);
    });

    test('timezone format', function (assert) {
        assert.equal(moment().utcOffset(60).format('ZZ'), '+0100', '-60 -> +0100');
        assert.equal(moment().utcOffset(90).format('ZZ'), '+0130', '-90 -> +0130');
        assert.equal(
            moment().utcOffset(120).format('ZZ'),
            '+0200',
            '-120 -> +0200'
        );

        assert.equal(moment().utcOffset(-60).format('ZZ'), '-0100', '+60 -> -0100');
        assert.equal(moment().utcOffset(-90).format('ZZ'), '-0130', '+90 -> -0130');
        assert.equal(
            moment().utcOffset(-120).format('ZZ'),
            '-0200',
            '+120 -> -0200'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('utc');

    test('utc and local', function (assert) {
        var m = moment(Date.UTC(2011, 1, 2, 3, 4, 5, 6)),
            offset,
            expected;
        m.utc();
        // utc
        assert.equal(m.date(), 2, 'the day should be correct for utc');
        assert.equal(m.day(), 3, 'the date should be correct for utc');
        assert.equal(m.hours(), 3, 'the hours should be correct for utc');

        // local
        m.local();
        if (m.utcOffset() < -180) {
            assert.equal(m.date(), 1, 'the date should be correct for local');
            assert.equal(m.day(), 2, 'the day should be correct for local');
        } else {
            assert.equal(m.date(), 2, 'the date should be correct for local');
            assert.equal(m.day(), 3, 'the day should be correct for local');
        }
        offset = Math.floor(m.utcOffset() / 60);
        expected = (24 + 3 + offset) % 24;
        assert.equal(
            m.hours(),
            expected,
            'the hours (' + m.hours() + ') should be correct for local'
        );
        assert.equal(
            moment().utc().utcOffset(),
            0,
            'timezone in utc should always be zero'
        );
    });

    test('creating with utc and no arguments', function (assert) {
        var startOfTest = new Date().valueOf(),
            momentDefaultUtcTime = moment.utc().valueOf(),
            afterMomentCreationTime = new Date().valueOf();

        assert.ok(
            startOfTest <= momentDefaultUtcTime,
            'moment UTC default time should be now, not in the past'
        );
        assert.ok(
            momentDefaultUtcTime <= afterMomentCreationTime,
            'moment UTC default time should be now, not in the future'
        );
    });

    test('creating with utc and a date parameter array', function (assert) {
        var m = moment.utc([2011, 1, 2, 3, 4, 5, 6]);
        assert.equal(m.date(), 2, 'the day should be correct for utc array');
        assert.equal(m.hours(), 3, 'the hours should be correct for utc array');

        m = moment.utc('2011-02-02 3:04:05', 'YYYY-MM-DD HH:mm:ss');
        assert.equal(
            m.date(),
            2,
            'the day should be correct for utc parsing format'
        );
        assert.equal(
            m.hours(),
            3,
            'the hours should be correct for utc parsing format'
        );

        m = moment.utc('2011-02-02T03:04:05+00:00');
        assert.equal(m.date(), 2, 'the day should be correct for utc parsing iso');
        assert.equal(
            m.hours(),
            3,
            'the hours should be correct for utc parsing iso'
        );
    });

    test('creating with utc without timezone', function (assert) {
        var m = moment.utc('2012-01-02T08:20:00');
        assert.equal(
            m.date(),
            2,
            'the day should be correct for utc parse without timezone'
        );
        assert.equal(
            m.hours(),
            8,
            'the hours should be correct for utc parse without timezone'
        );

        m = moment.utc('2012-01-02T08:20:00+09:00');
        assert.equal(
            m.date(),
            1,
            'the day should be correct for utc parse with timezone'
        );
        assert.equal(
            m.hours(),
            23,
            'the hours should be correct for utc parse with timezone'
        );
    });

    test('cloning with utc offset', function (assert) {
        var m = moment.utc('2012-01-02T08:20:00');
        assert.equal(
            moment.utc(m)._isUTC,
            true,
            'the local offset should be converted to UTC'
        );
        assert.equal(
            moment.utc(m.clone().utc())._isUTC,
            true,
            'the local offset should stay in UTC'
        );

        m.utcOffset(120);
        assert.equal(
            moment.utc(m)._isUTC,
            true,
            'the explicit utc offset should stay in UTC'
        );
        assert.equal(
            moment.utc(m).utcOffset(),
            0,
            'the explicit utc offset should have an offset of 0'
        );
    });

    test('weekday with utc', function (assert) {
        assert.equal(
            moment('2013-09-15T00:00:00Z').utc().weekday(), // first minute of the day
            moment('2013-09-15T23:59:00Z').utc().weekday(), // last minute of the day
            "a UTC-moment's .weekday() should not be affected by the local timezone"
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('week year');

    test('iso week year', function (assert) {
        // Some examples taken from https://en.wikipedia.org/wiki/ISO_week
        assert.equal(moment([2005, 0, 1]).isoWeekYear(), 2004);
        assert.equal(moment([2005, 0, 2]).isoWeekYear(), 2004);
        assert.equal(moment([2005, 0, 3]).isoWeekYear(), 2005);
        assert.equal(moment([2005, 11, 31]).isoWeekYear(), 2005);
        assert.equal(moment([2006, 0, 1]).isoWeekYear(), 2005);
        assert.equal(moment([2006, 0, 2]).isoWeekYear(), 2006);
        assert.equal(moment([2007, 0, 1]).isoWeekYear(), 2007);
        assert.equal(moment([2007, 11, 30]).isoWeekYear(), 2007);
        assert.equal(moment([2007, 11, 31]).isoWeekYear(), 2008);
        assert.equal(moment([2008, 0, 1]).isoWeekYear(), 2008);
        assert.equal(moment([2008, 11, 28]).isoWeekYear(), 2008);
        assert.equal(moment([2008, 11, 29]).isoWeekYear(), 2009);
        assert.equal(moment([2008, 11, 30]).isoWeekYear(), 2009);
        assert.equal(moment([2008, 11, 31]).isoWeekYear(), 2009);
        assert.equal(moment([2009, 0, 1]).isoWeekYear(), 2009);
        assert.equal(moment([2010, 0, 1]).isoWeekYear(), 2009);
        assert.equal(moment([2010, 0, 2]).isoWeekYear(), 2009);
        assert.equal(moment([2010, 0, 3]).isoWeekYear(), 2009);
        assert.equal(moment([2010, 0, 4]).isoWeekYear(), 2010);
    });

    test('week year', function (assert) {
        // Some examples taken from https://en.wikipedia.org/wiki/ISO_week
        moment.locale('dow: 1,doy: 4', { week: { dow: 1, doy: 4 } }); // like iso
        assert.equal(moment([2005, 0, 1]).weekYear(), 2004);
        assert.equal(moment([2005, 0, 2]).weekYear(), 2004);
        assert.equal(moment([2005, 0, 3]).weekYear(), 2005);
        assert.equal(moment([2005, 11, 31]).weekYear(), 2005);
        assert.equal(moment([2006, 0, 1]).weekYear(), 2005);
        assert.equal(moment([2006, 0, 2]).weekYear(), 2006);
        assert.equal(moment([2007, 0, 1]).weekYear(), 2007);
        assert.equal(moment([2007, 11, 30]).weekYear(), 2007);
        assert.equal(moment([2007, 11, 31]).weekYear(), 2008);
        assert.equal(moment([2008, 0, 1]).weekYear(), 2008);
        assert.equal(moment([2008, 11, 28]).weekYear(), 2008);
        assert.equal(moment([2008, 11, 29]).weekYear(), 2009);
        assert.equal(moment([2008, 11, 30]).weekYear(), 2009);
        assert.equal(moment([2008, 11, 31]).weekYear(), 2009);
        assert.equal(moment([2009, 0, 1]).weekYear(), 2009);
        assert.equal(moment([2010, 0, 1]).weekYear(), 2009);
        assert.equal(moment([2010, 0, 2]).weekYear(), 2009);
        assert.equal(moment([2010, 0, 3]).weekYear(), 2009);
        assert.equal(moment([2010, 0, 4]).weekYear(), 2010);

        moment.locale('dow: 1,doy: 7', { week: { dow: 1, doy: 7 } });
        assert.equal(moment([2004, 11, 26]).weekYear(), 2004);
        assert.equal(moment([2004, 11, 27]).weekYear(), 2005);
        assert.equal(moment([2005, 11, 25]).weekYear(), 2005);
        assert.equal(moment([2005, 11, 26]).weekYear(), 2006);
        assert.equal(moment([2006, 11, 31]).weekYear(), 2006);
        assert.equal(moment([2007, 0, 1]).weekYear(), 2007);
        assert.equal(moment([2007, 11, 30]).weekYear(), 2007);
        assert.equal(moment([2007, 11, 31]).weekYear(), 2008);
        assert.equal(moment([2008, 11, 28]).weekYear(), 2008);
        assert.equal(moment([2008, 11, 29]).weekYear(), 2009);
        assert.equal(moment([2009, 11, 27]).weekYear(), 2009);
        assert.equal(moment([2009, 11, 28]).weekYear(), 2010);
    });

    // Verifies that the week number, week day computation is correct for all dow, doy combinations
    test('week year roundtrip', function (assert) {
        var dow, doy, wd, m, localeName;
        for (dow = 0; dow < 7; ++dow) {
            for (doy = dow; doy < dow + 7; ++doy) {
                for (wd = 0; wd < 7; ++wd) {
                    localeName = 'dow: ' + dow + ', doy: ' + doy;
                    moment.locale(localeName, { week: { dow: dow, doy: doy } });
                    // We use the 10th week as the 1st one can spill to the previous year
                    m = moment('2015 10 ' + wd, 'gggg w d', true);
                    assert.equal(
                        m.format('gggg w d'),
                        '2015 10 ' + wd,
                        'dow: ' + dow + ' doy: ' + doy + ' wd: ' + wd
                    );
                    m = moment('2015 10 ' + wd, 'gggg w e', true);
                    assert.equal(
                        m.format('gggg w e'),
                        '2015 10 ' + wd,
                        'dow: ' + dow + ' doy: ' + doy + ' wd: ' + wd
                    );
                    moment.defineLocale(localeName, null);
                }
            }
        }
    });

    test('week numbers 2012/2013', function (assert) {
        moment.locale('dow: 6, doy: 12', { week: { dow: 6, doy: 12 } });
        assert.equal(
            52,
            moment('2012-12-28', 'YYYY-MM-DD').week(),
            '2012-12-28 is week 52'
        ); // 51 -- should be 52?
        assert.equal(
            1,
            moment('2012-12-29', 'YYYY-MM-DD').week(),
            '2012-12-29 is week 1'
        ); // 52 -- should be 1
        assert.equal(
            1,
            moment('2013-01-01', 'YYYY-MM-DD').week(),
            '2013-01-01 is week 1'
        ); // 52 -- should be 1
        assert.equal(
            2,
            moment('2013-01-08', 'YYYY-MM-DD').week(),
            '2013-01-08 is week 2'
        ); // 53 -- should be 2
        assert.equal(
            2,
            moment('2013-01-11', 'YYYY-MM-DD').week(),
            '2013-01-11 is week 2'
        ); // 53 -- should be 2
        assert.equal(
            3,
            moment('2013-01-12', 'YYYY-MM-DD').week(),
            '2013-01-12 is week 3'
        ); // 1 -- should be 3
        assert.equal(
            52,
            moment('2012-01-01', 'YYYY-MM-DD').weeksInYear(),
            'weeks in 2012 are 52'
        ); // 52
        moment.defineLocale('dow: 6, doy: 12', null);
    });

    test('weeks numbers dow:1 doy:4', function (assert) {
        moment.locale('dow: 1, doy: 4', { week: { dow: 1, doy: 4 } });
        assert.equal(
            moment([2012, 0, 1]).week(),
            52,
            'Jan  1 2012 should be week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).week(),
            1,
            'Jan  2 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).week(),
            1,
            'Jan  8 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).week(),
            2,
            'Jan  9 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).week(),
            2,
            'Jan 15 2012 should be week 2'
        );
        assert.equal(
            moment([2007, 0, 1]).week(),
            1,
            'Jan  1 2007 should be week 1'
        );
        assert.equal(
            moment([2007, 0, 7]).week(),
            1,
            'Jan  7 2007 should be week 1'
        );
        assert.equal(
            moment([2007, 0, 8]).week(),
            2,
            'Jan  8 2007 should be week 2'
        );
        assert.equal(
            moment([2007, 0, 14]).week(),
            2,
            'Jan 14 2007 should be week 2'
        );
        assert.equal(
            moment([2007, 0, 15]).week(),
            3,
            'Jan 15 2007 should be week 3'
        );
        assert.equal(
            moment([2007, 11, 31]).week(),
            1,
            'Dec 31 2007 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 1]).week(),
            1,
            'Jan  1 2008 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 6]).week(),
            1,
            'Jan  6 2008 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 7]).week(),
            2,
            'Jan  7 2008 should be week 2'
        );
        assert.equal(
            moment([2008, 0, 13]).week(),
            2,
            'Jan 13 2008 should be week 2'
        );
        assert.equal(
            moment([2008, 0, 14]).week(),
            3,
            'Jan 14 2008 should be week 3'
        );
        assert.equal(
            moment([2002, 11, 30]).week(),
            1,
            'Dec 30 2002 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 1]).week(),
            1,
            'Jan  1 2003 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 5]).week(),
            1,
            'Jan  5 2003 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 6]).week(),
            2,
            'Jan  6 2003 should be week 2'
        );
        assert.equal(
            moment([2003, 0, 12]).week(),
            2,
            'Jan 12 2003 should be week 2'
        );
        assert.equal(
            moment([2003, 0, 13]).week(),
            3,
            'Jan 13 2003 should be week 3'
        );
        assert.equal(
            moment([2008, 11, 29]).week(),
            1,
            'Dec 29 2008 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 1]).week(),
            1,
            'Jan  1 2009 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 4]).week(),
            1,
            'Jan  4 2009 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 5]).week(),
            2,
            'Jan  5 2009 should be week 2'
        );
        assert.equal(
            moment([2009, 0, 11]).week(),
            2,
            'Jan 11 2009 should be week 2'
        );
        assert.equal(
            moment([2009, 0, 13]).week(),
            3,
            'Jan 12 2009 should be week 3'
        );
        assert.equal(
            moment([2009, 11, 28]).week(),
            53,
            'Dec 28 2009 should be week 53'
        );
        assert.equal(
            moment([2010, 0, 1]).week(),
            53,
            'Jan  1 2010 should be week 53'
        );
        assert.equal(
            moment([2010, 0, 3]).week(),
            53,
            'Jan  3 2010 should be week 53'
        );
        assert.equal(
            moment([2010, 0, 4]).week(),
            1,
            'Jan  4 2010 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 10]).week(),
            1,
            'Jan 10 2010 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 11]).week(),
            2,
            'Jan 11 2010 should be week 2'
        );
        assert.equal(
            moment([2010, 11, 27]).week(),
            52,
            'Dec 27 2010 should be week 52'
        );
        assert.equal(
            moment([2011, 0, 1]).week(),
            52,
            'Jan  1 2011 should be week 52'
        );
        assert.equal(
            moment([2011, 0, 2]).week(),
            52,
            'Jan  2 2011 should be week 52'
        );
        assert.equal(
            moment([2011, 0, 3]).week(),
            1,
            'Jan  3 2011 should be week 1'
        );
        assert.equal(
            moment([2011, 0, 9]).week(),
            1,
            'Jan  9 2011 should be week 1'
        );
        assert.equal(
            moment([2011, 0, 10]).week(),
            2,
            'Jan 10 2011 should be week 2'
        );
        moment.defineLocale('dow: 1, doy: 4', null);
    });

    test('weeks numbers dow:6 doy:12', function (assert) {
        moment.locale('dow: 6, doy: 12', { week: { dow: 6, doy: 12 } });
        assert.equal(
            moment([2011, 11, 31]).week(),
            1,
            'Dec 31 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 6]).week(),
            1,
            'Jan  6 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).week(),
            2,
            'Jan  7 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 13]).week(),
            2,
            'Jan 13 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).week(),
            3,
            'Jan 14 2012 should be week 3'
        );
        assert.equal(
            moment([2006, 11, 30]).week(),
            1,
            'Dec 30 2006 should be week 1'
        );
        assert.equal(
            moment([2007, 0, 5]).week(),
            1,
            'Jan  5 2007 should be week 1'
        );
        assert.equal(
            moment([2007, 0, 6]).week(),
            2,
            'Jan  6 2007 should be week 2'
        );
        assert.equal(
            moment([2007, 0, 12]).week(),
            2,
            'Jan 12 2007 should be week 2'
        );
        assert.equal(
            moment([2007, 0, 13]).week(),
            3,
            'Jan 13 2007 should be week 3'
        );
        assert.equal(
            moment([2007, 11, 29]).week(),
            1,
            'Dec 29 2007 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 1]).week(),
            1,
            'Jan  1 2008 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 4]).week(),
            1,
            'Jan  4 2008 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 5]).week(),
            2,
            'Jan  5 2008 should be week 2'
        );
        assert.equal(
            moment([2008, 0, 11]).week(),
            2,
            'Jan 11 2008 should be week 2'
        );
        assert.equal(
            moment([2008, 0, 12]).week(),
            3,
            'Jan 12 2008 should be week 3'
        );
        assert.equal(
            moment([2002, 11, 28]).week(),
            1,
            'Dec 28 2002 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 1]).week(),
            1,
            'Jan  1 2003 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 3]).week(),
            1,
            'Jan  3 2003 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 4]).week(),
            2,
            'Jan  4 2003 should be week 2'
        );
        assert.equal(
            moment([2003, 0, 10]).week(),
            2,
            'Jan 10 2003 should be week 2'
        );
        assert.equal(
            moment([2003, 0, 11]).week(),
            3,
            'Jan 11 2003 should be week 3'
        );
        assert.equal(
            moment([2008, 11, 27]).week(),
            1,
            'Dec 27 2008 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 1]).week(),
            1,
            'Jan  1 2009 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 2]).week(),
            1,
            'Jan  2 2009 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 3]).week(),
            2,
            'Jan  3 2009 should be week 2'
        );
        assert.equal(
            moment([2009, 0, 9]).week(),
            2,
            'Jan  9 2009 should be week 2'
        );
        assert.equal(
            moment([2009, 0, 10]).week(),
            3,
            'Jan 10 2009 should be week 3'
        );
        assert.equal(
            moment([2009, 11, 26]).week(),
            1,
            'Dec 26 2009 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 1]).week(),
            1,
            'Jan  1 2010 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 2]).week(),
            2,
            'Jan  2 2010 should be week 2'
        );
        assert.equal(
            moment([2010, 0, 8]).week(),
            2,
            'Jan  8 2010 should be week 2'
        );
        assert.equal(
            moment([2010, 0, 9]).week(),
            3,
            'Jan  9 2010 should be week 3'
        );
        assert.equal(
            moment([2011, 0, 1]).week(),
            1,
            'Jan  1 2011 should be week 1'
        );
        assert.equal(
            moment([2011, 0, 7]).week(),
            1,
            'Jan  7 2011 should be week 1'
        );
        assert.equal(
            moment([2011, 0, 8]).week(),
            2,
            'Jan  8 2011 should be week 2'
        );
        assert.equal(
            moment([2011, 0, 14]).week(),
            2,
            'Jan 14 2011 should be week 2'
        );
        assert.equal(
            moment([2011, 0, 15]).week(),
            3,
            'Jan 15 2011 should be week 3'
        );
        moment.defineLocale('dow: 6, doy: 12', null);
    });

    test('weeks numbers dow:1 doy:7', function (assert) {
        moment.locale('dow: 1, doy: 7', { week: { dow: 1, doy: 7 } });
        assert.equal(
            moment([2011, 11, 26]).week(),
            1,
            'Dec 26 2011 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 1]).week(),
            1,
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 2]).week(),
            2,
            'Jan  2 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 8]).week(),
            2,
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 9]).week(),
            3,
            'Jan  9 2012 should be week 3'
        );
        assert.equal(
            moment([2007, 0, 1]).week(),
            1,
            'Jan  1 2007 should be week 1'
        );
        assert.equal(
            moment([2007, 0, 7]).week(),
            1,
            'Jan  7 2007 should be week 1'
        );
        assert.equal(
            moment([2007, 0, 8]).week(),
            2,
            'Jan  8 2007 should be week 2'
        );
        assert.equal(
            moment([2007, 0, 14]).week(),
            2,
            'Jan 14 2007 should be week 2'
        );
        assert.equal(
            moment([2007, 0, 15]).week(),
            3,
            'Jan 15 2007 should be week 3'
        );
        assert.equal(
            moment([2007, 11, 31]).week(),
            1,
            'Dec 31 2007 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 1]).week(),
            1,
            'Jan  1 2008 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 6]).week(),
            1,
            'Jan  6 2008 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 7]).week(),
            2,
            'Jan  7 2008 should be week 2'
        );
        assert.equal(
            moment([2008, 0, 13]).week(),
            2,
            'Jan 13 2008 should be week 2'
        );
        assert.equal(
            moment([2008, 0, 14]).week(),
            3,
            'Jan 14 2008 should be week 3'
        );
        assert.equal(
            moment([2002, 11, 30]).week(),
            1,
            'Dec 30 2002 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 1]).week(),
            1,
            'Jan  1 2003 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 5]).week(),
            1,
            'Jan  5 2003 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 6]).week(),
            2,
            'Jan  6 2003 should be week 2'
        );
        assert.equal(
            moment([2003, 0, 12]).week(),
            2,
            'Jan 12 2003 should be week 2'
        );
        assert.equal(
            moment([2003, 0, 13]).week(),
            3,
            'Jan 13 2003 should be week 3'
        );
        assert.equal(
            moment([2008, 11, 29]).week(),
            1,
            'Dec 29 2008 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 1]).week(),
            1,
            'Jan  1 2009 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 4]).week(),
            1,
            'Jan  4 2009 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 5]).week(),
            2,
            'Jan  5 2009 should be week 2'
        );
        assert.equal(
            moment([2009, 0, 11]).week(),
            2,
            'Jan 11 2009 should be week 2'
        );
        assert.equal(
            moment([2009, 0, 12]).week(),
            3,
            'Jan 12 2009 should be week 3'
        );
        assert.equal(
            moment([2009, 11, 28]).week(),
            1,
            'Dec 28 2009 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 1]).week(),
            1,
            'Jan  1 2010 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 3]).week(),
            1,
            'Jan  3 2010 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 4]).week(),
            2,
            'Jan  4 2010 should be week 2'
        );
        assert.equal(
            moment([2010, 0, 10]).week(),
            2,
            'Jan 10 2010 should be week 2'
        );
        assert.equal(
            moment([2010, 0, 11]).week(),
            3,
            'Jan 11 2010 should be week 3'
        );
        assert.equal(
            moment([2010, 11, 27]).week(),
            1,
            'Dec 27 2010 should be week 1'
        );
        assert.equal(
            moment([2011, 0, 1]).week(),
            1,
            'Jan  1 2011 should be week 1'
        );
        assert.equal(
            moment([2011, 0, 2]).week(),
            1,
            'Jan  2 2011 should be week 1'
        );
        assert.equal(
            moment([2011, 0, 3]).week(),
            2,
            'Jan  3 2011 should be week 2'
        );
        assert.equal(
            moment([2011, 0, 9]).week(),
            2,
            'Jan  9 2011 should be week 2'
        );
        assert.equal(
            moment([2011, 0, 10]).week(),
            3,
            'Jan 10 2011 should be week 3'
        );
        moment.defineLocale('dow: 1, doy: 7', null);
    });

    test('weeks numbers dow:0 doy:6', function (assert) {
        moment.locale('dow: 0, doy: 6', { week: { dow: 0, doy: 6 } });
        assert.equal(
            moment([2012, 0, 1]).week(),
            1,
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).week(),
            1,
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).week(),
            2,
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).week(),
            2,
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).week(),
            3,
            'Jan 15 2012 should be week 3'
        );
        assert.equal(
            moment([2006, 11, 31]).week(),
            1,
            'Dec 31 2006 should be week 1'
        );
        assert.equal(
            moment([2007, 0, 1]).week(),
            1,
            'Jan  1 2007 should be week 1'
        );
        assert.equal(
            moment([2007, 0, 6]).week(),
            1,
            'Jan  6 2007 should be week 1'
        );
        assert.equal(
            moment([2007, 0, 7]).week(),
            2,
            'Jan  7 2007 should be week 2'
        );
        assert.equal(
            moment([2007, 0, 13]).week(),
            2,
            'Jan 13 2007 should be week 2'
        );
        assert.equal(
            moment([2007, 0, 14]).week(),
            3,
            'Jan 14 2007 should be week 3'
        );
        assert.equal(
            moment([2007, 11, 29]).week(),
            52,
            'Dec 29 2007 should be week 52'
        );
        assert.equal(
            moment([2008, 0, 1]).week(),
            1,
            'Jan  1 2008 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 5]).week(),
            1,
            'Jan  5 2008 should be week 1'
        );
        assert.equal(
            moment([2008, 0, 6]).week(),
            2,
            'Jan  6 2008 should be week 2'
        );
        assert.equal(
            moment([2008, 0, 12]).week(),
            2,
            'Jan 12 2008 should be week 2'
        );
        assert.equal(
            moment([2008, 0, 13]).week(),
            3,
            'Jan 13 2008 should be week 3'
        );
        assert.equal(
            moment([2002, 11, 29]).week(),
            1,
            'Dec 29 2002 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 1]).week(),
            1,
            'Jan  1 2003 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 4]).week(),
            1,
            'Jan  4 2003 should be week 1'
        );
        assert.equal(
            moment([2003, 0, 5]).week(),
            2,
            'Jan  5 2003 should be week 2'
        );
        assert.equal(
            moment([2003, 0, 11]).week(),
            2,
            'Jan 11 2003 should be week 2'
        );
        assert.equal(
            moment([2003, 0, 12]).week(),
            3,
            'Jan 12 2003 should be week 3'
        );
        assert.equal(
            moment([2008, 11, 28]).week(),
            1,
            'Dec 28 2008 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 1]).week(),
            1,
            'Jan  1 2009 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 3]).week(),
            1,
            'Jan  3 2009 should be week 1'
        );
        assert.equal(
            moment([2009, 0, 4]).week(),
            2,
            'Jan  4 2009 should be week 2'
        );
        assert.equal(
            moment([2009, 0, 10]).week(),
            2,
            'Jan 10 2009 should be week 2'
        );
        assert.equal(
            moment([2009, 0, 11]).week(),
            3,
            'Jan 11 2009 should be week 3'
        );
        assert.equal(
            moment([2009, 11, 27]).week(),
            1,
            'Dec 27 2009 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 1]).week(),
            1,
            'Jan  1 2010 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 2]).week(),
            1,
            'Jan  2 2010 should be week 1'
        );
        assert.equal(
            moment([2010, 0, 3]).week(),
            2,
            'Jan  3 2010 should be week 2'
        );
        assert.equal(
            moment([2010, 0, 9]).week(),
            2,
            'Jan  9 2010 should be week 2'
        );
        assert.equal(
            moment([2010, 0, 10]).week(),
            3,
            'Jan 10 2010 should be week 3'
        );
        assert.equal(
            moment([2010, 11, 26]).week(),
            1,
            'Dec 26 2010 should be week 1'
        );
        assert.equal(
            moment([2011, 0, 1]).week(),
            1,
            'Jan  1 2011 should be week 1'
        );
        assert.equal(
            moment([2011, 0, 2]).week(),
            2,
            'Jan  2 2011 should be week 2'
        );
        assert.equal(
            moment([2011, 0, 8]).week(),
            2,
            'Jan  8 2011 should be week 2'
        );
        assert.equal(
            moment([2011, 0, 9]).week(),
            3,
            'Jan  9 2011 should be week 3'
        );
        moment.defineLocale('dow: 0, doy: 6', null);
    });

    test('week year overflows', function (assert) {
        assert.equal(
            '2005-01-01',
            moment.utc('2004-W53-6', moment.ISO_8601, true).format('YYYY-MM-DD'),
            '2004-W53-6 is 1st Jan 2005'
        );
        assert.equal(
            '2007-12-31',
            moment.utc('2008-W01-1', moment.ISO_8601, true).format('YYYY-MM-DD'),
            '2008-W01-1 is 31st Dec 2007'
        );
    });

    test('weeks overflow', function (assert) {
        assert.equal(
            7,
            moment.utc('2004-W54-1', moment.ISO_8601, true).parsingFlags().overflow,
            '2004 has only 53 weeks'
        );
        assert.equal(
            7,
            moment.utc('2004-W00-1', moment.ISO_8601, true).parsingFlags().overflow,
            'there is no 0th week'
        );
    });

    test('weekday overflow', function (assert) {
        assert.equal(
            8,
            moment.utc('2004-W30-0', moment.ISO_8601, true).parsingFlags().overflow,
            'there is no 0 iso weekday'
        );
        assert.equal(
            8,
            moment.utc('2004-W30-8', moment.ISO_8601, true).parsingFlags().overflow,
            'there is no 8 iso weekday'
        );
        assert.equal(
            8,
            moment.utc('2004-w30-7', 'gggg-[w]ww-e', true).parsingFlags().overflow,
            "there is no 7 'e' weekday"
        );
        assert.equal(
            8,
            moment.utc('2004-w30-7', 'gggg-[w]ww-d', true).parsingFlags().overflow,
            "there is no 7 'd' weekday"
        );
    });

    test('week year setter works', function (assert) {
        for (var year = 2000; year <= 2020; year += 1) {
            assert.equal(
                moment
                    .utc('2012-12-31T00:00:00.000Z')
                    .isoWeekYear(year)
                    .isoWeekYear(),
                year,
                'setting iso-week-year to ' + year
            );
            assert.equal(
                moment.utc('2012-12-31T00:00:00.000Z').weekYear(year).weekYear(),
                year,
                'setting week-year to ' + year
            );
        }

        assert.equal(
            moment
                .utc('2004-W53-1', moment.ISO_8601, true)
                .isoWeekYear(2013)
                .format('GGGG-[W]WW-E'),
            '2013-W52-1',
            '2004-W53-1 to 2013'
        );
        assert.equal(
            moment
                .utc('2004-W53-1', moment.ISO_8601, true)
                .isoWeekYear(2020)
                .format('GGGG-[W]WW-E'),
            '2020-W53-1',
            '2004-W53-1 to 2020'
        );
        assert.equal(
            moment
                .utc('2005-W52-1', moment.ISO_8601, true)
                .isoWeekYear(2004)
                .format('GGGG-[W]WW-E'),
            '2004-W52-1',
            '2005-W52-1 to 2004'
        );
        assert.equal(
            moment
                .utc('2013-W30-4', moment.ISO_8601, true)
                .isoWeekYear(2015)
                .format('GGGG-[W]WW-E'),
            '2015-W30-4',
            '2013-W30-4 to 2015'
        );

        assert.equal(
            moment
                .utc('2005-w53-0', 'gggg-[w]ww-e', true)
                .weekYear(2013)
                .format('gggg-[w]ww-e'),
            '2013-w52-0',
            '2005-w53-0 to 2013'
        );
        assert.equal(
            moment
                .utc('2005-w53-0', 'gggg-[w]ww-e', true)
                .weekYear(2016)
                .format('gggg-[w]ww-e'),
            '2016-w53-0',
            '2005-w53-0 to 2016'
        );
        assert.equal(
            moment
                .utc('2004-w52-0', 'gggg-[w]ww-e', true)
                .weekYear(2005)
                .format('gggg-[w]ww-e'),
            '2005-w52-0',
            '2004-w52-0 to 2005'
        );
        assert.equal(
            moment
                .utc('2013-w30-4', 'gggg-[w]ww-e', true)
                .weekYear(2015)
                .format('gggg-[w]ww-e'),
            '2015-w30-4',
            '2013-w30-4 to 2015'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('week day');

    test('iso weekday', function (assert) {
        var i;

        for (i = 0; i < 7; ++i) {
            moment.locale('dow:' + i + ',doy: 6', { week: { dow: i, doy: 6 } });
            assert.equal(
                moment([1985, 1, 4]).isoWeekday(),
                1,
                'Feb  4 1985 is Monday    -- 1st day'
            );
            assert.equal(
                moment([2029, 8, 18]).isoWeekday(),
                2,
                'Sep 18 2029 is Tuesday   -- 2nd day'
            );
            assert.equal(
                moment([2013, 3, 24]).isoWeekday(),
                3,
                'Apr 24 2013 is Wednesday -- 3rd day'
            );
            assert.equal(
                moment([2015, 2, 5]).isoWeekday(),
                4,
                'Mar  5 2015 is Thursday  -- 4th day'
            );
            assert.equal(
                moment([1970, 0, 2]).isoWeekday(),
                5,
                'Jan  2 1970 is Friday    -- 5th day'
            );
            assert.equal(
                moment([2001, 4, 12]).isoWeekday(),
                6,
                'May 12 2001 is Saturday  -- 6th day'
            );
            assert.equal(
                moment([2000, 0, 2]).isoWeekday(),
                7,
                'Jan  2 2000 is Sunday    -- 7th day'
            );
        }
    });

    test('iso weekday setter', function (assert) {
        var a = moment([2011, 0, 10]);
        assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from mon to mon');
        assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from mon to thu');
        assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from mon to sun');
        assert.equal(
            moment(a).isoWeekday(-6).date(),
            3,
            'set from mon to last mon'
        );
        assert.equal(
            moment(a).isoWeekday(-3).date(),
            6,
            'set from mon to last thu'
        );
        assert.equal(moment(a).isoWeekday(0).date(), 9, 'set from mon to last sun');
        assert.equal(
            moment(a).isoWeekday(8).date(),
            17,
            'set from mon to next mon'
        );
        assert.equal(
            moment(a).isoWeekday(11).date(),
            20,
            'set from mon to next thu'
        );
        assert.equal(
            moment(a).isoWeekday(14).date(),
            23,
            'set from mon to next sun'
        );

        a = moment([2011, 0, 13]);
        assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from thu to mon');
        assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from thu to thu');
        assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from thu to sun');
        assert.equal(
            moment(a).isoWeekday(-6).date(),
            3,
            'set from thu to last mon'
        );
        assert.equal(
            moment(a).isoWeekday(-3).date(),
            6,
            'set from thu to last thu'
        );
        assert.equal(moment(a).isoWeekday(0).date(), 9, 'set from thu to last sun');
        assert.equal(
            moment(a).isoWeekday(8).date(),
            17,
            'set from thu to next mon'
        );
        assert.equal(
            moment(a).isoWeekday(11).date(),
            20,
            'set from thu to next thu'
        );
        assert.equal(
            moment(a).isoWeekday(14).date(),
            23,
            'set from thu to next sun'
        );

        a = moment([2011, 0, 16]);
        assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from sun to mon');
        assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from sun to thu');
        assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from sun to sun');
        assert.equal(
            moment(a).isoWeekday(-6).date(),
            3,
            'set from sun to last mon'
        );
        assert.equal(
            moment(a).isoWeekday(-3).date(),
            6,
            'set from sun to last thu'
        );
        assert.equal(moment(a).isoWeekday(0).date(), 9, 'set from sun to last sun');
        assert.equal(
            moment(a).isoWeekday(8).date(),
            17,
            'set from sun to next mon'
        );
        assert.equal(
            moment(a).isoWeekday(11).date(),
            20,
            'set from sun to next thu'
        );
        assert.equal(
            moment(a).isoWeekday(14).date(),
            23,
            'set from sun to next sun'
        );
    });

    test('iso weekday setter with day name', function (assert) {
        moment.locale('en');

        var a = moment([2011, 0, 10]);
        assert.equal(
            moment(a).isoWeekday('Monday').date(),
            10,
            'set from mon to mon'
        );
        assert.equal(
            moment(a).isoWeekday('Thursday').date(),
            13,
            'set from mon to thu'
        );
        assert.equal(
            moment(a).isoWeekday('Sunday').date(),
            16,
            'set from mon to sun'
        );

        a = moment([2011, 0, 13]);
        assert.equal(
            moment(a).isoWeekday('Monday').date(),
            10,
            'set from thu to mon'
        );
        assert.equal(
            moment(a).isoWeekday('Thursday').date(),
            13,
            'set from thu to thu'
        );
        assert.equal(
            moment(a).isoWeekday('Sunday').date(),
            16,
            'set from thu to sun'
        );

        a = moment([2011, 0, 16]);
        assert.equal(
            moment(a).isoWeekday('Monday').date(),
            10,
            'set from sun to mon'
        );
        assert.equal(
            moment(a).isoWeekday('Thursday').date(),
            13,
            'set from sun to thu'
        );
        assert.equal(
            moment(a).isoWeekday('Sunday').date(),
            16,
            'set from sun to sun'
        );
    });

    test('weekday first day of week Sunday (dow 0)', function (assert) {
        moment.locale('dow: 0,doy: 6', { week: { dow: 0, doy: 6 } });
        assert.equal(
            moment([1985, 1, 3]).weekday(),
            0,
            'Feb  3 1985 is Sunday    -- 0th day'
        );
        assert.equal(
            moment([2029, 8, 17]).weekday(),
            1,
            'Sep 17 2029 is Monday    -- 1st day'
        );
        assert.equal(
            moment([2013, 3, 23]).weekday(),
            2,
            'Apr 23 2013 is Tuesday   -- 2nd day'
        );
        assert.equal(
            moment([2015, 2, 4]).weekday(),
            3,
            'Mar  4 2015 is Wednesday -- 3nd day'
        );
        assert.equal(
            moment([1970, 0, 1]).weekday(),
            4,
            'Jan  1 1970 is Thursday  -- 4th day'
        );
        assert.equal(
            moment([2001, 4, 11]).weekday(),
            5,
            'May 11 2001 is Friday    -- 5th day'
        );
        assert.equal(
            moment([2000, 0, 1]).weekday(),
            6,
            'Jan  1 2000 is Saturday  -- 6th day'
        );
    });

    test('weekday first day of week Monday (dow 1)', function (assert) {
        moment.locale('dow: 1,doy: 6', { week: { dow: 1, doy: 6 } });
        assert.equal(
            moment([1985, 1, 4]).weekday(),
            0,
            'Feb  4 1985 is Monday    -- 0th day'
        );
        assert.equal(
            moment([2029, 8, 18]).weekday(),
            1,
            'Sep 18 2029 is Tuesday   -- 1st day'
        );
        assert.equal(
            moment([2013, 3, 24]).weekday(),
            2,
            'Apr 24 2013 is Wednesday -- 2nd day'
        );
        assert.equal(
            moment([2015, 2, 5]).weekday(),
            3,
            'Mar  5 2015 is Thursday  -- 3nd day'
        );
        assert.equal(
            moment([1970, 0, 2]).weekday(),
            4,
            'Jan  2 1970 is Friday    -- 4th day'
        );
        assert.equal(
            moment([2001, 4, 12]).weekday(),
            5,
            'May 12 2001 is Saturday  -- 5th day'
        );
        assert.equal(
            moment([2000, 0, 2]).weekday(),
            6,
            'Jan  2 2000 is Sunday    -- 6th day'
        );
    });

    test('weekday first day of week Tuesday (dow 2)', function (assert) {
        moment.locale('dow: 2,doy: 6', { week: { dow: 2, doy: 6 } });
        assert.equal(
            moment([1985, 1, 5]).weekday(),
            0,
            'Feb  5 1985 is Tuesday   -- 0th day'
        );
        assert.equal(
            moment([2029, 8, 19]).weekday(),
            1,
            'Sep 19 2029 is Wednesday -- 1st day'
        );
        assert.equal(
            moment([2013, 3, 25]).weekday(),
            2,
            'Apr 25 2013 is Thursday  -- 2nd day'
        );
        assert.equal(
            moment([2015, 2, 6]).weekday(),
            3,
            'Mar  6 2015 is Friday    -- 3nd day'
        );
        assert.equal(
            moment([1970, 0, 3]).weekday(),
            4,
            'Jan  3 1970 is Saturday  -- 4th day'
        );
        assert.equal(
            moment([2001, 4, 13]).weekday(),
            5,
            'May 13 2001 is Sunday    -- 5th day'
        );
        assert.equal(
            moment([2000, 0, 3]).weekday(),
            6,
            'Jan  3 2000 is Monday    -- 6th day'
        );
    });

    test('weekday first day of week Wednesday (dow 3)', function (assert) {
        moment.locale('dow: 3,doy: 6', { week: { dow: 3, doy: 6 } });
        assert.equal(
            moment([1985, 1, 6]).weekday(),
            0,
            'Feb  6 1985 is Wednesday -- 0th day'
        );
        assert.equal(
            moment([2029, 8, 20]).weekday(),
            1,
            'Sep 20 2029 is Thursday  -- 1st day'
        );
        assert.equal(
            moment([2013, 3, 26]).weekday(),
            2,
            'Apr 26 2013 is Friday    -- 2nd day'
        );
        assert.equal(
            moment([2015, 2, 7]).weekday(),
            3,
            'Mar  7 2015 is Saturday  -- 3nd day'
        );
        assert.equal(
            moment([1970, 0, 4]).weekday(),
            4,
            'Jan  4 1970 is Sunday    -- 4th day'
        );
        assert.equal(
            moment([2001, 4, 14]).weekday(),
            5,
            'May 14 2001 is Monday    -- 5th day'
        );
        assert.equal(
            moment([2000, 0, 4]).weekday(),
            6,
            'Jan  4 2000 is Tuesday   -- 6th day'
        );
    });

    test('weekday first day of week Thursday (dow 4)', function (assert) {
        moment.locale('dow: 4,doy: 6', { week: { dow: 4, doy: 6 } });
        assert.equal(
            moment([1985, 1, 7]).weekday(),
            0,
            'Feb  7 1985 is Thursday  -- 0th day'
        );
        assert.equal(
            moment([2029, 8, 21]).weekday(),
            1,
            'Sep 21 2029 is Friday    -- 1st day'
        );
        assert.equal(
            moment([2013, 3, 27]).weekday(),
            2,
            'Apr 27 2013 is Saturday  -- 2nd day'
        );
        assert.equal(
            moment([2015, 2, 8]).weekday(),
            3,
            'Mar  8 2015 is Sunday    -- 3nd day'
        );
        assert.equal(
            moment([1970, 0, 5]).weekday(),
            4,
            'Jan  5 1970 is Monday    -- 4th day'
        );
        assert.equal(
            moment([2001, 4, 15]).weekday(),
            5,
            'May 15 2001 is Tuesday   -- 5th day'
        );
        assert.equal(
            moment([2000, 0, 5]).weekday(),
            6,
            'Jan  5 2000 is Wednesday -- 6th day'
        );
    });

    test('weekday first day of week Friday (dow 5)', function (assert) {
        moment.locale('dow: 5,doy: 6', { week: { dow: 5, doy: 6 } });
        assert.equal(
            moment([1985, 1, 8]).weekday(),
            0,
            'Feb  8 1985 is Friday    -- 0th day'
        );
        assert.equal(
            moment([2029, 8, 22]).weekday(),
            1,
            'Sep 22 2029 is Saturday  -- 1st day'
        );
        assert.equal(
            moment([2013, 3, 28]).weekday(),
            2,
            'Apr 28 2013 is Sunday    -- 2nd day'
        );
        assert.equal(
            moment([2015, 2, 9]).weekday(),
            3,
            'Mar  9 2015 is Monday    -- 3nd day'
        );
        assert.equal(
            moment([1970, 0, 6]).weekday(),
            4,
            'Jan  6 1970 is Tuesday   -- 4th day'
        );
        assert.equal(
            moment([2001, 4, 16]).weekday(),
            5,
            'May 16 2001 is Wednesday -- 5th day'
        );
        assert.equal(
            moment([2000, 0, 6]).weekday(),
            6,
            'Jan  6 2000 is Thursday  -- 6th day'
        );
    });

    test('weekday first day of week Saturday (dow 6)', function (assert) {
        moment.locale('dow: 6,doy: 6', { week: { dow: 6, doy: 6 } });
        assert.equal(
            moment([1985, 1, 9]).weekday(),
            0,
            'Feb  9 1985 is Saturday  -- 0th day'
        );
        assert.equal(
            moment([2029, 8, 23]).weekday(),
            1,
            'Sep 23 2029 is Sunday    -- 1st day'
        );
        assert.equal(
            moment([2013, 3, 29]).weekday(),
            2,
            'Apr 29 2013 is Monday    -- 2nd day'
        );
        assert.equal(
            moment([2015, 2, 10]).weekday(),
            3,
            'Mar 10 2015 is Tuesday   -- 3nd day'
        );
        assert.equal(
            moment([1970, 0, 7]).weekday(),
            4,
            'Jan  7 1970 is Wednesday -- 4th day'
        );
        assert.equal(
            moment([2001, 4, 17]).weekday(),
            5,
            'May 17 2001 is Thursday  -- 5th day'
        );
        assert.equal(
            moment([2000, 0, 7]).weekday(),
            6,
            'Jan  7 2000 is Friday    -- 6th day'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('weeks in year');

    test('isoWeeksInYear', function (assert) {
        assert.equal(
            moment([2005]).isoWeeksInYear(),
            52,
            'ISO year 2005 has 52 iso weeks'
        );
        assert.equal(
            moment([2006]).isoWeeksInYear(),
            52,
            'ISO year 2006 has 52 iso weeks'
        );
        assert.equal(
            moment([2009]).isoWeeksInYear(),
            53,
            'ISO year 2009 has 53 iso weeks'
        );
        assert.equal(
            moment([2010]).isoWeeksInYear(),
            52,
            'ISO year 2010 has 52 iso weeks'
        );
    });

    test('isoWeeksInISOWeekYear first day of ISO Year', function (assert) {
        assert.equal(
            moment('2003-12-29').isoWeeksInISOWeekYear(),
            53,
            'ISO year 2004 has 53 iso weeks'
        );
        assert.equal(
            moment('2005-01-03').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2005 has 53 iso weeks'
        );
        assert.equal(
            moment('2006-01-02').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2006 has 53 iso weeks'
        );
        assert.equal(
            moment('2007-01-01').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2007 has 52 iso weeks'
        );
        assert.equal(
            moment('2007-12-31').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2008 has 53 iso weeks'
        );
        assert.equal(
            moment('2008-12-29').isoWeeksInISOWeekYear(),
            53,
            'ISO year 2009 has 53 iso weeks'
        );
        assert.equal(
            moment('2010-01-04').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2010 has 52 iso weeks'
        );
        assert.equal(
            moment('2011-01-03').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2011 has 52 iso weeks'
        );
        assert.equal(
            moment('2012-01-02').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2012 has 52 iso weeks'
        );
        assert.equal(
            moment('2012-12-31').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2013 has 52 iso weeks'
        );
        assert.equal(
            moment('2013-12-30').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2014 has 52 iso weeks'
        );
        assert.equal(
            moment('2014-12-29').isoWeeksInISOWeekYear(),
            53,
            'ISO year 2015 has 53 iso weeks'
        );
        assert.equal(
            moment('2016-01-04').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2016 has 52 iso weeks'
        );
        assert.equal(
            moment('2017-01-02').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2017 has 52 iso weeks'
        );
        assert.equal(
            moment('2018-01-01').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2018 has 52 iso weeks'
        );
        assert.equal(
            moment('2018-12-31').isoWeeksInISOWeekYear(),
            52,
            'ISO year 2019 has 52 iso weeks'
        );
        assert.equal(
            moment('2019-12-30').isoWeeksInISOWeekYear(),
            53,
            'ISO year 2020 has 53 iso weeks'
        );
    });

    test('weeksInYear doy/dow = 1/4', function (assert) {
        moment.locale('1/4', { week: { dow: 1, doy: 4 } });

        assert.equal(moment('2004-01-01').weeksInYear(), 53, '2004 has 53 weeks');
        assert.equal(moment('2005-01-01').weeksInYear(), 52, '2005 has 52 weeks');
        assert.equal(
            moment('2005-01-01').weeksInWeekYear(),
            53,
            '2005-01-01 is weekYear 2014, which has 53 weeks'
        );
        assert.equal(moment('2006-01-01').weeksInYear(), 52, '2006 has 52 weeks');
        assert.equal(moment('2007-01-01').weeksInYear(), 52, '2007 has 52 weeks');
        assert.equal(moment('2008-01-01').weeksInYear(), 52, '2008 has 52 weeks');
        assert.equal(moment('2009-01-01').weeksInYear(), 53, '2009 has 53 weeks');
        assert.equal(moment('2010-01-01').weeksInYear(), 52, '2010 has 52 weeks');
        assert.equal(
            moment('2010-01-01').weeksInWeekYear(),
            53,
            '2010-01-01 is weekYear 2009, which has 53 weeks'
        );
        assert.equal(moment('2011-01-01').weeksInYear(), 52, '2011 has 52 weeks');
        assert.equal(moment('2012-01-01').weeksInYear(), 52, '2012 has 52 weeks');
        assert.equal(moment('2013-01-01').weeksInYear(), 52, '2013 has 52 weeks');
        assert.equal(moment('2014-01-01').weeksInYear(), 52, '2014 has 52 weeks');
        assert.equal(moment('2015-01-01').weeksInYear(), 53, '2015 has 53 weeks');
        assert.equal(moment('2016-01-01').weeksInYear(), 52, '2016 has 52 weeks');
        assert.equal(
            moment('2016-01-01').weeksInWeekYear(),
            53,
            '2016-01-01 is weekYear 2015, which has 53 weeks'
        );
    });

    test('weeksInYear doy/dow = 6/12', function (assert) {
        moment.locale('6/12', { week: { dow: 6, doy: 12 } });

        assert.equal(moment([2004]).weeksInYear(), 53, '2004 has 53 weeks');
        assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 52 weeks');
        assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 52 weeks');
        assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');
        assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 52 weeks');
        assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 52 weeks');
        assert.equal(moment([2010]).weeksInYear(), 53, '2010 has 53 weeks');
        assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');
        assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');
        assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');
        assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');
        assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 52 weeks');
    });

    test('weeksInYear doy/dow = 1/7', function (assert) {
        moment.locale('1/7', { week: { dow: 1, doy: 7 } });

        assert.equal(moment([2004]).weeksInYear(), 52, '2004 has 52 weeks');
        assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 52 weeks');
        assert.equal(moment([2006]).weeksInYear(), 53, '2006 has 53 weeks');
        assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');
        assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 52 weeks');
        assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 52 weeks');
        assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');
        assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');
        assert.equal(moment([2012]).weeksInYear(), 53, '2012 has 53 weeks');
        assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');
        assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');
        assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 52 weeks');
        assert.equal(moment([2016]).weeksInYear(), 52, '2016 has 52 weeks');
    });

    test('weeksInYear doy/dow = 0/6', function (assert) {
        moment.locale('0/6', { week: { dow: 0, doy: 6 } });

        assert.equal(moment([2004]).weeksInYear(), 52, '2004 has 53 weeks');
        assert.equal(moment([2005]).weeksInYear(), 53, '2005 has 53 weeks');
        assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');
        assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');
        assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');
        assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');
        assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');
        assert.equal(moment([2011]).weeksInYear(), 53, '2011 has 52 weeks');
        assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');
        assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');
        assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');
        assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');
    });

    test('isoWeeksInYear calendar year !== ISO year', function (assert) {
        var m = moment('2010-01-01');
        assert.equal(
            moment('2019-12-31').isoWeeksInISOWeekYear(),
            53,
            'December 31, 2019 is in ISO year 2020 and ISO year 2020 has 53 weeks'
        );
        assert.equal(
            moment('2020-12-31').isoWeeksInISOWeekYear(),
            53,
            'December 31, 2020 is in ISO year 2020 and ISO year 2020 has 53 weeks'
        );
        assert.equal(
            m.isoWeeksInISOWeekYear(),
            53,
            '2010-01-01 is isoWeekYear 2009, which has 53 iso weeks'
        );
        assert.equal(
            +m,
            +moment('2010-01-01'),
            'isoWeeksInYear does not modify moment object'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('weeks');

    test('day of year', function (assert) {
        assert.equal(
            moment([2000, 0, 1]).dayOfYear(),
            1,
            'Jan  1 2000 should be day 1 of the year'
        );
        assert.equal(
            moment([2000, 1, 28]).dayOfYear(),
            59,
            'Feb 28 2000 should be day 59 of the year'
        );
        assert.equal(
            moment([2000, 1, 29]).dayOfYear(),
            60,
            'Feb 29 2000 should be day 60 of the year'
        );
        assert.equal(
            moment([2000, 11, 31]).dayOfYear(),
            366,
            'Dec 31 2000 should be day 366 of the year'
        );
        assert.equal(
            moment([2001, 0, 1]).dayOfYear(),
            1,
            'Jan  1 2001 should be day 1 of the year'
        );
        assert.equal(
            moment([2001, 1, 28]).dayOfYear(),
            59,
            'Feb 28 2001 should be day 59 of the year'
        );
        assert.equal(
            moment([2001, 2, 1]).dayOfYear(),
            60,
            'Mar  1 2001 should be day 60 of the year'
        );
        assert.equal(
            moment([2001, 11, 31]).dayOfYear(),
            365,
            'Dec 31 2001 should be day 365 of the year'
        );
    });

    test('day of year setters', function (assert) {
        assert.equal(
            moment([2000, 0, 1]).dayOfYear(200).dayOfYear(),
            200,
            'Setting Jan  1 2000 day of the year to 200 should work'
        );
        assert.equal(
            moment([2000, 1, 28]).dayOfYear(200).dayOfYear(),
            200,
            'Setting Feb 28 2000 day of the year to 200 should work'
        );
        assert.equal(
            moment([2000, 1, 29]).dayOfYear(200).dayOfYear(),
            200,
            'Setting Feb 29 2000 day of the year to 200 should work'
        );
        assert.equal(
            moment([2000, 11, 31]).dayOfYear(200).dayOfYear(),
            200,
            'Setting Dec 31 2000 day of the year to 200 should work'
        );
        assert.equal(
            moment().dayOfYear(1).dayOfYear(),
            1,
            'Setting day of the year to 1 should work'
        );
        assert.equal(
            moment().dayOfYear(59).dayOfYear(),
            59,
            'Setting day of the year to 59 should work'
        );
        assert.equal(
            moment().dayOfYear(60).dayOfYear(),
            60,
            'Setting day of the year to 60 should work'
        );
        assert.equal(
            moment().dayOfYear(365).dayOfYear(),
            365,
            'Setting day of the year to 365 should work'
        );
    });

    test('iso weeks year starting sunday', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).isoWeek(),
            52,
            'Jan  1 2012 should be iso week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).isoWeek(),
            1,
            'Jan  2 2012 should be iso week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).isoWeek(),
            1,
            'Jan  8 2012 should be iso week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).isoWeek(),
            2,
            'Jan  9 2012 should be iso week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).isoWeek(),
            2,
            'Jan 15 2012 should be iso week 2'
        );
    });

    test('iso weeks year starting monday', function (assert) {
        assert.equal(
            moment([2007, 0, 1]).isoWeek(),
            1,
            'Jan  1 2007 should be iso week 1'
        );
        assert.equal(
            moment([2007, 0, 7]).isoWeek(),
            1,
            'Jan  7 2007 should be iso week 1'
        );
        assert.equal(
            moment([2007, 0, 8]).isoWeek(),
            2,
            'Jan  8 2007 should be iso week 2'
        );
        assert.equal(
            moment([2007, 0, 14]).isoWeek(),
            2,
            'Jan 14 2007 should be iso week 2'
        );
        assert.equal(
            moment([2007, 0, 15]).isoWeek(),
            3,
            'Jan 15 2007 should be iso week 3'
        );
    });

    test('iso weeks year starting tuesday', function (assert) {
        assert.equal(
            moment([2007, 11, 31]).isoWeek(),
            1,
            'Dec 31 2007 should be iso week 1'
        );
        assert.equal(
            moment([2008, 0, 1]).isoWeek(),
            1,
            'Jan  1 2008 should be iso week 1'
        );
        assert.equal(
            moment([2008, 0, 6]).isoWeek(),
            1,
            'Jan  6 2008 should be iso week 1'
        );
        assert.equal(
            moment([2008, 0, 7]).isoWeek(),
            2,
            'Jan  7 2008 should be iso week 2'
        );
        assert.equal(
            moment([2008, 0, 13]).isoWeek(),
            2,
            'Jan 13 2008 should be iso week 2'
        );
        assert.equal(
            moment([2008, 0, 14]).isoWeek(),
            3,
            'Jan 14 2008 should be iso week 3'
        );
    });

    test('iso weeks year starting wednesday', function (assert) {
        assert.equal(
            moment([2002, 11, 30]).isoWeek(),
            1,
            'Dec 30 2002 should be iso week 1'
        );
        assert.equal(
            moment([2003, 0, 1]).isoWeek(),
            1,
            'Jan  1 2003 should be iso week 1'
        );
        assert.equal(
            moment([2003, 0, 5]).isoWeek(),
            1,
            'Jan  5 2003 should be iso week 1'
        );
        assert.equal(
            moment([2003, 0, 6]).isoWeek(),
            2,
            'Jan  6 2003 should be iso week 2'
        );
        assert.equal(
            moment([2003, 0, 12]).isoWeek(),
            2,
            'Jan 12 2003 should be iso week 2'
        );
        assert.equal(
            moment([2003, 0, 13]).isoWeek(),
            3,
            'Jan 13 2003 should be iso week 3'
        );
    });

    test('iso weeks year starting thursday', function (assert) {
        assert.equal(
            moment([2008, 11, 29]).isoWeek(),
            1,
            'Dec 29 2008 should be iso week 1'
        );
        assert.equal(
            moment([2009, 0, 1]).isoWeek(),
            1,
            'Jan  1 2009 should be iso week 1'
        );
        assert.equal(
            moment([2009, 0, 4]).isoWeek(),
            1,
            'Jan  4 2009 should be iso week 1'
        );
        assert.equal(
            moment([2009, 0, 5]).isoWeek(),
            2,
            'Jan  5 2009 should be iso week 2'
        );
        assert.equal(
            moment([2009, 0, 11]).isoWeek(),
            2,
            'Jan 11 2009 should be iso week 2'
        );
        assert.equal(
            moment([2009, 0, 13]).isoWeek(),
            3,
            'Jan 12 2009 should be iso week 3'
        );
    });

    test('iso weeks year starting friday', function (assert) {
        assert.equal(
            moment([2009, 11, 28]).isoWeek(),
            53,
            'Dec 28 2009 should be iso week 53'
        );
        assert.equal(
            moment([2010, 0, 1]).isoWeek(),
            53,
            'Jan  1 2010 should be iso week 53'
        );
        assert.equal(
            moment([2010, 0, 3]).isoWeek(),
            53,
            'Jan  3 2010 should be iso week 53'
        );
        assert.equal(
            moment([2010, 0, 4]).isoWeek(),
            1,
            'Jan  4 2010 should be iso week 1'
        );
        assert.equal(
            moment([2010, 0, 10]).isoWeek(),
            1,
            'Jan 10 2010 should be iso week 1'
        );
        assert.equal(
            moment([2010, 0, 11]).isoWeek(),
            2,
            'Jan 11 2010 should be iso week 2'
        );
    });

    test('iso weeks year starting saturday', function (assert) {
        assert.equal(
            moment([2010, 11, 27]).isoWeek(),
            52,
            'Dec 27 2010 should be iso week 52'
        );
        assert.equal(
            moment([2011, 0, 1]).isoWeek(),
            52,
            'Jan  1 2011 should be iso week 52'
        );
        assert.equal(
            moment([2011, 0, 2]).isoWeek(),
            52,
            'Jan  2 2011 should be iso week 52'
        );
        assert.equal(
            moment([2011, 0, 3]).isoWeek(),
            1,
            'Jan  3 2011 should be iso week 1'
        );
        assert.equal(
            moment([2011, 0, 9]).isoWeek(),
            1,
            'Jan  9 2011 should be iso week 1'
        );
        assert.equal(
            moment([2011, 0, 10]).isoWeek(),
            2,
            'Jan 10 2011 should be iso week 2'
        );
    });

    test('iso weeks year starting sunday formatted', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).format('W WW Wo'),
            '52 52 52nd',
            'Jan  1 2012 should be iso week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).format('W WW Wo'),
            '1 01 1st',
            'Jan  2 2012 should be iso week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).format('W WW Wo'),
            '1 01 1st',
            'Jan  8 2012 should be iso week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).format('W WW Wo'),
            '2 02 2nd',
            'Jan  9 2012 should be iso week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).format('W WW Wo'),
            '2 02 2nd',
            'Jan 15 2012 should be iso week 2'
        );
    });

    test('weeks plural year starting sunday', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).weeks(),
            1,
            'Jan  1 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 7]).weeks(),
            1,
            'Jan  7 2012 should be week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).weeks(),
            2,
            'Jan  8 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 14]).weeks(),
            2,
            'Jan 14 2012 should be week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).weeks(),
            3,
            'Jan 15 2012 should be week 3'
        );
    });

    test('iso weeks plural year starting sunday', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).isoWeeks(),
            52,
            'Jan  1 2012 should be iso week 52'
        );
        assert.equal(
            moment([2012, 0, 2]).isoWeeks(),
            1,
            'Jan  2 2012 should be iso week 1'
        );
        assert.equal(
            moment([2012, 0, 8]).isoWeeks(),
            1,
            'Jan  8 2012 should be iso week 1'
        );
        assert.equal(
            moment([2012, 0, 9]).isoWeeks(),
            2,
            'Jan  9 2012 should be iso week 2'
        );
        assert.equal(
            moment([2012, 0, 15]).isoWeeks(),
            2,
            'Jan 15 2012 should be iso week 2'
        );
    });

    test('weeks setter', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).week(30).week(),
            30,
            'Setting Jan 1 2012 to week 30 should work'
        );
        assert.equal(
            moment([2012, 0, 7]).week(30).week(),
            30,
            'Setting Jan 7 2012 to week 30 should work'
        );
        assert.equal(
            moment([2012, 0, 8]).week(30).week(),
            30,
            'Setting Jan 8 2012 to week 30 should work'
        );
        assert.equal(
            moment([2012, 0, 14]).week(30).week(),
            30,
            'Setting Jan 14 2012 to week 30 should work'
        );
        assert.equal(
            moment([2012, 0, 15]).week(30).week(),
            30,
            'Setting Jan 15 2012 to week 30 should work'
        );
    });

    test('iso weeks setter', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).isoWeeks(25).isoWeeks(),
            25,
            'Setting Jan  1 2012 to week 25 should work'
        );
        assert.equal(
            moment([2012, 0, 2]).isoWeeks(24).isoWeeks(),
            24,
            'Setting Jan  2 2012 to week 24 should work'
        );
        assert.equal(
            moment([2012, 0, 8]).isoWeeks(23).isoWeeks(),
            23,
            'Setting Jan  8 2012 to week 23 should work'
        );
        assert.equal(
            moment([2012, 0, 9]).isoWeeks(22).isoWeeks(),
            22,
            'Setting Jan  9 2012 to week 22 should work'
        );
        assert.equal(
            moment([2012, 0, 15]).isoWeeks(21).isoWeeks(),
            21,
            'Setting Jan 15 2012 to week 21 should work'
        );
    });

    test('iso weeks setter day of year', function (assert) {
        assert.equal(
            moment([2012, 0, 1]).isoWeek(1).dayOfYear(),
            9,
            'Setting Jan  1 2012 to week 1 should be day of year 8'
        );
        assert.equal(
            moment([2012, 0, 1]).isoWeek(1).year(),
            2011,
            'Setting Jan  1 2012 to week 1 should be year 2011'
        );
        assert.equal(
            moment([2012, 0, 2]).isoWeek(1).dayOfYear(),
            2,
            'Setting Jan  2 2012 to week 1 should be day of year 2'
        );
        assert.equal(
            moment([2012, 0, 8]).isoWeek(1).dayOfYear(),
            8,
            'Setting Jan  8 2012 to week 1 should be day of year 8'
        );
        assert.equal(
            moment([2012, 0, 9]).isoWeek(1).dayOfYear(),
            2,
            'Setting Jan  9 2012 to week 1 should be day of year 2'
        );
        assert.equal(
            moment([2012, 0, 15]).isoWeek(1).dayOfYear(),
            8,
            'Setting Jan 15 2012 to week 1 should be day of year 8'
        );
    });

    test('years with iso week 53', function (assert) {
        // Based on a table taken from https://en.wikipedia.org/wiki/ISO_week_date
        // (as downloaded on 2014-01-06) listing the 71 years in a 400-year cycle
        // that have 53 weeks; in this case reflecting the 2000 based cycle
        assert.equal(
            moment([2004, 11, 31]).isoWeek(),
            53,
            'Dec 31 2004 should be iso week 53'
        );
        assert.equal(
            moment([2009, 11, 31]).isoWeek(),
            53,
            'Dec 31 2009 should be iso week 53'
        );
        assert.equal(
            moment([2015, 11, 31]).isoWeek(),
            53,
            'Dec 31 2015 should be iso week 53'
        );
        assert.equal(
            moment([2020, 11, 31]).isoWeek(),
            53,
            'Dec 31 2020 should be iso week 53'
        );
        assert.equal(
            moment([2026, 11, 31]).isoWeek(),
            53,
            'Dec 31 2026 should be iso week 53'
        );
        assert.equal(
            moment([2032, 11, 31]).isoWeek(),
            53,
            'Dec 31 2032 should be iso week 53'
        );
        assert.equal(
            moment([2037, 11, 31]).isoWeek(),
            53,
            'Dec 31 2037 should be iso week 53'
        );
        assert.equal(
            moment([2043, 11, 31]).isoWeek(),
            53,
            'Dec 31 2043 should be iso week 53'
        );
        assert.equal(
            moment([2048, 11, 31]).isoWeek(),
            53,
            'Dec 31 2048 should be iso week 53'
        );
        assert.equal(
            moment([2054, 11, 31]).isoWeek(),
            53,
            'Dec 31 2054 should be iso week 53'
        );
        assert.equal(
            moment([2060, 11, 31]).isoWeek(),
            53,
            'Dec 31 2060 should be iso week 53'
        );
        assert.equal(
            moment([2065, 11, 31]).isoWeek(),
            53,
            'Dec 31 2065 should be iso week 53'
        );
        assert.equal(
            moment([2071, 11, 31]).isoWeek(),
            53,
            'Dec 31 2071 should be iso week 53'
        );
        assert.equal(
            moment([2076, 11, 31]).isoWeek(),
            53,
            'Dec 31 2076 should be iso week 53'
        );
        assert.equal(
            moment([2082, 11, 31]).isoWeek(),
            53,
            'Dec 31 2082 should be iso week 53'
        );
        assert.equal(
            moment([2088, 11, 31]).isoWeek(),
            53,
            'Dec 31 2088 should be iso week 53'
        );
        assert.equal(
            moment([2093, 11, 31]).isoWeek(),
            53,
            'Dec 31 2093 should be iso week 53'
        );
        assert.equal(
            moment([2099, 11, 31]).isoWeek(),
            53,
            'Dec 31 2099 should be iso week 53'
        );
        assert.equal(
            moment([2105, 11, 31]).isoWeek(),
            53,
            'Dec 31 2105 should be iso week 53'
        );
        assert.equal(
            moment([2111, 11, 31]).isoWeek(),
            53,
            'Dec 31 2111 should be iso week 53'
        );
        assert.equal(
            moment([2116, 11, 31]).isoWeek(),
            53,
            'Dec 31 2116 should be iso week 53'
        );
        assert.equal(
            moment([2122, 11, 31]).isoWeek(),
            53,
            'Dec 31 2122 should be iso week 53'
        );
        assert.equal(
            moment([2128, 11, 31]).isoWeek(),
            53,
            'Dec 31 2128 should be iso week 53'
        );
        assert.equal(
            moment([2133, 11, 31]).isoWeek(),
            53,
            'Dec 31 2133 should be iso week 53'
        );
        assert.equal(
            moment([2139, 11, 31]).isoWeek(),
            53,
            'Dec 31 2139 should be iso week 53'
        );
        assert.equal(
            moment([2144, 11, 31]).isoWeek(),
            53,
            'Dec 31 2144 should be iso week 53'
        );
        assert.equal(
            moment([2150, 11, 31]).isoWeek(),
            53,
            'Dec 31 2150 should be iso week 53'
        );
        assert.equal(
            moment([2156, 11, 31]).isoWeek(),
            53,
            'Dec 31 2156 should be iso week 53'
        );
        assert.equal(
            moment([2161, 11, 31]).isoWeek(),
            53,
            'Dec 31 2161 should be iso week 53'
        );
        assert.equal(
            moment([2167, 11, 31]).isoWeek(),
            53,
            'Dec 31 2167 should be iso week 53'
        );
        assert.equal(
            moment([2172, 11, 31]).isoWeek(),
            53,
            'Dec 31 2172 should be iso week 53'
        );
        assert.equal(
            moment([2178, 11, 31]).isoWeek(),
            53,
            'Dec 31 2178 should be iso week 53'
        );
        assert.equal(
            moment([2184, 11, 31]).isoWeek(),
            53,
            'Dec 31 2184 should be iso week 53'
        );
        assert.equal(
            moment([2189, 11, 31]).isoWeek(),
            53,
            'Dec 31 2189 should be iso week 53'
        );
        assert.equal(
            moment([2195, 11, 31]).isoWeek(),
            53,
            'Dec 31 2195 should be iso week 53'
        );
        assert.equal(
            moment([2201, 11, 31]).isoWeek(),
            53,
            'Dec 31 2201 should be iso week 53'
        );
        assert.equal(
            moment([2207, 11, 31]).isoWeek(),
            53,
            'Dec 31 2207 should be iso week 53'
        );
        assert.equal(
            moment([2212, 11, 31]).isoWeek(),
            53,
            'Dec 31 2212 should be iso week 53'
        );
        assert.equal(
            moment([2218, 11, 31]).isoWeek(),
            53,
            'Dec 31 2218 should be iso week 53'
        );
        assert.equal(
            moment([2224, 11, 31]).isoWeek(),
            53,
            'Dec 31 2224 should be iso week 53'
        );
        assert.equal(
            moment([2229, 11, 31]).isoWeek(),
            53,
            'Dec 31 2229 should be iso week 53'
        );
        assert.equal(
            moment([2235, 11, 31]).isoWeek(),
            53,
            'Dec 31 2235 should be iso week 53'
        );
        assert.equal(
            moment([2240, 11, 31]).isoWeek(),
            53,
            'Dec 31 2240 should be iso week 53'
        );
        assert.equal(
            moment([2246, 11, 31]).isoWeek(),
            53,
            'Dec 31 2246 should be iso week 53'
        );
        assert.equal(
            moment([2252, 11, 31]).isoWeek(),
            53,
            'Dec 31 2252 should be iso week 53'
        );
        assert.equal(
            moment([2257, 11, 31]).isoWeek(),
            53,
            'Dec 31 2257 should be iso week 53'
        );
        assert.equal(
            moment([2263, 11, 31]).isoWeek(),
            53,
            'Dec 31 2263 should be iso week 53'
        );
        assert.equal(
            moment([2268, 11, 31]).isoWeek(),
            53,
            'Dec 31 2268 should be iso week 53'
        );
        assert.equal(
            moment([2274, 11, 31]).isoWeek(),
            53,
            'Dec 31 2274 should be iso week 53'
        );
        assert.equal(
            moment([2280, 11, 31]).isoWeek(),
            53,
            'Dec 31 2280 should be iso week 53'
        );
        assert.equal(
            moment([2285, 11, 31]).isoWeek(),
            53,
            'Dec 31 2285 should be iso week 53'
        );
        assert.equal(
            moment([2291, 11, 31]).isoWeek(),
            53,
            'Dec 31 2291 should be iso week 53'
        );
        assert.equal(
            moment([2296, 11, 31]).isoWeek(),
            53,
            'Dec 31 2296 should be iso week 53'
        );
        assert.equal(
            moment([2303, 11, 31]).isoWeek(),
            53,
            'Dec 31 2303 should be iso week 53'
        );
        assert.equal(
            moment([2308, 11, 31]).isoWeek(),
            53,
            'Dec 31 2308 should be iso week 53'
        );
        assert.equal(
            moment([2314, 11, 31]).isoWeek(),
            53,
            'Dec 31 2314 should be iso week 53'
        );
        assert.equal(
            moment([2320, 11, 31]).isoWeek(),
            53,
            'Dec 31 2320 should be iso week 53'
        );
        assert.equal(
            moment([2325, 11, 31]).isoWeek(),
            53,
            'Dec 31 2325 should be iso week 53'
        );
        assert.equal(
            moment([2331, 11, 31]).isoWeek(),
            53,
            'Dec 31 2331 should be iso week 53'
        );
        assert.equal(
            moment([2336, 11, 31]).isoWeek(),
            53,
            'Dec 31 2336 should be iso week 53'
        );
        assert.equal(
            moment([2342, 11, 31]).isoWeek(),
            53,
            'Dec 31 2342 should be iso week 53'
        );
        assert.equal(
            moment([2348, 11, 31]).isoWeek(),
            53,
            'Dec 31 2348 should be iso week 53'
        );
        assert.equal(
            moment([2353, 11, 31]).isoWeek(),
            53,
            'Dec 31 2353 should be iso week 53'
        );
        assert.equal(
            moment([2359, 11, 31]).isoWeek(),
            53,
            'Dec 31 2359 should be iso week 53'
        );
        assert.equal(
            moment([2364, 11, 31]).isoWeek(),
            53,
            'Dec 31 2364 should be iso week 53'
        );
        assert.equal(
            moment([2370, 11, 31]).isoWeek(),
            53,
            'Dec 31 2370 should be iso week 53'
        );
        assert.equal(
            moment([2376, 11, 31]).isoWeek(),
            53,
            'Dec 31 2376 should be iso week 53'
        );
        assert.equal(
            moment([2381, 11, 31]).isoWeek(),
            53,
            'Dec 31 2381 should be iso week 53'
        );
        assert.equal(
            moment([2387, 11, 31]).isoWeek(),
            53,
            'Dec 31 2387 should be iso week 53'
        );
        assert.equal(
            moment([2392, 11, 31]).isoWeek(),
            53,
            'Dec 31 2392 should be iso week 53'
        );
        assert.equal(
            moment([2398, 11, 31]).isoWeek(),
            53,
            'Dec 31 2398 should be iso week 53'
        );
    });

    test('count years with iso week 53', function (assert) {
        // Based on https://en.wikipedia.org/wiki/ISO_week_date (as seen on 2014-01-06)
        // stating that there are 71 years in a 400-year cycle that have 53 weeks;
        // in this case reflecting the 2000 based cycle
        var count = 0,
            i;
        for (i = 0; i < 400; i++) {
            count += moment([2000 + i, 11, 31]).isoWeek() === 53 ? 1 : 0;
        }
        assert.equal(
            count,
            71,
            'Should have 71 years in 400-year cycle with iso week 53'
        );
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    function isNearSpringDST() {
        return (
            moment().subtract(1, 'day').utcOffset() !==
            moment().add(1, 'day').utcOffset()
        );
    }

    module('zone switching');

    test('local to utc, keepLocalTime = true', function (assert) {
        var m = moment(),
            fmt = 'YYYY-DD-MM HH:mm:ss';
        assert.equal(
            m.clone().utc(true).format(fmt),
            m.format(fmt),
            'local to utc failed to keep local time'
        );
    });

    test('local to utc, keepLocalTime = false', function (assert) {
        var m = moment();
        assert.equal(
            m.clone().utc().valueOf(),
            m.valueOf(),
            'local to utc failed to keep utc time (implicit)'
        );
        assert.equal(
            m.clone().utc(false).valueOf(),
            m.valueOf(),
            'local to utc failed to keep utc time (explicit)'
        );
    });

    test('local to zone, keepLocalTime = true', function (assert) {
        test.expectedDeprecations('moment().zone');
        var m = moment(),
            fmt = 'YYYY-DD-MM HH:mm:ss',
            z;

        // Apparently there is -12:00 and +14:00
        // https://en.wikipedia.org/wiki/UTC+14:00
        // https://en.wikipedia.org/wiki/UTC-12:00
        for (z = -12; z <= 14; ++z) {
            assert.equal(
                m
                    .clone()
                    .zone(z * 60, true)
                    .format(fmt),
                m.format(fmt),
                'local to zone(' + z + ':00) failed to keep local time'
            );
        }
    });

    test('local to zone, keepLocalTime = false', function (assert) {
        test.expectedDeprecations('moment().zone');
        var m = moment(),
            z;

        // Apparently there is -12:00 and +14:00
        // https://en.wikipedia.org/wiki/UTC+14:00
        // https://en.wikipedia.org/wiki/UTC-12:00
        for (z = -12; z <= 14; ++z) {
            assert.equal(
                m
                    .clone()
                    .zone(z * 60)
                    .valueOf(),
                m.valueOf(),
                'local to zone(' + z + ':00) failed to keep utc time (implicit)'
            );
            assert.equal(
                m
                    .clone()
                    .zone(z * 60, false)
                    .valueOf(),
                m.valueOf(),
                'local to zone(' + z + ':00) failed to keep utc time (explicit)'
            );
        }
    });

    test('utc to local, keepLocalTime = true', function (assert) {
        // Don't test near the spring DST transition
        if (isNearSpringDST()) {
            assert.expect(0);
            return;
        }

        var um = moment.utc(),
            fmt = 'YYYY-DD-MM HH:mm:ss';

        assert.equal(
            um.clone().local(true).format(fmt),
            um.format(fmt),
            'utc to local failed to keep local time'
        );
    });

    test('utc to local, keepLocalTime = false', function (assert) {
        var um = moment.utc();
        assert.equal(
            um.clone().local().valueOf(),
            um.valueOf(),
            'utc to local failed to keep utc time (implicit)'
        );
        assert.equal(
            um.clone().local(false).valueOf(),
            um.valueOf(),
            'utc to local failed to keep utc time (explicit)'
        );
    });

    test('zone to local, keepLocalTime = true', function (assert) {
        // Don't test near the spring DST transition
        if (isNearSpringDST()) {
            assert.expect(0);
            return;
        }

        test.expectedDeprecations('moment().zone');

        var m = moment(),
            fmt = 'YYYY-DD-MM HH:mm:ss',
            z;

        // Apparently there is -12:00 and +14:00
        // https://en.wikipedia.org/wiki/UTC+14:00
        // https://en.wikipedia.org/wiki/UTC-12:00
        for (z = -12; z <= 14; ++z) {
            m.zone(z * 60);

            assert.equal(
                m.clone().local(true).format(fmt),
                m.format(fmt),
                'zone(' + z + ':00) to local failed to keep local time'
            );
        }
    });

    test('zone to local, keepLocalTime = false', function (assert) {
        test.expectedDeprecations('moment().zone');
        var m = moment(),
            z;

        // Apparently there is -12:00 and +14:00
        // https://en.wikipedia.org/wiki/UTC+14:00
        // https://en.wikipedia.org/wiki/UTC-12:00
        for (z = -12; z <= 14; ++z) {
            m.zone(z * 60);

            assert.equal(
                m.clone().local(false).valueOf(),
                m.valueOf(),
                'zone(' + z + ':00) to local failed to keep utc time (explicit)'
            );
            assert.equal(
                m.clone().local().valueOf(),
                m.valueOf(),
                'zone(' + z + ':00) to local failed to keep utc time (implicit)'
            );
        }
    });

})));



;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../../moment')) :
   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

    function each(array, callback) {
        var i;
        for (i = 0; i < array.length; i++) {
            callback(array[i], i, array);
        }
    }

    function setupDeprecationHandler(test, moment, scope) {
        test._expectedDeprecations = null;
        test._observedDeprecations = null;
        test._oldSupress = moment.suppressDeprecationWarnings;
        moment.suppressDeprecationWarnings = true;
        test.expectedDeprecations = function () {
            test._expectedDeprecations = arguments;
            test._observedDeprecations = [];
        };
        moment.deprecationHandler = function (name, msg) {
            var deprecationId = matchedDeprecation(
                name,
                msg,
                test._expectedDeprecations
            );
            if (deprecationId === -1) {
                throw new Error(
                    'Unexpected deprecation thrown name=' + name + ' msg=' + msg
                );
            }
            test._observedDeprecations[deprecationId] = 1;
        };
    }

    function teardownDeprecationHandler(test, moment, scope) {
        moment.suppressDeprecationWarnings = test._oldSupress;

        if (test._expectedDeprecations != null) {
            var missedDeprecations = [];
            each(test._expectedDeprecations, function (deprecationPattern, id) {
                if (test._observedDeprecations[id] !== 1) {
                    missedDeprecations.push(deprecationPattern);
                }
            });
            if (missedDeprecations.length !== 0) {
                throw new Error(
                    'Expected deprecation warnings did not happen: ' +
                        missedDeprecations.join(' ')
                );
            }
        }
    }

    function matchedDeprecation(name, msg, deprecations) {
        if (deprecations == null) {
            return -1;
        }
        for (var i = 0; i < deprecations.length; ++i) {
            if (name != null && name === deprecations[i]) {
                return i;
            }
            if (
                msg != null &&
                msg.substring(0, deprecations[i].length) === deprecations[i]
            ) {
                return i;
            }
        }
        return -1;
    }

    /*global QUnit:false*/

    var test = QUnit.test,
        only = QUnit.only;

    function module(name, lifecycle) {
        QUnit.module(name, {
            beforeEach: function () {
                moment.locale('en');
                moment.createFromInputFallback = function (config) {
                    throw new Error('input not handled by moment: ' + config._i);
                };
                setupDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.setup) {
                    lifecycle.setup();
                }
            },
            afterEach: function () {
                teardownDeprecationHandler(test, moment);
                if (lifecycle && lifecycle.teardown) {
                    lifecycle.teardown();
                }
            },
        });
    }

    module('zones', {
        setup: function () {
            test.expectedDeprecations('moment().zone');
        },
    });

    test('set zone', function (assert) {
        var zone = moment();

        zone.zone(0);
        assert.equal(zone.zone(), 0, 'should be able to set the zone to 0');

        zone.zone(60);
        assert.equal(zone.zone(), 60, 'should be able to set the zone to 60');

        zone.zone(-60);
        assert.equal(zone.zone(), -60, 'should be able to set the zone to -60');
    });

    test('set zone shorthand', function (assert) {
        var zone = moment();

        zone.zone(1);
        assert.equal(
            zone.zone(),
            60,
            'setting the zone to 1 should imply hours and convert to 60'
        );

        zone.zone(-1);
        assert.equal(
            zone.zone(),
            -60,
            'setting the zone to -1 should imply hours and convert to -60'
        );

        zone.zone(15);
        assert.equal(
            zone.zone(),
            900,
            'setting the zone to 15 should imply hours and convert to 900'
        );

        zone.zone(-15);
        assert.equal(
            zone.zone(),
            -900,
            'setting the zone to -15 should imply hours and convert to -900'
        );

        zone.zone(16);
        assert.equal(
            zone.zone(),
            16,
            'setting the zone to 16 should imply minutes'
        );

        zone.zone(-16);
        assert.equal(
            zone.zone(),
            -16,
            'setting the zone to -16 should imply minutes'
        );
    });

    test('set zone with string', function (assert) {
        var zone = moment();

        zone.zone('+00:00');
        assert.equal(zone.zone(), 0, 'set the zone with a timezone string');

        zone.zone('2013-03-07T07:00:00-08:00');
        assert.equal(
            zone.zone(),
            480,
            'set the zone with a string that does not begin with the timezone'
        );

        zone.zone('2013-03-07T07:00:00+0100');
        assert.equal(
            zone.zone(),
            -60,
            'set the zone with a string that uses the +0000 syntax'
        );

        zone.zone('2013-03-07T07:00:00+02');
        assert.equal(
            zone.zone(),
            -120,
            'set the zone with a string that uses the +00 syntax'
        );

        zone.zone('03-07-2013T07:00:00-08:00');
        assert.equal(
            zone.zone(),
            480,
            'set the zone with a string with a non-ISO 8601 date'
        );
    });

    test('change hours when changing the zone', function (assert) {
        var zone = moment.utc([2000, 0, 1, 6]);

        zone.zone(0);
        assert.equal(zone.hour(), 6, 'UTC 6AM should be 6AM at +0000');

        zone.zone(60);
        assert.equal(zone.hour(), 5, 'UTC 6AM should be 5AM at -0100');

        zone.zone(-60);
        assert.equal(zone.hour(), 7, 'UTC 6AM should be 7AM at +0100');
    });

    test('change minutes when changing the zone', function (assert) {
        var zone = moment.utc([2000, 0, 1, 6, 31]);

        zone.zone(0);
        assert.equal(
            zone.format('HH:mm'),
            '06:31',
            'UTC 6:31AM should be 6:31AM at +0000'
        );

        zone.zone(30);
        assert.equal(
            zone.format('HH:mm'),
            '06:01',
            'UTC 6:31AM should be 6:01AM at -0030'
        );

        zone.zone(-30);
        assert.equal(
            zone.format('HH:mm'),
            '07:01',
            'UTC 6:31AM should be 7:01AM at +0030'
        );

        zone.zone(1380);
        assert.equal(
            zone.format('HH:mm'),
            '07:31',
            'UTC 6:31AM should be 7:31AM at +1380'
        );
    });

    test('distance from the unix epoch', function (assert) {
        var zoneA = moment(),
            zoneB = moment(zoneA),
            zoneC = moment(zoneA),
            zoneD = moment(zoneA),
            zoneE = moment(zoneA);

        zoneB.utc();
        assert.equal(+zoneA, +zoneB, 'moment should equal moment.utc');

        zoneC.zone(-60);
        assert.equal(+zoneA, +zoneC, 'moment should equal moment.zone(-60)');

        zoneD.zone(480);
        assert.equal(+zoneA, +zoneD, 'moment should equal moment.zone(480)');

        zoneE.zone(1000);
        assert.equal(+zoneA, +zoneE, 'moment should equal moment.zone(1000)');
    });

    test('update offset after changing any values', function (assert) {
        var oldOffset = moment.updateOffset,
            m = moment.utc([2000, 6, 1]);

        moment.updateOffset = function (mom, keepTime) {
            if (mom.__doChange) {
                if (+mom > 962409600000) {
                    mom.zone(120, keepTime);
                } else {
                    mom.zone(60, keepTime);
                }
            }
        };

        assert.equal(m.format('ZZ'), '+0000', 'should be at +0000');
        assert.equal(
            m.format('HH:mm'),
            '00:00',
            'should start 12AM at +0000 timezone'
        );

        m.__doChange = true;
        m.add(1, 'h');

        assert.equal(m.format('ZZ'), '-0200', 'should be at -0200');
        assert.equal(
            m.format('HH:mm'),
            '23:00',
            '1AM at +0000 should be 11PM at -0200 timezone'
        );

        m.subtract(1, 'h');

        assert.equal(m.format('ZZ'), '-0100', 'should be at -0100');
        assert.equal(
            m.format('HH:mm'),
            '23:00',
            '12AM at +0000 should be 11PM at -0100 timezone'
        );

        moment.updateOffset = oldOffset;
    });

    test('getters and setters', function (assert) {
        var a = moment([2011, 5, 20]);

        assert.equal(
            a.clone().zone(120).year(2012).year(),
            2012,
            'should get and set year correctly'
        );
        assert.equal(
            a.clone().zone(120).month(1).month(),
            1,
            'should get and set month correctly'
        );
        assert.equal(
            a.clone().zone(120).date(2).date(),
            2,
            'should get and set date correctly'
        );
        assert.equal(
            a.clone().zone(120).day(1).day(),
            1,
            'should get and set day correctly'
        );
        assert.equal(
            a.clone().zone(120).hour(1).hour(),
            1,
            'should get and set hour correctly'
        );
        assert.equal(
            a.clone().zone(120).minute(1).minute(),
            1,
            'should get and set minute correctly'
        );
    });

    test('getters', function (assert) {
        var a = moment.utc([2012, 0, 1, 0, 0, 0]);

        assert.equal(a.clone().zone(120).year(), 2011, 'should get year correctly');
        assert.equal(a.clone().zone(120).month(), 11, 'should get month correctly');
        assert.equal(a.clone().zone(120).date(), 31, 'should get date correctly');
        assert.equal(a.clone().zone(120).hour(), 22, 'should get hour correctly');
        assert.equal(
            a.clone().zone(120).minute(),
            0,
            'should get minute correctly'
        );

        assert.equal(
            a.clone().zone(-120).year(),
            2012,
            'should get year correctly'
        );
        assert.equal(a.clone().zone(-120).month(), 0, 'should get month correctly');
        assert.equal(a.clone().zone(-120).date(), 1, 'should get date correctly');
        assert.equal(a.clone().zone(-120).hour(), 2, 'should get hour correctly');
        assert.equal(
            a.clone().zone(-120).minute(),
            0,
            'should get minute correctly'
        );

        assert.equal(a.clone().zone(-90).year(), 2012, 'should get year correctly');
        assert.equal(a.clone().zone(-90).month(), 0, 'should get month correctly');
        assert.equal(a.clone().zone(-90).date(), 1, 'should get date correctly');
        assert.equal(a.clone().zone(-90).hour(), 1, 'should get hour correctly');
        assert.equal(
            a.clone().zone(-90).minute(),
            30,
            'should get minute correctly'
        );
    });

    test('from', function (assert) {
        var zoneA = moment(),
            zoneB = moment(zoneA).zone(720),
            zoneC = moment(zoneA).zone(360),
            zoneD = moment(zoneA).zone(-690),
            other = moment(zoneA).add(35, 'm');

        assert.equal(
            zoneA.from(other),
            zoneB.from(other),
            'moment#from should be the same in all zones'
        );
        assert.equal(
            zoneA.from(other),
            zoneC.from(other),
            'moment#from should be the same in all zones'
        );
        assert.equal(
            zoneA.from(other),
            zoneD.from(other),
            'moment#from should be the same in all zones'
        );
    });

    test('diff', function (assert) {
        var zoneA = moment(),
            zoneB = moment(zoneA).zone(720),
            zoneC = moment(zoneA).zone(360),
            zoneD = moment(zoneA).zone(-690),
            other = moment(zoneA).add(35, 'm');

        assert.equal(
            zoneA.diff(other),
            zoneB.diff(other),
            'moment#diff should be the same in all zones'
        );
        assert.equal(
            zoneA.diff(other),
            zoneC.diff(other),
            'moment#diff should be the same in all zones'
        );
        assert.equal(
            zoneA.diff(other),
            zoneD.diff(other),
            'moment#diff should be the same in all zones'
        );

        assert.equal(
            zoneA.diff(other, 'minute', true),
            zoneB.diff(other, 'minute', true),
            'moment#diff should be the same in all zones'
        );
        assert.equal(
            zoneA.diff(other, 'minute', true),
            zoneC.diff(other, 'minute', true),
            'moment#diff should be the same in all zones'
        );
        assert.equal(
            zoneA.diff(other, 'minute', true),
            zoneD.diff(other, 'minute', true),
            'moment#diff should be the same in all zones'
        );

        assert.equal(
            zoneA.diff(other, 'hour', true),
            zoneB.diff(other, 'hour', true),
            'moment#diff should be the same in all zones'
        );
        assert.equal(
            zoneA.diff(other, 'hour', true),
            zoneC.diff(other, 'hour', true),
            'moment#diff should be the same in all zones'
        );
        assert.equal(
            zoneA.diff(other, 'hour', true),
            zoneD.diff(other, 'hour', true),
            'moment#diff should be the same in all zones'
        );
    });

    test('unix offset and timestamp', function (assert) {
        var zoneA = moment(),
            zoneB = moment(zoneA).zone(720),
            zoneC = moment(zoneA).zone(360),
            zoneD = moment(zoneA).zone(-690);

        assert.equal(
            zoneA.unix(),
            zoneB.unix(),
            'moment#unix should be the same in all zones'
        );
        assert.equal(
            zoneA.unix(),
            zoneC.unix(),
            'moment#unix should be the same in all zones'
        );
        assert.equal(
            zoneA.unix(),
            zoneD.unix(),
            'moment#unix should be the same in all zones'
        );

        assert.equal(
            +zoneA,
            +zoneB,
            'moment#valueOf should be the same in all zones'
        );
        assert.equal(
            +zoneA,
            +zoneC,
            'moment#valueOf should be the same in all zones'
        );
        assert.equal(
            +zoneA,
            +zoneD,
            'moment#valueOf should be the same in all zones'
        );
    });

    test('cloning', function (assert) {
        assert.equal(
            moment().zone(120).clone().zone(),
            120,
            'explicit cloning should retain the zone'
        );
        assert.equal(
            moment().zone(-120).clone().zone(),
            -120,
            'explicit cloning should retain the zone'
        );
        assert.equal(
            moment(moment().zone(120)).zone(),
            120,
            'implicit cloning should retain the zone'
        );
        assert.equal(
            moment(moment().zone(-120)).zone(),
            -120,
            'implicit cloning should retain the zone'
        );
    });

    test('start of / end of', function (assert) {
        var a = moment.utc([2010, 1, 2, 0, 0, 0]).zone(450);

        assert.equal(
            a.clone().startOf('day').hour(),
            0,
            'start of day should work on moments with a zone'
        );
        assert.equal(
            a.clone().startOf('day').minute(),
            0,
            'start of day should work on moments with a zone'
        );
        assert.equal(
            a.clone().startOf('hour').minute(),
            0,
            'start of hour should work on moments with a zone'
        );

        assert.equal(
            a.clone().endOf('day').hour(),
            23,
            'end of day should work on moments with a zone'
        );
        assert.equal(
            a.clone().endOf('day').minute(),
            59,
            'end of day should work on moments with a zone'
        );
        assert.equal(
            a.clone().endOf('hour').minute(),
            59,
            'end of hour should work on moments with a zone'
        );
    });

    test('reset zone with moment#utc', function (assert) {
        var a = moment.utc([2012]).zone(480);

        assert.equal(
            a.clone().hour(),
            16,
            'different zone should have different hour'
        );
        assert.equal(
            a.clone().utc().hour(),
            0,
            'calling moment#utc should reset the offset'
        );
    });

    test('reset zone with moment#local', function (assert) {
        var a = moment([2012]).zone(480);

        assert.equal(
            a.clone().local().hour(),
            0,
            'calling moment#local should reset the offset'
        );
    });

    test('toDate', function (assert) {
        var zoneA = new Date(),
            zoneB = moment(zoneA).zone(720).toDate(),
            zoneC = moment(zoneA).zone(360).toDate(),
            zoneD = moment(zoneA).zone(-690).toDate();

        assert.equal(
            +zoneA,
            +zoneB,
            'moment#toDate should output a date with the right unix timestamp'
        );
        assert.equal(
            +zoneA,
            +zoneC,
            'moment#toDate should output a date with the right unix timestamp'
        );
        assert.equal(
            +zoneA,
            +zoneD,
            'moment#toDate should output a date with the right unix timestamp'
        );
    });

    test('same / before / after', function (assert) {
        var zoneA = moment().utc(),
            zoneB = moment(zoneA).zone(120),
            zoneC = moment(zoneA).zone(-120);

        assert.ok(
            zoneA.isSame(zoneB),
            'two moments with different offsets should be the same'
        );
        assert.ok(
            zoneA.isSame(zoneC),
            'two moments with different offsets should be the same'
        );

        assert.ok(
            zoneA.isSame(zoneB, 'hour'),
            'two moments with different offsets should be the same hour'
        );
        assert.ok(
            zoneA.isSame(zoneC, 'hour'),
            'two moments with different offsets should be the same hour'
        );

        zoneA.add(1, 'hour');

        assert.ok(
            zoneA.isAfter(zoneB),
            'isAfter should work with two moments with different offsets'
        );
        assert.ok(
            zoneA.isAfter(zoneC),
            'isAfter should work with two moments with different offsets'
        );

        assert.ok(
            zoneA.isAfter(zoneB, 'hour'),
            'isAfter:hour should work with two moments with different offsets'
        );
        assert.ok(
            zoneA.isAfter(zoneC, 'hour'),
            'isAfter:hour should work with two moments with different offsets'
        );

        zoneA.subtract(2, 'hour');

        assert.ok(
            zoneA.isBefore(zoneB),
            'isBefore should work with two moments with different offsets'
        );
        assert.ok(
            zoneA.isBefore(zoneC),
            'isBefore should work with two moments with different offsets'
        );

        assert.ok(
            zoneA.isBefore(zoneB, 'hour'),
            'isBefore:hour should work with two moments with different offsets'
        );
        assert.ok(
            zoneA.isBefore(zoneC, 'hour'),
            'isBefore:hour should work with two moments with different offsets'
        );
    });

    test('add / subtract over dst', function (assert) {
        var oldOffset = moment.updateOffset,
            m = moment.utc([2000, 2, 31, 3]);

        moment.updateOffset = function (mom, keepTime) {
            if (mom.clone().utc().month() > 2) {
                mom.zone(-60, keepTime);
            } else {
                mom.zone(0, keepTime);
            }
        };

        assert.equal(m.hour(), 3, 'should start at 00:00');

        m.add(24, 'hour');

        assert.equal(m.hour(), 4, 'adding 24 hours should disregard dst');

        m.subtract(24, 'hour');

        assert.equal(m.hour(), 3, 'subtracting 24 hours should disregard dst');

        m.add(1, 'day');

        assert.equal(m.hour(), 3, 'adding 1 day should have the same hour');

        m.subtract(1, 'day');

        assert.equal(m.hour(), 3, 'subtracting 1 day should have the same hour');

        m.add(1, 'month');

        assert.equal(m.hour(), 3, 'adding 1 month should have the same hour');

        m.subtract(1, 'month');

        assert.equal(m.hour(), 3, 'subtracting 1 month should have the same hour');

        moment.updateOffset = oldOffset;
    });

    test('isDST', function (assert) {
        var oldOffset = moment.updateOffset;

        moment.updateOffset = function (mom, keepTime) {
            if (mom.month() > 2 && mom.month() < 9) {
                mom.zone(-60, keepTime);
            } else {
                mom.zone(0, keepTime);
            }
        };

        assert.ok(!moment().month(0).isDST(), 'Jan should not be summer dst');
        assert.ok(moment().month(6).isDST(), 'Jul should be summer dst');
        assert.ok(!moment().month(11).isDST(), 'Dec should not be summer dst');

        moment.updateOffset = function (mom) {
            if (mom.month() > 2 && mom.month() < 9) {
                mom.zone(0);
            } else {
                mom.zone(-60);
            }
        };

        assert.ok(moment().month(0).isDST(), 'Jan should be winter dst');
        assert.ok(!moment().month(6).isDST(), 'Jul should not be winter dst');
        assert.ok(moment().month(11).isDST(), 'Dec should be winter dst');

        moment.updateOffset = oldOffset;
    });

    test('zone names', function (assert) {
        test.expectedDeprecations();
        assert.equal(moment().zoneAbbr(), '', 'Local zone abbr should be empty');
        assert.equal(
            moment().format('z'),
            '',
            'Local zone formatted abbr should be empty'
        );
        assert.equal(moment().zoneName(), '', 'Local zone name should be empty');
        assert.equal(
            moment().format('zz'),
            '',
            'Local zone formatted name should be empty'
        );

        assert.equal(moment.utc().zoneAbbr(), 'UTC', 'UTC zone abbr should be UTC');
        assert.equal(
            moment.utc().format('z'),
            'UTC',
            'UTC zone formatted abbr should be UTC'
        );
        assert.equal(
            moment.utc().zoneName(),
            'Coordinated Universal Time',
            'UTC zone abbr should be Coordinated Universal Time'
        );
        assert.equal(
            moment.utc().format('zz'),
            'Coordinated Universal Time',
            'UTC zone formatted abbr should be Coordinated Universal Time'
        );
    });

    test('hours alignment with UTC', function (assert) {
        assert.equal(moment().zone(120).hasAlignedHourOffset(), true);
        assert.equal(moment().zone(-180).hasAlignedHourOffset(), true);
        assert.equal(moment().zone(90).hasAlignedHourOffset(), false);
        assert.equal(moment().zone(-90).hasAlignedHourOffset(), false);
    });

    test('hours alignment with other zone', function (assert) {
        var m = moment().zone(120);

        assert.equal(m.hasAlignedHourOffset(moment().zone(180)), true);
        assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), true);
        assert.equal(m.hasAlignedHourOffset(moment().zone(90)), false);
        assert.equal(m.hasAlignedHourOffset(moment().zone(-90)), false);

        m = moment().zone(90);

        assert.equal(m.hasAlignedHourOffset(moment().zone(180)), false);
        assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), false);
        assert.equal(m.hasAlignedHourOffset(moment().zone(30)), true);
        assert.equal(m.hasAlignedHourOffset(moment().zone(-30)), true);

        m = moment().zone(-60);

        assert.equal(m.hasAlignedHourOffset(moment().zone(180)), true);
        assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), true);
        assert.equal(m.hasAlignedHourOffset(moment().zone(90)), false);
        assert.equal(m.hasAlignedHourOffset(moment().zone(-90)), false);

        m = moment().zone(25);

        assert.equal(m.hasAlignedHourOffset(moment().zone(-35)), true);
        assert.equal(m.hasAlignedHourOffset(moment().zone(85)), true);

        assert.equal(m.hasAlignedHourOffset(moment().zone(35)), false);
        assert.equal(m.hasAlignedHourOffset(moment().zone(-85)), false);
    });

    test('parse zone', function (assert) {
        var m = moment('2013-01-01T00:00:00-13:00').parseZone();
        assert.equal(m.zone(), 13 * 60);
        assert.equal(m.hours(), 0);
    });

    test('parse zone static', function (assert) {
        var m = moment.parseZone('2013-01-01T00:00:00-13:00');
        assert.equal(m.zone(), 13 * 60);
        assert.equal(m.hours(), 0);
    });

    test('parse zone with more arguments', function (assert) {
        test.expectedDeprecations();
        var m;
        m = moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ');
        assert.equal(
            m.format(),
            '2013-01-01T05:00:00-13:00',
            'accept input and format'
        );
        m = moment.parseZone('2013-01-01-13:00', 'YYYY MM DD ZZ', true);
        assert.equal(m.isValid(), false, 'accept input, format and strict flag');
        m = moment.parseZone('2013-01-01-13:00', [
            'DD MM YYYY ZZ',
            'YYYY MM DD ZZ',
        ]);
        assert.equal(
            m.format(),
            '2013-01-01T00:00:00-13:00',
            'accept input and array of formats'
        );
    });

    test('parse zone with a timezone from the format string', function (assert) {
        var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY ZZ #####').parseZone();

        assert.equal(m.zone(), 4 * 60);
    });

    test('parse zone without a timezone included in the format string', function (assert) {
        var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY').parseZone();

        assert.equal(m.zone(), -11 * 60);
    });

    test('timezone format', function (assert) {
        assert.equal(moment().zone(-60).format('ZZ'), '+0100', '-60 -> +0100');
        assert.equal(moment().zone(-90).format('ZZ'), '+0130', '-90 -> +0130');
        assert.equal(moment().zone(-120).format('ZZ'), '+0200', '-120 -> +0200');

        assert.equal(
            moment()
                .zone(+60)
                .format('ZZ'),
            '-0100',
            '+60 -> -0100'
        );
        assert.equal(
            moment()
                .zone(+90)
                .format('ZZ'),
            '-0130',
            '+90 -> -0130'
        );
        assert.equal(
            moment()
                .zone(+120)
                .format('ZZ'),
            '-0200',
            '+120 -> -0200'
        );
    });

    test('parse zone without a timezone', function (assert) {
        test.expectedDeprecations();
        var m1 = moment.parseZone('2016-02-01T00:00:00'),
            m2 = moment.parseZone('2016-02-01T00:00:00Z'),
            m3 = moment.parseZone('2016-02-01T00:00:00+00:00'), //Someone might argue this is not necessary, you could even argue that is wrong being here.
            m4 = moment.parseZone('2016-02-01T00:00:00+0000'); //Someone might argue this is not necessary, you could even argue that is wrong being here.
        assert.equal(
            m1.format('M D YYYY HH:mm:ss ZZ'),
            '2 1 2016 00:00:00 +0000',
            'Not providing a timezone should keep the time and change the zone to 0'
        );
        assert.equal(
            m2.format('M D YYYY HH:mm:ss ZZ'),
            '2 1 2016 00:00:00 +0000',
            'Not providing a timezone should keep the time and change the zone to 0'
        );
        assert.equal(
            m3.format('M D YYYY HH:mm:ss ZZ'),
            '2 1 2016 00:00:00 +0000',
            'Not providing a timezone should keep the time and change the zone to 0'
        );
        assert.equal(
            m4.format('M D YYYY HH:mm:ss ZZ'),
            '2 1 2016 00:00:00 +0000',
            'Not providing a timezone should keep the time and change the zone to 0'
        );
    });

    test('parse zone with a minutes unit abs less than 16 should retain minutes', function (assert) {
        //ensure when minutes are explicitly parsed, they are retained
        //instead of converted to hours, even if less than 16
        var n = moment.parseZone('2013-01-01T00:00:00-00:15'),
            o;
        assert.equal(n.utcOffset(), -15);
        assert.equal(n.zone(), 15);
        assert.equal(n.hour(), 0);

        o = moment.parseZone('2013-01-01T00:00:00+00:15');
        assert.equal(o.utcOffset(), 15);
        assert.equal(o.zone(), -15);
        assert.equal(o.hour(), 0);
    });

    test('parse zone with weekday on verifies day according to the offset', function (assert) {
        test.expectedDeprecations();
        assert.ok(
            moment.parseZone('Mon 03:59 +12:00', 'ddd HH:mm Z', true).isValid(),
            'Monday 03:59'
        );
    });

})));
