diff options
| author | Frederic van der Essen <fva@openerp.com / fvdessen+o@gmail.com> | 2014-08-25 16:42:57 +0200 |
|---|---|---|
| committer | Frederic van der Essen <fva@openerp.com / fvdessen+o@gmail.com> | 2014-08-25 16:42:57 +0200 |
| commit | d7f93defb899b2b48a14d679e5dffffdb4a00eff (patch) | |
| tree | f8572183b480477622917a1f504cf49a8e202f6e /addons/web | |
| parent | 2b67528fe9e366829d44d8aba756bc6e359b4c61 (diff) | |
| parent | 36146b3fadc47543f4b696ab75c31b3459afb15b (diff) | |
Merge branch 'master' into master-pos-new-payment-screen-fva
Conflicts:
addons/point_of_sale/point_of_sale.py
addons/point_of_sale/point_of_sale_view.xml
Diffstat (limited to 'addons/web')
102 files changed, 12037 insertions, 1500 deletions
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index b74efc9c452..b34c33d4a23 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -70,7 +70,7 @@ def serialize_exception(f): se = _serialize_exception(e) error = { 'code': 200, - 'message': "OpenERP Server Error", + 'message': "Odoo Server Error", 'data': se } return werkzeug.exceptions.InternalServerError(simplejson.dumps(error)) @@ -590,6 +590,34 @@ class WebClient(http.Controller): def jslist(self, mods=None): return manifest_list('js', mods=mods) + @http.route('/web/webclient/locale/<string:lang>', type='http', auth="none") + def load_locale(self, lang): + magic_file_finding = [lang.replace("_",'-').lower(), lang.split('_')[0]] + addons_path = http.addons_manifest['web']['addons_path'] + #load datejs locale + datejs_locale = "" + try: + with open(os.path.join(addons_path, 'web', 'static', 'lib', 'datejs', 'globalization', lang.replace('_', '-') + '.js'), 'r') as f: + datejs_locale = f.read() + except IOError: + pass + + #load momentjs locale + momentjs_locale_file = False + momentjs_locale = "" + for code in magic_file_finding: + try: + with open(os.path.join(addons_path, 'web', 'static', 'lib', 'moment', 'locale', code + '.js'), 'r') as f: + momentjs_locale = f.read() + #we found a locale matching so we can exit + break + except IOError: + continue + + #return the content of the locale + headers = [('Content-Type', 'application/javascript'), ('Cache-Control', 'max-age=%s' % (36000))] + return request.make_response(datejs_locale + "\n"+ momentjs_locale, headers) + @http.route('/web/webclient/qweb', type='http', auth="none") def qweb(self, mods=None, db=None): files = [f[0] for f in manifest_glob('qweb', addons=mods, db=db)] @@ -1330,7 +1358,7 @@ class Export(http.Controller): fields['.id'] = fields.pop('id', {'string': 'ID'}) fields_sequence = sorted(fields.iteritems(), - key=lambda field: field[1].get('string', '')) + key=lambda field: openerp.tools.ustr(field[1].get('string', ''))) records = [] for field_name, field in fields_sequence: diff --git a/addons/web/doc/_templates/sidebarintro.html b/addons/web/doc/_templates/sidebarintro.html index ecd51980e58..bbe4c472607 100644 --- a/addons/web/doc/_templates/sidebarintro.html +++ b/addons/web/doc/_templates/sidebarintro.html @@ -1,16 +1,16 @@ -<p class="logo"><a href="http://doc.openerp.com/"> +<p class="logo"><a href="https://doc.odoo.com/"> <img class="logo" src="{{ pathto('_static/openerp.png', 1) }}" alt="Logo"/> </a></p> <h3>Other Docs</h3> <ul> - <li><a href="http://doc.openerp.com/trunk/developers">OpenERP Developers Documentation</a></li> - <li><a href="http://doc.openerp.com/trunk/developers/server">OpenERP Server Developers Documentation</a></li> - <li><a href="http://doc.openerp.com/trunk/users">OpenERP Users Documentation</a></li> + <li><a href="https://doc.odoo.com/trunk">Odoo Developers Documentation</a></li> + <li><a href="https://doc.odoo.com/trunk/server">Odoo Server Developers Documentation</a></li> + <li><a href="https://doc.odoo.com/book">Odoo Users Documentation</a></li> </ul> <h3>Useful Links</h3> <ul> - <li><a href="http://www.openerp.com/">The OpenERP website</a></li> + <li><a href="https://www.odoo.com/">The Odoo website</a></li> <li><a href="http://python.org/">The Python programming language</a></li> </ul> diff --git a/addons/web/static/lib/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css b/addons/web/static/lib/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css new file mode 100644 index 00000000000..69ca89a2e5e --- /dev/null +++ b/addons/web/static/lib/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css @@ -0,0 +1,234 @@ +/*! + * Datetimepicker for Bootstrap v3 +//! version : 3.0.3 + * https://github.com/Eonasdan/bootstrap-datetimepicker/ + */ +.bootstrap-datetimepicker-widget { + top: 0; + left: 0; + width: 250px; + padding: 4px; + margin-top: 1px; + z-index: 99999 !important; + border-radius: 4px; +} +.bootstrap-datetimepicker-widget.timepicker-sbs { + width: 600px; +} +.bootstrap-datetimepicker-widget.bottom:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 7px; +} +.bootstrap-datetimepicker-widget.bottom:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid white; + position: absolute; + top: -6px; + left: 8px; +} +.bootstrap-datetimepicker-widget.top:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-top: 7px solid #ccc; + border-top-color: rgba(0, 0, 0, 0.2); + position: absolute; + bottom: -7px; + left: 6px; +} +.bootstrap-datetimepicker-widget.top:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-top: 6px solid white; + position: absolute; + bottom: -6px; + left: 7px; +} +.bootstrap-datetimepicker-widget .dow { + width: 14.2857%; +} +.bootstrap-datetimepicker-widget.pull-right:before { + left: auto; + right: 6px; +} +.bootstrap-datetimepicker-widget.pull-right:after { + left: auto; + right: 7px; +} +.bootstrap-datetimepicker-widget > ul { + list-style-type: none; + margin: 0; +} +.bootstrap-datetimepicker-widget a[data-action] { + padding: 6px 0; +} +.bootstrap-datetimepicker-widget .timepicker-hour, +.bootstrap-datetimepicker-widget .timepicker-minute, +.bootstrap-datetimepicker-widget .timepicker-second { + width: 54px; + font-weight: bold; + font-size: 1.2em; + margin: 0; +} +.bootstrap-datetimepicker-widget button[data-action] { + padding: 6px; +} +.bootstrap-datetimepicker-widget table[data-hour-format="12"] .separator { + width: 4px; + padding: 0; + margin: 0; +} +.bootstrap-datetimepicker-widget .datepicker > div { + display: none; +} +.bootstrap-datetimepicker-widget .picker-switch { + text-align: center; +} +.bootstrap-datetimepicker-widget table { + width: 100%; + margin: 0; +} +.bootstrap-datetimepicker-widget td, +.bootstrap-datetimepicker-widget th { + text-align: center; + border-radius: 4px; +} +.bootstrap-datetimepicker-widget td { + height: 54px; + line-height: 54px; + width: 54px; +} +.bootstrap-datetimepicker-widget td.cw { + font-size: 10px; + height: 20px; + line-height: 20px; +} +.bootstrap-datetimepicker-widget td.day { + height: 20px; + line-height: 20px; + width: 20px; +} +.bootstrap-datetimepicker-widget td.day:hover, +.bootstrap-datetimepicker-widget td.hour:hover, +.bootstrap-datetimepicker-widget td.minute:hover, +.bootstrap-datetimepicker-widget td.second:hover { + background: #eeeeee; + cursor: pointer; +} +.bootstrap-datetimepicker-widget td.old, +.bootstrap-datetimepicker-widget td.new { + color: #777777; +} +.bootstrap-datetimepicker-widget td.today { + position: relative; +} +.bootstrap-datetimepicker-widget td.today:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-bottom: 7px solid #428bca; + border-top-color: rgba(0, 0, 0, 0.2); + position: absolute; + bottom: 4px; + right: 4px; +} +.bootstrap-datetimepicker-widget td.active, +.bootstrap-datetimepicker-widget td.active:hover { + background-color: #428bca; + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.bootstrap-datetimepicker-widget td.active.today:before { + border-bottom-color: #fff; +} +.bootstrap-datetimepicker-widget td.disabled, +.bootstrap-datetimepicker-widget td.disabled:hover { + background: none; + color: #777777; + cursor: not-allowed; +} +.bootstrap-datetimepicker-widget td span { + display: inline-block; + width: 54px; + height: 54px; + line-height: 54px; + margin: 2px 1.5px; + cursor: pointer; + border-radius: 4px; +} +.bootstrap-datetimepicker-widget td span:hover { + background: #eeeeee; +} +.bootstrap-datetimepicker-widget td span.active { + background-color: #428bca; + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.bootstrap-datetimepicker-widget td span.old { + color: #777777; +} +.bootstrap-datetimepicker-widget td span.disabled, +.bootstrap-datetimepicker-widget td span.disabled:hover { + background: none; + color: #777777; + cursor: not-allowed; +} +.bootstrap-datetimepicker-widget th { + height: 20px; + line-height: 20px; + width: 20px; +} +.bootstrap-datetimepicker-widget th.picker-switch { + width: 145px; +} +.bootstrap-datetimepicker-widget th.next, +.bootstrap-datetimepicker-widget th.prev { + font-size: 21px; +} +.bootstrap-datetimepicker-widget th.disabled, +.bootstrap-datetimepicker-widget th.disabled:hover { + background: none; + color: #777777; + cursor: not-allowed; +} +.bootstrap-datetimepicker-widget thead tr:first-child th { + cursor: pointer; +} +.bootstrap-datetimepicker-widget thead tr:first-child th:hover { + background: #eeeeee; +} +.input-group.date .input-group-addon span { + display: block; + cursor: pointer; + width: 16px; + height: 16px; +} +.bootstrap-datetimepicker-widget.left-oriented:before { + left: auto; + right: 6px; +} +.bootstrap-datetimepicker-widget.left-oriented:after { + left: auto; + right: 7px; +} +.bootstrap-datetimepicker-widget ul.list-unstyled li div.timepicker div.timepicker-picker table.table-condensed tbody > tr > td { + padding: 0px !important; +} +@media screen and (max-width: 767px) { + .bootstrap-datetimepicker-widget.timepicker-sbs { + width: 283px; + } +} diff --git a/addons/web/static/lib/bootstrap-datetimepicker/src/js/bootstrap-datetimepicker.js b/addons/web/static/lib/bootstrap-datetimepicker/src/js/bootstrap-datetimepicker.js new file mode 100644 index 00000000000..8619c44a7d6 --- /dev/null +++ b/addons/web/static/lib/bootstrap-datetimepicker/src/js/bootstrap-datetimepicker.js @@ -0,0 +1,1370 @@ +/* +//! version : 3.0.3 +========================================================= +bootstrap-datetimepicker.js +https://github.com/Eonasdan/bootstrap-datetimepicker +========================================================= +The MIT License (MIT) + +Copyright (c) 2014 Jonathan Peterson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +;(function (root, factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // AMD is used - Register as an anonymous module. + define(['jquery', 'moment'], factory); + } else { + // AMD is not used - Attempt to fetch dependencies from scope. + if (!jQuery) { + throw new Error('bootstrap-datetimepicker requires jQuery to be loaded first'); + } + if (!moment) { + throw new Error('bootstrap-datetimepicker requires moment.js to be loaded first'); + } + factory(root.jQuery, moment); + } +}(this, function ($, moment) { + 'use strict'; + if (typeof moment === 'undefined') { + throw new Error('momentjs is required'); + } + + var dpgId = 0, + + DateTimePicker = function (element, options) { + var defaults = $.fn.datetimepicker.defaults, + + icons = { + time: 'glyphicon glyphicon-time', + date: 'glyphicon glyphicon-calendar', + up: 'glyphicon glyphicon-chevron-up', + down: 'glyphicon glyphicon-chevron-down' + }, + + picker = this, + + dDate, + + init = function () { + var icon = false, localeData, rInterval; + picker.options = $.extend({}, defaults, options); + picker.options.icons = $.extend({}, icons, picker.options.icons); + + picker.element = $(element); + + dataToOptions(); + + if (!(picker.options.pickTime || picker.options.pickDate)) { + throw new Error('Must choose at least one picker'); + } + + picker.id = dpgId++; + moment.locale(picker.options.language); + picker.date = moment(); + picker.unset = false; + picker.isInput = picker.element.is('input'); + picker.component = false; + + if (picker.element.hasClass('input-group')) { + if (picker.element.find('.datepickerbutton').size() === 0) {//in case there is more then one 'input-group-addon' Issue #48 + picker.component = picker.element.find('[class^="input-group-"]'); + } + else { + picker.component = picker.element.find('.datepickerbutton'); + } + } + picker.format = picker.options.format; + + localeData = moment().localeData(); + + if (!picker.format) { + picker.format = (picker.options.pickDate ? localeData.longDateFormat('L') : ''); + if (picker.options.pickDate && picker.options.pickTime) { + picker.format += ' '; + } + picker.format += (picker.options.pickTime ? localeData.longDateFormat('LT') : ''); + if (picker.options.useSeconds) { + if (localeData.longDateFormat('LT').indexOf(' A') !== -1) { + picker.format = picker.format.split(' A')[0] + ':ss A'; + } + else { + picker.format += ':ss'; + } + } + } + picker.use24hours = picker.format.toLowerCase().indexOf('a') < 1; + + if (picker.component) { + icon = picker.component.find('span'); + } + + if (picker.options.pickTime) { + if (icon) { + icon.addClass(picker.options.icons.time); + } + } + if (picker.options.pickDate) { + if (icon) { + icon.removeClass(picker.options.icons.time); + icon.addClass(picker.options.icons.date); + } + } + + picker.options.widgetParent = + typeof picker.options.widgetParent === 'string' && picker.options.widgetParent || + picker.element.parents().filter(function () { + return 'scroll' === $(this).css('overflow-y'); + }).get(0) || + 'body'; + + picker.widget = $(getTemplate()).appendTo(picker.options.widgetParent); + + picker.minViewMode = picker.options.minViewMode || 0; + if (typeof picker.minViewMode === 'string') { + switch (picker.minViewMode) { + case 'months': + picker.minViewMode = 1; + break; + case 'years': + picker.minViewMode = 2; + break; + default: + picker.minViewMode = 0; + break; + } + } + picker.viewMode = picker.options.viewMode || 0; + if (typeof picker.viewMode === 'string') { + switch (picker.viewMode) { + case 'months': + picker.viewMode = 1; + break; + case 'years': + picker.viewMode = 2; + break; + default: + picker.viewMode = 0; + break; + } + } + + picker.viewMode = Math.max(picker.viewMode, picker.minViewMode); + + picker.options.disabledDates = indexGivenDates(picker.options.disabledDates); + picker.options.enabledDates = indexGivenDates(picker.options.enabledDates); + + picker.startViewMode = picker.viewMode; + picker.setMinDate(picker.options.minDate); + picker.setMaxDate(picker.options.maxDate); + fillDow(); + fillMonths(); + fillHours(); + fillMinutes(); + fillSeconds(); + update(); + showMode(); + attachDatePickerEvents(); + if (picker.options.defaultDate !== '' && getPickerInput().val() === '') { + picker.setValue(picker.options.defaultDate); + } + if (picker.options.minuteStepping !== 1) { + rInterval = picker.options.minuteStepping; + picker.date.minutes((Math.round(picker.date.minutes() / rInterval) * rInterval) % 60).seconds(0); + } + }, + + getPickerInput = function () { + var input; + + if (picker.isInput) { + return picker.element; + } + input = picker.element.find('.datepickerinput'); + if (input.size() === 0) { + input = picker.element.find('input'); + } + else if (!input.is('input')) { + throw new Error('CSS class "datepickerinput" cannot be applied to non input element'); + } + return input; + }, + + dataToOptions = function () { + var eData; + if (picker.element.is('input')) { + eData = picker.element.data(); + } + else { + eData = picker.element.find('input').data(); + } + if (eData.dateFormat !== undefined) { + picker.options.format = eData.dateFormat; + } + if (eData.datePickdate !== undefined) { + picker.options.pickDate = eData.datePickdate; + } + if (eData.datePicktime !== undefined) { + picker.options.pickTime = eData.datePicktime; + } + if (eData.dateUseminutes !== undefined) { + picker.options.useMinutes = eData.dateUseminutes; + } + if (eData.dateUseseconds !== undefined) { + picker.options.useSeconds = eData.dateUseseconds; + } + if (eData.dateUsecurrent !== undefined) { + picker.options.useCurrent = eData.dateUsecurrent; + } + if (eData.calendarWeeks !== undefined) { + picker.options.calendarWeeks = eData.calendarWeeks; + } + if (eData.dateMinutestepping !== undefined) { + picker.options.minuteStepping = eData.dateMinutestepping; + } + if (eData.dateMindate !== undefined) { + picker.options.minDate = eData.dateMindate; + } + if (eData.dateMaxdate !== undefined) { + picker.options.maxDate = eData.dateMaxdate; + } + if (eData.dateShowtoday !== undefined) { + picker.options.showToday = eData.dateShowtoday; + } + if (eData.dateCollapse !== undefined) { + picker.options.collapse = eData.dateCollapse; + } + if (eData.dateLanguage !== undefined) { + picker.options.language = eData.dateLanguage; + } + if (eData.dateDefaultdate !== undefined) { + picker.options.defaultDate = eData.dateDefaultdate; + } + if (eData.dateDisableddates !== undefined) { + picker.options.disabledDates = eData.dateDisableddates; + } + if (eData.dateEnableddates !== undefined) { + picker.options.enabledDates = eData.dateEnableddates; + } + if (eData.dateIcons !== undefined) { + picker.options.icons = eData.dateIcons; + } + if (eData.dateUsestrict !== undefined) { + picker.options.useStrict = eData.dateUsestrict; + } + if (eData.dateDirection !== undefined) { + picker.options.direction = eData.dateDirection; + } + if (eData.dateSidebyside !== undefined) { + picker.options.sideBySide = eData.dateSidebyside; + } + if (eData.dateDaysofweekdisabled !== undefined) { + picker.options.daysOfWeekDisabled = eData.dateDaysofweekdisabled; + } +// $.each(defaults, function (key) { +// var attributeName = 'date' + key.charAt(0).toUpperCase() + key.slice(1); +// if (eData[attributeName] !== undefined) { +// picker.options[key] = eData[attributeName]; +// } +// }); + }, + + place = function () { + var position = 'absolute', + offset = picker.component ? picker.component.offset() : picker.element.offset(), + $window = $(window), + placePosition; + + picker.width = picker.component ? picker.component.outerWidth() : picker.element.outerWidth(); + offset.top = offset.top + picker.element.outerHeight(); + + if (picker.options.direction === 'up') { + placePosition = 'top'; + } else if (picker.options.direction === 'bottom') { + placePosition = 'bottom'; + } else if (picker.options.direction === 'auto') { + if (offset.top + picker.widget.height() > $window.height() + $window.scrollTop() && picker.widget.height() + picker.element.outerHeight() < offset.top) { + placePosition = 'top'; + } else { + placePosition = 'bottom'; + } + } + if (placePosition === 'top') { + offset.top -= picker.widget.height() + picker.element.outerHeight() + 15; + picker.widget.addClass('top').removeClass('bottom'); + } else { + offset.top += 1; + picker.widget.addClass('bottom').removeClass('top'); + } + + if (picker.options.width !== undefined) { + picker.widget.width(picker.options.width); + } + + if (picker.options.orientation === 'left') { + picker.widget.addClass('left-oriented'); + offset.left = offset.left - picker.widget.width() + 20; + } + + if (isInFixed()) { + position = 'fixed'; + offset.top -= $window.scrollTop(); + offset.left -= $window.scrollLeft(); + } + + if ($window.width() < offset.left + picker.widget.outerWidth()) { + offset.right = $window.width() - offset.left - picker.width; + offset.left = 'auto'; + picker.widget.addClass('pull-right'); + } else { + offset.right = 'auto'; + picker.widget.removeClass('pull-right'); + } + + picker.widget.css({ + position: position, + top: offset.top, + left: offset.left, + right: offset.right + }); + }, + + notifyChange = function (oldDate, eventType) { + if (moment(picker.date).isSame(moment(oldDate))) { + return; + } + picker.element.trigger({ + type: 'dp.change', + date: moment(picker.date), + oldDate: moment(oldDate) + }); + + if (eventType !== 'change') { + picker.element.change(); + } + }, + + notifyError = function (date) { + picker.element.trigger({ + type: 'dp.error', + date: moment(date, picker.format, picker.options.useStrict) + }); + }, + + update = function (newDate) { + moment.locale(picker.options.language); + var dateStr = newDate; + if (!dateStr) { + dateStr = getPickerInput().val(); + if (dateStr) { + picker.date = moment(dateStr, picker.format, picker.options.useStrict); + } + if (!picker.date) { + picker.date = moment(); + } + } + picker.viewDate = moment(picker.date).startOf('month'); + fillDate(); + fillTime(); + }, + + fillDow = function () { + moment.locale(picker.options.language); + var html = $('<tr>'), weekdaysMin = moment.weekdaysMin(), i; + if (picker.options.calendarWeeks === true) { + html.append('<th class="cw">#</th>'); + } + if (moment().localeData()._week.dow === 0) { // starts on Sunday + for (i = 0; i < 7; i++) { + html.append('<th class="dow">' + weekdaysMin[i] + '</th>'); + } + } else { + for (i = 1; i < 8; i++) { + if (i === 7) { + html.append('<th class="dow">' + weekdaysMin[0] + '</th>'); + } else { + html.append('<th class="dow">' + weekdaysMin[i] + '</th>'); + } + } + } + picker.widget.find('.datepicker-days thead').append(html); + }, + + fillMonths = function () { + moment.locale(picker.options.language); + var html = '', i, monthsShort = moment.monthsShort(); + for (i = 0; i < 12; i++) { + html += '<span class="month">' + monthsShort[i] + '</span>'; + } + picker.widget.find('.datepicker-months td').append(html); + }, + + fillDate = function () { + if (!picker.options.pickDate) { + return; + } + moment.locale(picker.options.language); + var year = picker.viewDate.year(), + month = picker.viewDate.month(), + startYear = picker.options.minDate.year(), + startMonth = picker.options.minDate.month(), + endYear = picker.options.maxDate.year(), + endMonth = picker.options.maxDate.month(), + currentDate, + prevMonth, nextMonth, html = [], row, clsName, i, days, yearCont, currentYear, months = moment.months(); + + picker.widget.find('.datepicker-days').find('.disabled').removeClass('disabled'); + picker.widget.find('.datepicker-months').find('.disabled').removeClass('disabled'); + picker.widget.find('.datepicker-years').find('.disabled').removeClass('disabled'); + + picker.widget.find('.datepicker-days th:eq(1)').text( + months[month] + ' ' + year); + + prevMonth = moment(picker.viewDate, picker.format, picker.options.useStrict).subtract(1, 'months'); + days = prevMonth.daysInMonth(); + prevMonth.date(days).startOf('week'); + if ((year === startYear && month <= startMonth) || year < startYear) { + picker.widget.find('.datepicker-days th:eq(0)').addClass('disabled'); + } + if ((year === endYear && month >= endMonth) || year > endYear) { + picker.widget.find('.datepicker-days th:eq(2)').addClass('disabled'); + } + + nextMonth = moment(prevMonth).add(42, 'd'); + while (prevMonth.isBefore(nextMonth)) { + if (prevMonth.weekday() === moment().startOf('week').weekday()) { + row = $('<tr>'); + html.push(row); + if (picker.options.calendarWeeks === true) { + row.append('<td class="cw">' + prevMonth.week() + '</td>'); + } + } + clsName = ''; + if (prevMonth.year() < year || (prevMonth.year() === year && prevMonth.month() < month)) { + clsName += ' old'; + } else if (prevMonth.year() > year || (prevMonth.year() === year && prevMonth.month() > month)) { + clsName += ' new'; + } + if (prevMonth.isSame(moment({y: picker.date.year(), M: picker.date.month(), d: picker.date.date()}))) { + clsName += ' active'; + } + if (isInDisableDates(prevMonth, 'day') || !isInEnableDates(prevMonth)) { + clsName += ' disabled'; + } + if (picker.options.showToday === true) { + if (prevMonth.isSame(moment(), 'day')) { + clsName += ' today'; + } + } + if (picker.options.daysOfWeekDisabled) { + for (i = 0; i < picker.options.daysOfWeekDisabled.length; i++) { + if (prevMonth.day() === picker.options.daysOfWeekDisabled[i]) { + clsName += ' disabled'; + break; + } + } + } + row.append('<td class="day' + clsName + '">' + prevMonth.date() + '</td>'); + + currentDate = prevMonth.date(); + prevMonth.add(1, 'd'); + + if (currentDate === prevMonth.date()) { + prevMonth.add(1, 'd'); + } + } + picker.widget.find('.datepicker-days tbody').empty().append(html); + currentYear = picker.date.year(); + months = picker.widget.find('.datepicker-months').find('th:eq(1)').text(year).end().find('span').removeClass('active'); + if (currentYear === year) { + months.eq(picker.date.month()).addClass('active'); + } + if (year - 1 < startYear) { + picker.widget.find('.datepicker-months th:eq(0)').addClass('disabled'); + } + if (year + 1 > endYear) { + picker.widget.find('.datepicker-months th:eq(2)').addClass('disabled'); + } + for (i = 0; i < 12; i++) { + if ((year === startYear && startMonth > i) || (year < startYear)) { + $(months[i]).addClass('disabled'); + } else if ((year === endYear && endMonth < i) || (year > endYear)) { + $(months[i]).addClass('disabled'); + } + } + + html = ''; + year = parseInt(year / 10, 10) * 10; + yearCont = picker.widget.find('.datepicker-years').find( + 'th:eq(1)').text(year + '-' + (year + 9)).parents('table').find('td'); + picker.widget.find('.datepicker-years').find('th').removeClass('disabled'); + if (startYear > year) { + picker.widget.find('.datepicker-years').find('th:eq(0)').addClass('disabled'); + } + if (endYear < year + 9) { + picker.widget.find('.datepicker-years').find('th:eq(2)').addClass('disabled'); + } + year -= 1; + for (i = -1; i < 11; i++) { + html += '<span class="year' + (i === -1 || i === 10 ? ' old' : '') + (currentYear === year ? ' active' : '') + ((year < startYear || year > endYear) ? ' disabled' : '') + '">' + year + '</span>'; + year += 1; + } + yearCont.html(html); + }, + + fillHours = function () { + moment.locale(picker.options.language); + var table = picker.widget.find('.timepicker .timepicker-hours table'), html = '', current, i, j; + table.parent().hide(); + if (picker.use24hours) { + current = 0; + for (i = 0; i < 6; i += 1) { + html += '<tr>'; + for (j = 0; j < 4; j += 1) { + html += '<td class="hour">' + padLeft(current.toString()) + '</td>'; + current++; + } + html += '</tr>'; + } + } + else { + current = 1; + for (i = 0; i < 3; i += 1) { + html += '<tr>'; + for (j = 0; j < 4; j += 1) { + html += '<td class="hour">' + padLeft(current.toString()) + '</td>'; + current++; + } + html += '</tr>'; + } + } + table.html(html); + }, + + fillMinutes = function () { + var table = picker.widget.find('.timepicker .timepicker-minutes table'), html = '', current = 0, i, j, step = picker.options.minuteStepping; + table.parent().hide(); + if (step === 1) { + step = 5; + } + for (i = 0; i < Math.ceil(60 / step / 4) ; i++) { + html += '<tr>'; + for (j = 0; j < 4; j += 1) { + if (current < 60) { + html += '<td class="minute">' + padLeft(current.toString()) + '</td>'; + current += step; + } else { + html += '<td></td>'; + } + } + html += '</tr>'; + } + table.html(html); + }, + + fillSeconds = function () { + var table = picker.widget.find('.timepicker .timepicker-seconds table'), html = '', current = 0, i, j; + table.parent().hide(); + for (i = 0; i < 3; i++) { + html += '<tr>'; + for (j = 0; j < 4; j += 1) { + html += '<td class="second">' + padLeft(current.toString()) + '</td>'; + current += 5; + } + html += '</tr>'; + } + table.html(html); + }, + + fillTime = function () { + if (!picker.date) { + return; + } + var timeComponents = picker.widget.find('.timepicker span[data-time-component]'), + hour = picker.date.hours(), + period = picker.date.format('A'); + if (!picker.use24hours) { + if (hour === 0) { + hour = 12; + } else if (hour !== 12) { + hour = hour % 12; + } + picker.widget.find('.timepicker [data-action=togglePeriod]').text(period); + } + timeComponents.filter('[data-time-component=hours]').text(padLeft(hour)); + timeComponents.filter('[data-time-component=minutes]').text(padLeft(picker.date.minutes())); + timeComponents.filter('[data-time-component=seconds]').text(padLeft(picker.date.second())); + }, + + click = function (e) { + e.stopPropagation(); + e.preventDefault(); + picker.unset = false; + var target = $(e.target).closest('span, td, th'), month, year, step, day, oldDate = moment(picker.date); + if (target.length === 1) { + if (!target.is('.disabled')) { + switch (target[0].nodeName.toLowerCase()) { + case 'th': + switch (target[0].className) { + case 'picker-switch': + showMode(1); + break; + case 'prev': + case 'next': + step = dpGlobal.modes[picker.viewMode].navStep; + if (target[0].className === 'prev') { + step = step * -1; + } + picker.viewDate.add(step, dpGlobal.modes[picker.viewMode].navFnc); + fillDate(); + break; + } + break; + case 'span': + if (target.is('.month')) { + month = target.parent().find('span').index(target); + picker.viewDate.month(month); + } else { + year = parseInt(target.text(), 10) || 0; + picker.viewDate.year(year); + } + if (picker.viewMode === picker.minViewMode) { + picker.date = moment({ + y: picker.viewDate.year(), + M: picker.viewDate.month(), + d: picker.viewDate.date(), + h: picker.date.hours(), + m: picker.date.minutes(), + s: picker.date.seconds() + }); + set(); + notifyChange(oldDate, e.type); + } + showMode(-1); + fillDate(); + break; + case 'td': + if (target.is('.day')) { + day = parseInt(target.text(), 10) || 1; + month = picker.viewDate.month(); + year = picker.viewDate.year(); + if (target.is('.old')) { + if (month === 0) { + month = 11; + year -= 1; + } else { + month -= 1; + } + } else if (target.is('.new')) { + if (month === 11) { + month = 0; + year += 1; + } else { + month += 1; + } + } + picker.date = moment({ + y: year, + M: month, + d: day, + h: picker.date.hours(), + m: picker.date.minutes(), + s: picker.date.seconds() + } + ); + picker.viewDate = moment({ + y: year, M: month, d: Math.min(28, day) + }); + fillDate(); + set(); + notifyChange(oldDate, e.type); + } + break; + } + } + } + }, + + actions = { + incrementHours: function () { + checkDate('add', 'hours', 1); + }, + + incrementMinutes: function () { + checkDate('add', 'minutes', picker.options.minuteStepping); + }, + + incrementSeconds: function () { + checkDate('add', 'seconds', 1); + }, + + decrementHours: function () { + checkDate('subtract', 'hours', 1); + }, + + decrementMinutes: function () { + checkDate('subtract', 'minutes', picker.options.minuteStepping); + }, + + decrementSeconds: function () { + checkDate('subtract', 'seconds', 1); + }, + + togglePeriod: function () { + var hour = picker.date.hours(); + if (hour >= 12) { + hour -= 12; + } else { + hour += 12; + } + picker.date.hours(hour); + }, + + showPicker: function () { + picker.widget.find('.timepicker > div:not(.timepicker-picker)').hide(); + picker.widget.find('.timepicker .timepicker-picker').show(); + }, + + showHours: function () { + picker.widget.find('.timepicker .timepicker-picker').hide(); + picker.widget.find('.timepicker .timepicker-hours').show(); + }, + + showMinutes: function () { + picker.widget.find('.timepicker .timepicker-picker').hide(); + picker.widget.find('.timepicker .timepicker-minutes').show(); + }, + + showSeconds: function () { + picker.widget.find('.timepicker .timepicker-picker').hide(); + picker.widget.find('.timepicker .timepicker-seconds').show(); + }, + + selectHour: function (e) { + var hour = parseInt($(e.target).text(), 10); + if (!picker.use24hours) { + if (picker.date.hours() >= 12) { + if (hour !== 12) { + hour += 12; + } + } else { + if (hour === 12) { + hour = 0; + } + } + } + picker.date.hours(hour); + actions.showPicker.call(picker); + }, + + selectMinute: function (e) { + picker.date.minutes(parseInt($(e.target).text(), 10)); + actions.showPicker.call(picker); + }, + + selectSecond: function (e) { + picker.date.seconds(parseInt($(e.target).text(), 10)); + actions.showPicker.call(picker); + } + }, + + doAction = function (e) { + var oldDate = moment(picker.date), + action = $(e.currentTarget).data('action'), + rv = actions[action].apply(picker, arguments); + stopEvent(e); + if (!picker.date) { + picker.date = moment({y: 1970}); + } + set(); + fillTime(); + notifyChange(oldDate, e.type); + return rv; + }, + + stopEvent = function (e) { + e.stopPropagation(); + e.preventDefault(); + }, + + keydown = function (e) { + if (e.keyCode === 27) { // allow escape to hide picker + picker.hide(); + } + }, + + change = function (e) { + moment.locale(picker.options.language); + var input = $(e.target), oldDate = moment(picker.date), newDate = moment(input.val(), picker.format, picker.options.useStrict); + if (newDate.isValid() && !isInDisableDates(newDate) && isInEnableDates(newDate)) { + update(); + picker.setValue(newDate); + notifyChange(oldDate, e.type); + set(); + } + else { + picker.viewDate = oldDate; + picker.unset = true; + notifyChange(oldDate, e.type); + notifyError(newDate); + } + }, + + showMode = function (dir) { + if (dir) { + picker.viewMode = Math.max(picker.minViewMode, Math.min(2, picker.viewMode + dir)); + } + picker.widget.find('.datepicker > div').hide().filter('.datepicker-' + dpGlobal.modes[picker.viewMode].clsName).show(); + }, + + attachDatePickerEvents = function () { + var $this, $parent, expanded, closed, collapseData; + picker.widget.on('click', '.datepicker *', $.proxy(click, this)); // this handles date picker clicks + picker.widget.on('click', '[data-action]', $.proxy(doAction, this)); // this handles time picker clicks + picker.widget.on('mousedown', $.proxy(stopEvent, this)); + picker.element.on('keydown', $.proxy(keydown, this)); + if (picker.options.pickDate && picker.options.pickTime) { + picker.widget.on('click.togglePicker', '.accordion-toggle', function (e) { + e.stopPropagation(); + $this = $(this); + $parent = $this.closest('ul'); + expanded = $parent.find('.in'); + closed = $parent.find('.collapse:not(.in)'); + + if (expanded && expanded.length) { + collapseData = expanded.data('collapse'); + if (collapseData && collapseData.transitioning) { + return; + } + expanded.collapse('hide'); + closed.collapse('show'); + $this.find('span').toggleClass(picker.options.icons.time + ' ' + picker.options.icons.date); + if (picker.component) { + picker.component.find('span').toggleClass(picker.options.icons.time + ' ' + picker.options.icons.date); + } + } + }); + } + if (picker.isInput) { + picker.element.on({ + 'click': $.proxy(picker.show, this), + 'focus': $.proxy(picker.show, this), + 'change': $.proxy(change, this), + 'blur': $.proxy(picker.hide, this) + }); + } else { + picker.element.on({ + 'change': $.proxy(change, this) + }, 'input'); + if (picker.component) { + picker.component.on('click', $.proxy(picker.show, this)); + picker.component.on('mousedown', $.proxy(stopEvent, this)); + } else { + picker.element.on('click', $.proxy(picker.show, this)); + } + } + }, + + attachDatePickerGlobalEvents = function () { + $(window).on( + 'resize.datetimepicker' + picker.id, $.proxy(place, this)); + if (!picker.isInput) { + $(document).on( + 'mousedown.datetimepicker' + picker.id, $.proxy(picker.hide, this)); + } + }, + + detachDatePickerEvents = function () { + picker.widget.off('click', '.datepicker *', picker.click); + picker.widget.off('click', '[data-action]'); + picker.widget.off('mousedown', picker.stopEvent); + if (picker.options.pickDate && picker.options.pickTime) { + picker.widget.off('click.togglePicker'); + } + if (picker.isInput) { + picker.element.off({ + 'focus': picker.show, + 'change': picker.change, + 'click': picker.show, + 'blur' : picker.hide + }); + } else { + picker.element.off({ + 'change': picker.change + }, 'input'); + if (picker.component) { + picker.component.off('click', picker.show); + picker.component.off('mousedown', picker.stopEvent); + } else { + picker.element.off('click', picker.show); + } + } + }, + + detachDatePickerGlobalEvents = function () { + $(window).off('resize.datetimepicker' + picker.id); + if (!picker.isInput) { + $(document).off('mousedown.datetimepicker' + picker.id); + } + }, + + isInFixed = function () { + if (picker.element) { + var parents = picker.element.parents(), inFixed = false, i; + for (i = 0; i < parents.length; i++) { + if ($(parents[i]).css('position') === 'fixed') { + inFixed = true; + break; + } + } + return inFixed; + } else { + return false; + } + }, + + set = function () { + moment.locale(picker.options.language); + var formatted = ''; + if (!picker.unset) { + formatted = moment(picker.date).format(picker.format); + } + getPickerInput().val(formatted); + picker.element.data('date', formatted); + if (!picker.options.pickTime) { + picker.hide(); + } + }, + + checkDate = function (direction, unit, amount) { + moment.locale(picker.options.language); + var newDate; + if (direction === 'add') { + newDate = moment(picker.date); + if (newDate.hours() === 23) { + newDate.add(amount, unit); + } + newDate.add(amount, unit); + } + else { + newDate = moment(picker.date).subtract(amount, unit); + } + if (isInDisableDates(moment(newDate.subtract(amount, unit))) || isInDisableDates(newDate)) { + notifyError(newDate.format(picker.format)); + return; + } + + if (direction === 'add') { + picker.date.add(amount, unit); + } + else { + picker.date.subtract(amount, unit); + } + picker.unset = false; + }, + + isInDisableDates = function (date, timeUnit) { + moment.locale(picker.options.language); + var maxDate = moment(picker.options.maxDate, picker.format, picker.options.useStrict), + minDate = moment(picker.options.minDate, picker.format, picker.options.useStrict); + + if (timeUnit) { + maxDate = maxDate.endOf(timeUnit); + minDate = minDate.startOf(timeUnit); + } + + if (date.isAfter(maxDate) || date.isBefore(minDate)) { + return true; + } + if (picker.options.disabledDates === false) { + return false; + } + return picker.options.disabledDates[date.format('YYYY-MM-DD')] === true; + }, + isInEnableDates = function (date) { + moment.locale(picker.options.language); + if (picker.options.enabledDates === false) { + return true; + } + return picker.options.enabledDates[date.format('YYYY-MM-DD')] === true; + }, + + indexGivenDates = function (givenDatesArray) { + // Store given enabledDates and disabledDates as keys. + // This way we can check their existence in O(1) time instead of looping through whole array. + // (for example: picker.options.enabledDates['2014-02-27'] === true) + var givenDatesIndexed = {}, givenDatesCount = 0, i; + for (i = 0; i < givenDatesArray.length; i++) { + if (moment.isMoment(givenDatesArray[i]) || givenDatesArray[i] instanceof Date) { + dDate = moment(givenDatesArray[i]); + } else { + dDate = moment(givenDatesArray[i], picker.format, picker.options.useStrict); + } + if (dDate.isValid()) { + givenDatesIndexed[dDate.format('YYYY-MM-DD')] = true; + givenDatesCount++; + } + } + if (givenDatesCount > 0) { + return givenDatesIndexed; + } + return false; + }, + + padLeft = function (string) { + string = string.toString(); + if (string.length >= 2) { + return string; + } + return '0' + string; + }, + + getTemplate = function () { + if (picker.options.pickDate && picker.options.pickTime) { + var ret = ''; + ret = '<div class="bootstrap-datetimepicker-widget' + (picker.options.sideBySide ? ' timepicker-sbs' : '') + (picker.use24hours ? ' usetwentyfour' : '') + ' dropdown-menu" style="z-index:9999 !important;">'; + if (picker.options.sideBySide) { + ret += '<div class="row">' + + '<div class="col-sm-6 datepicker">' + dpGlobal.template + '</div>' + + '<div class="col-sm-6 timepicker">' + tpGlobal.getTemplate() + '</div>' + + '</div>'; + } else { + ret += '<ul class="list-unstyled">' + + '<li' + (picker.options.collapse ? ' class="collapse in"' : '') + '>' + + '<div class="datepicker">' + dpGlobal.template + '</div>' + + '</li>' + + '<li class="picker-switch accordion-toggle"><a class="btn" style="width:100%"><span class="' + picker.options.icons.time + '"></span></a></li>' + + '<li' + (picker.options.collapse ? ' class="collapse"' : '') + '>' + + '<div class="timepicker">' + tpGlobal.getTemplate() + '</div>' + + '</li>' + + '</ul>'; + } + ret += '</div>'; + return ret; + } + if (picker.options.pickTime) { + return ( + '<div class="bootstrap-datetimepicker-widget dropdown-menu">' + + '<div class="timepicker">' + tpGlobal.getTemplate() + '</div>' + + '</div>' + ); + } + return ( + '<div class="bootstrap-datetimepicker-widget dropdown-menu">' + + '<div class="datepicker">' + dpGlobal.template + '</div>' + + '</div>' + ); + }, + + dpGlobal = { + modes: [ + { + clsName: 'days', + navFnc: 'month', + navStep: 1 + }, + { + clsName: 'months', + navFnc: 'year', + navStep: 1 + }, + { + clsName: 'years', + navFnc: 'year', + navStep: 10 + } + ], + headTemplate: + '<thead>' + + '<tr>' + + '<th class="prev">‹</th><th colspan="' + (options.calendarWeeks ? '6' : '5') + '" class="picker-switch"></th><th class="next">›</th>' + + '</tr>' + + '</thead>', + contTemplate: + '<tbody><tr><td colspan="' + (options.calendarWeeks ? '8' : '7') + '"></td></tr></tbody>' + }, + + tpGlobal = { + hourTemplate: '<span data-action="showHours" data-time-component="hours" class="timepicker-hour"></span>', + minuteTemplate: '<span data-action="showMinutes" data-time-component="minutes" class="timepicker-minute"></span>', + secondTemplate: '<span data-action="showSeconds" data-time-component="seconds" class="timepicker-second"></span>' + }; + + dpGlobal.template = + '<div class="datepicker-days">' + + '<table class="table-condensed">' + dpGlobal.headTemplate + '<tbody></tbody></table>' + + '</div>' + + '<div class="datepicker-months">' + + '<table class="table-condensed">' + dpGlobal.headTemplate + dpGlobal.contTemplate + '</table>' + + '</div>' + + '<div class="datepicker-years">' + + '<table class="table-condensed">' + dpGlobal.headTemplate + dpGlobal.contTemplate + '</table>' + + '</div>'; + + tpGlobal.getTemplate = function () { + return ( + '<div class="timepicker-picker">' + + '<table class="table-condensed">' + + '<tr>' + + '<td><a href="#" class="btn" data-action="incrementHours"><span class="' + picker.options.icons.up + '"></span></a></td>' + + '<td class="separator"></td>' + + '<td>' + (picker.options.useMinutes ? '<a href="#" class="btn" data-action="incrementMinutes"><span class="' + picker.options.icons.up + '"></span></a>' : '') + '</td>' + + (picker.options.useSeconds ? + '<td class="separator"></td><td><a href="#" class="btn" data-action="incrementSeconds"><span class="' + picker.options.icons.up + '"></span></a></td>' : '') + + (picker.use24hours ? '' : '<td class="separator"></td>') + + '</tr>' + + '<tr>' + + '<td>' + tpGlobal.hourTemplate + '</td> ' + + '<td class="separator">:</td>' + + '<td>' + (picker.options.useMinutes ? tpGlobal.minuteTemplate : '<span class="timepicker-minute">00</span>') + '</td> ' + + (picker.options.useSeconds ? + '<td class="separator">:</td><td>' + tpGlobal.secondTemplate + '</td>' : '') + + (picker.use24hours ? '' : '<td class="separator"></td>' + + '<td><button type="button" class="btn btn-primary" data-action="togglePeriod"></button></td>') + + '</tr>' + + '<tr>' + + '<td><a href="#" class="btn" data-action="decrementHours"><span class="' + picker.options.icons.down + '"></span></a></td>' + + '<td class="separator"></td>' + + '<td>' + (picker.options.useMinutes ? '<a href="#" class="btn" data-action="decrementMinutes"><span class="' + picker.options.icons.down + '"></span></a>' : '') + '</td>' + + (picker.options.useSeconds ? + '<td class="separator"></td><td><a href="#" class="btn" data-action="decrementSeconds"><span class="' + picker.options.icons.down + '"></span></a></td>' : '') + + (picker.use24hours ? '' : '<td class="separator"></td>') + + '</tr>' + + '</table>' + + '</div>' + + '<div class="timepicker-hours" data-action="selectHour">' + + '<table class="table-condensed"></table>' + + '</div>' + + '<div class="timepicker-minutes" data-action="selectMinute">' + + '<table class="table-condensed"></table>' + + '</div>' + + (picker.options.useSeconds ? + '<div class="timepicker-seconds" data-action="selectSecond"><table class="table-condensed"></table></div>' : '') + ); + }; + + picker.destroy = function () { + detachDatePickerEvents(); + detachDatePickerGlobalEvents(); + picker.widget.remove(); + picker.element.removeData('DateTimePicker'); + if (picker.component) { + picker.component.removeData('DateTimePicker'); + } + }; + + picker.show = function (e) { + if (picker.options.useCurrent) { + if (getPickerInput().val() === '') { + if (picker.options.minuteStepping !== 1) { + var mDate = moment(), + rInterval = picker.options.minuteStepping; + mDate.minutes((Math.round(mDate.minutes() / rInterval) * rInterval) % 60).seconds(0); + picker.setValue(mDate.format(picker.format)); + } else { + picker.setValue(moment().format(picker.format)); + } + notifyChange('', e.type); + } + } + // if this is a click event on the input field and picker is already open don't hide it + if (e && e.type === 'click' && picker.isInput && picker.widget.hasClass('picker-open')) { + return; + } + if (picker.widget.hasClass('picker-open')) { + picker.widget.hide(); + picker.widget.removeClass('picker-open'); + } + else { + picker.widget.show(); + picker.widget.addClass('picker-open'); + } + picker.height = picker.component ? picker.component.outerHeight() : picker.element.outerHeight(); + place(); + picker.element.trigger({ + type: 'dp.show', + date: moment(picker.date) + }); + attachDatePickerGlobalEvents(); + if (e) { + stopEvent(e); + } + }; + + picker.disable = function () { + var input = picker.element.find('input'); + if (input.prop('disabled')) { + return; + } + input.prop('disabled', true); + detachDatePickerEvents(); + }; + + picker.enable = function () { + var input = picker.element.find('input'); + if (!input.prop('disabled')) { + return; + } + input.prop('disabled', false); + attachDatePickerEvents(); + }; + + picker.hide = function () { + // Ignore event if in the middle of a picker transition + var collapse = picker.widget.find('.collapse'), i, collapseData; + for (i = 0; i < collapse.length; i++) { + collapseData = collapse.eq(i).data('collapse'); + if (collapseData && collapseData.transitioning) { + return; + } + } + picker.widget.hide(); + picker.widget.removeClass('picker-open'); + picker.viewMode = picker.startViewMode; + showMode(); + picker.element.trigger({ + type: 'dp.hide', + date: moment(picker.date) + }); + detachDatePickerGlobalEvents(); + }; + + picker.setValue = function (newDate) { + moment.locale(picker.options.language); + if (!newDate) { + picker.unset = true; + set(); + } else { + picker.unset = false; + } + if (!moment.isMoment(newDate)) { + newDate = (newDate instanceof Date) ? moment(newDate) : moment(newDate, picker.format, picker.options.useStrict); + } else { + newDate = newDate.locale(picker.options.language); + } + if (newDate.isValid()) { + picker.date = newDate; + set(); + picker.viewDate = moment({y: picker.date.year(), M: picker.date.month()}); + fillDate(); + fillTime(); + } + else { + notifyError(newDate); + } + }; + + picker.getDate = function () { + if (picker.unset) { + return null; + } + return moment(picker.date); + }; + + picker.setDate = function (date) { + var oldDate = moment(picker.date); + if (!date) { + picker.setValue(null); + } else { + picker.setValue(date); + } + notifyChange(oldDate, 'function'); + }; + + picker.setDisabledDates = function (dates) { + picker.options.disabledDates = indexGivenDates(dates); + if (picker.viewDate) { + update(); + } + }; + + picker.setEnabledDates = function (dates) { + picker.options.enabledDates = indexGivenDates(dates); + if (picker.viewDate) { + update(); + } + }; + + picker.setMaxDate = function (date) { + if (date === undefined) { + return; + } + if (moment.isMoment(date) || date instanceof Date) { + picker.options.maxDate = moment(date); + } else { + picker.options.maxDate = moment(date, picker.format, picker.options.useStrict); + } + if (picker.viewDate) { + update(); + } + }; + + picker.setMinDate = function (date) { + if (date === undefined) { + return; + } + if (moment.isMoment(date) || date instanceof Date) { + picker.options.minDate = moment(date); + } else { + picker.options.minDate = moment(date, picker.format, picker.options.useStrict); + } + if (picker.viewDate) { + update(); + } + }; + + init(); + }; + + $.fn.datetimepicker = function (options) { + return this.each(function () { + var $this = $(this), + data = $this.data('DateTimePicker'); + if (!data) { + $this.data('DateTimePicker', new DateTimePicker(this, options)); + } + }); + }; + + $.fn.datetimepicker.defaults = { + format: false, + pickDate: true, + pickTime: true, + useMinutes: true, + useSeconds: false, + useCurrent: true, + calendarWeeks: false, + minuteStepping: 1, + minDate: moment({y: 1900}), + maxDate: moment().add(100, 'y'), + showToday: true, + collapse: true, + language: moment.locale(), + defaultDate: '', + disabledDates: false, + enabledDates: false, + icons: {}, + useStrict: false, + direction: 'auto', + sideBySide: false, + daysOfWeekDisabled: [], + widgetParent: false + }; +})); diff --git a/addons/web/static/lib/bootstrap-datetimepicker/src/less/bootstrap-datetimepicker-build.less b/addons/web/static/lib/bootstrap-datetimepicker/src/less/bootstrap-datetimepicker-build.less new file mode 100644 index 00000000000..4a17370153b --- /dev/null +++ b/addons/web/static/lib/bootstrap-datetimepicker/src/less/bootstrap-datetimepicker-build.less @@ -0,0 +1,5 @@ +// Import boostrap variables including default color palette and fonts +@import "../../node_modules/bootstrap/less/variables.less"; + +// Import datepicker component +@import "bootstrap-datetimepicker.less"; diff --git a/addons/web/static/lib/bootstrap-datetimepicker/src/less/bootstrap-datetimepicker.less b/addons/web/static/lib/bootstrap-datetimepicker/src/less/bootstrap-datetimepicker.less new file mode 100755 index 00000000000..49fbc15d300 --- /dev/null +++ b/addons/web/static/lib/bootstrap-datetimepicker/src/less/bootstrap-datetimepicker.less @@ -0,0 +1,290 @@ +/*! + * Datetimepicker for Bootstrap v3 +//! version : 3.0.3 + * https://github.com/Eonasdan/bootstrap-datetimepicker/ + */ +.bootstrap-datetimepicker-widget { + top: 0; + left: 0; + width: 250px; + padding: 4px; + margin-top: 1px; + z-index: 99999 !important; + border-radius: @border-radius-base; + + &.timepicker-sbs { + width: 600px; + } + + &.bottom { + &:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0,0,0,.2); + position: absolute; + top: -7px; + left: 7px; + } + + &:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid white; + position: absolute; + top: -6px; + left: 8px; + } + } + + &.top { + &:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-top: 7px solid #ccc; + border-top-color: rgba(0,0,0,.2); + position: absolute; + bottom: -7px; + left: 6px; + } + + &:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-top: 6px solid white; + position: absolute; + bottom: -6px; + left: 7px; + } + } + + & .dow { + width: 14.2857%; + } + + &.pull-right { + &:before { + left: auto; + right: 6px; + } + + &:after { + left: auto; + right: 7px; + } + } + + >ul { + list-style-type: none; + margin: 0; + } + + a[data-action] { + padding: 6px 0; + } + + .timepicker-hour, .timepicker-minute, .timepicker-second { + width: 54px; + font-weight: bold; + font-size: 1.2em; + margin: 0; + } + + button[data-action] { + padding: 6px; + } + + table[data-hour-format="12"] .separator { + width: 4px; + padding: 0; + margin: 0; + } + + .datepicker > div { + display: none; + } + + .picker-switch { + text-align: center; + } + + table { + width: 100%; + margin: 0; + } + + td, + th { + text-align: center; + border-radius: @border-radius-base; + } + + td { + height: 54px; + line-height: 54px; + width: 54px; + + &.cw + { + font-size: 10px; + height: 20px; + line-height: 20px; + color: @gray-light; + } + + &.day + { + height: 20px; + line-height: 20px; + width: 20px; + } + + &.day:hover, + &.hour:hover, + &.minute:hover, + &.second:hover { + background: @gray-lighter; + cursor: pointer; + } + + &.old, + &.new { + color: @gray-light; + } + + &.today { + position: relative; + + &:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-bottom: 7px solid @btn-primary-bg; + border-top-color: rgba(0, 0, 0, 0.2); + position: absolute; + bottom: 4px; + right: 4px; + } + } + + &.active, + &.active:hover { + background-color: @btn-primary-bg; + color: #fff; + text-shadow: 0 -1px 0 rgba(0,0,0,.25); + } + + &.active.today:before { + border-bottom-color: #fff; + } + + &.disabled, + &.disabled:hover { + background: none; + color: @gray-light; + cursor: not-allowed; + } + + span { + display: inline-block; + width: 54px; + height: 54px; + line-height: 54px; + margin: 2px 1.5px; + cursor: pointer; + border-radius: @border-radius-base; + + &:hover { + background: @gray-lighter; + } + + &.active { + background-color: @btn-primary-bg; + color: #fff; + text-shadow: 0 -1px 0 rgba(0,0,0,.25); + } + + &.old { + color: @gray-light; + } + + &.disabled, + &.disabled:hover { + background: none; + color: @gray-light; + cursor: not-allowed; + } + } + } + + th { + height: 20px; + line-height: 20px; + width: 20px; + + &.picker-switch { + width: 145px; + } + + &.next, + &.prev { + font-size: @font-size-base * 1.5; + } + + &.disabled, + &.disabled:hover { + background: none; + color: @gray-light; + cursor: not-allowed; + } + } + + thead tr:first-child th { + cursor: pointer; + + &:hover { + background: @gray-lighter; + } + } +} + +.input-group { + &.date { + .input-group-addon span { + display: block; + cursor: pointer; + width: 16px; + height: 16px; + } + } +} + +.bootstrap-datetimepicker-widget.left-oriented { + &:before { + left: auto; + right: 6px; + } + + &:after { + left: auto; + right: 7px; + } +} + +.bootstrap-datetimepicker-widget ul.list-unstyled li div.timepicker div.timepicker-picker table.table-condensed tbody > tr > td { + padding: 0px !important; +} + +@media screen and (max-width: 767px) { + .bootstrap-datetimepicker-widget.timepicker-sbs { + width: 283px; + } +} diff --git a/addons/web/static/lib/jquery.ui.timepicker/css/jquery-ui-timepicker-addon.css b/addons/web/static/lib/jquery.ui.timepicker/css/jquery-ui-timepicker-addon.css deleted file mode 100644 index e0d03c290af..00000000000 --- a/addons/web/static/lib/jquery.ui.timepicker/css/jquery-ui-timepicker-addon.css +++ /dev/null @@ -1,6 +0,0 @@ -.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; } -.ui-timepicker-div dl { text-align: left; } -.ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; } -.ui-timepicker-div dl dd { margin: 0 10px 10px 65px; } -.ui-timepicker-div td { font-size: 90%; } -.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; } diff --git a/addons/web/static/lib/jquery.ui.timepicker/js/jquery-ui-timepicker-addon.js b/addons/web/static/lib/jquery.ui.timepicker/js/jquery-ui-timepicker-addon.js deleted file mode 100644 index 84888dbaaec..00000000000 --- a/addons/web/static/lib/jquery.ui.timepicker/js/jquery-ui-timepicker-addon.js +++ /dev/null @@ -1,1326 +0,0 @@ -/* -* jQuery timepicker addon -* By: Trent Richardson [http://trentrichardson.com] -* Version 0.9.9 -* Last Modified: 02/05/2012 -* -* Copyright 2012 Trent Richardson -* Dual licensed under the MIT and GPL licenses. -* http://trentrichardson.com/Impromptu/GPL-LICENSE.txt -* http://trentrichardson.com/Impromptu/MIT-LICENSE.txt -* -* HERES THE CSS: -* .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; } -* .ui-timepicker-div dl { text-align: left; } -* .ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; } -* .ui-timepicker-div dl dd { margin: 0 10px 10px 65px; } -* .ui-timepicker-div td { font-size: 90%; } -* .ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; } -*/ - -(function($) { - -$.extend($.ui, { timepicker: { version: "0.9.9" } }); - -/* Time picker manager. - Use the singleton instance of this class, $.timepicker, to interact with the time picker. - Settings for (groups of) time pickers are maintained in an instance object, - allowing multiple different settings on the same page. */ - -function Timepicker() { - this.regional = []; // Available regional settings, indexed by language code - this.regional[''] = { // Default regional settings - currentText: 'Now', - closeText: 'Done', - ampm: false, - amNames: ['AM', 'A'], - pmNames: ['PM', 'P'], - timeFormat: 'hh:mm tt', - timeSuffix: '', - timeOnlyTitle: 'Choose Time', - timeText: 'Time', - hourText: 'Hour', - minuteText: 'Minute', - secondText: 'Second', - millisecText: 'Millisecond', - timezoneText: 'Time Zone' - }; - this._defaults = { // Global defaults for all the datetime picker instances - showButtonPanel: true, - timeOnly: false, - showHour: true, - showMinute: true, - showSecond: false, - showMillisec: false, - showTimezone: false, - showTime: true, - stepHour: 1, - stepMinute: 1, - stepSecond: 1, - stepMillisec: 1, - hour: 0, - minute: 0, - second: 0, - millisec: 0, - timezone: '+0000', - hourMin: 0, - minuteMin: 0, - secondMin: 0, - millisecMin: 0, - hourMax: 23, - minuteMax: 59, - secondMax: 59, - millisecMax: 999, - minDateTime: null, - maxDateTime: null, - onSelect: null, - hourGrid: 0, - minuteGrid: 0, - secondGrid: 0, - millisecGrid: 0, - alwaysSetTime: true, - separator: ' ', - altFieldTimeOnly: true, - showTimepicker: true, - timezoneIso8609: false, - timezoneList: null, - addSliderAccess: false, - sliderAccessArgs: null - }; - $.extend(this._defaults, this.regional['']); -}; - -$.extend(Timepicker.prototype, { - $input: null, - $altInput: null, - $timeObj: null, - inst: null, - hour_slider: null, - minute_slider: null, - second_slider: null, - millisec_slider: null, - timezone_select: null, - hour: 0, - minute: 0, - second: 0, - millisec: 0, - timezone: '+0000', - hourMinOriginal: null, - minuteMinOriginal: null, - secondMinOriginal: null, - millisecMinOriginal: null, - hourMaxOriginal: null, - minuteMaxOriginal: null, - secondMaxOriginal: null, - millisecMaxOriginal: null, - ampm: '', - formattedDate: '', - formattedTime: '', - formattedDateTime: '', - timezoneList: null, - - /* Override the default settings for all instances of the time picker. - @param settings object - the new settings to use as defaults (anonymous object) - @return the manager object */ - setDefaults: function(settings) { - extendRemove(this._defaults, settings || {}); - return this; - }, - - //######################################################################## - // Create a new Timepicker instance - //######################################################################## - _newInst: function($input, o) { - var tp_inst = new Timepicker(), - inlineSettings = {}; - - for (var attrName in this._defaults) { - var attrValue = $input.attr('time:' + attrName); - if (attrValue) { - try { - inlineSettings[attrName] = eval(attrValue); - } catch (err) { - inlineSettings[attrName] = attrValue; - } - } - } - tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, { - beforeShow: function(input, dp_inst) { - if ($.isFunction(o.beforeShow)) - return o.beforeShow(input, dp_inst, tp_inst); - }, - onChangeMonthYear: function(year, month, dp_inst) { - // Update the time as well : this prevents the time from disappearing from the $input field. - tp_inst._updateDateTime(dp_inst); - if ($.isFunction(o.onChangeMonthYear)) - o.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst); - }, - onClose: function(dateText, dp_inst) { - if (tp_inst.timeDefined === true && $input.val() != '') - tp_inst._updateDateTime(dp_inst); - if ($.isFunction(o.onClose)) - o.onClose.call($input[0], dateText, dp_inst, tp_inst); - }, - timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); - }); - tp_inst.amNames = $.map(tp_inst._defaults.amNames, function(val) { return val.toUpperCase() }); - tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function(val) { return val.toUpperCase() }); - - if (tp_inst._defaults.timezoneList === null) { - var timezoneList = []; - for (var i = -11; i <= 12; i++) - timezoneList.push((i >= 0 ? '+' : '-') + ('0' + Math.abs(i).toString()).slice(-2) + '00'); - if (tp_inst._defaults.timezoneIso8609) - timezoneList = $.map(timezoneList, function(val) { - return val == '+0000' ? 'Z' : (val.substring(0, 3) + ':' + val.substring(3)); - }); - tp_inst._defaults.timezoneList = timezoneList; - } - - tp_inst.hour = tp_inst._defaults.hour; - tp_inst.minute = tp_inst._defaults.minute; - tp_inst.second = tp_inst._defaults.second; - tp_inst.millisec = tp_inst._defaults.millisec; - tp_inst.ampm = ''; - tp_inst.$input = $input; - - if (o.altField) - tp_inst.$altInput = $(o.altField) - .css({ cursor: 'pointer' }) - .focus(function(){ $input.trigger("focus"); }); - - if(tp_inst._defaults.minDate==0 || tp_inst._defaults.minDateTime==0) - { - tp_inst._defaults.minDate=new Date(); - } - if(tp_inst._defaults.maxDate==0 || tp_inst._defaults.maxDateTime==0) - { - tp_inst._defaults.maxDate=new Date(); - } - - // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. - if(tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) - tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); - if(tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) - tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); - if(tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) - tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); - if(tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) - tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); - return tp_inst; - }, - - //######################################################################## - // add our sliders to the calendar - //######################################################################## - _addTimePicker: function(dp_inst) { - var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? - this.$input.val() + ' ' + this.$altInput.val() : - this.$input.val(); - - this.timeDefined = this._parseTime(currDT); - this._limitMinMaxDateTime(dp_inst, false); - this._injectTimePicker(); - }, - - //######################################################################## - // parse the time string from input value or _setTime - //######################################################################## - _parseTime: function(timeString, withDate) { - var regstr = this._defaults.timeFormat.toString() - .replace(/h{1,2}/ig, '(\\d?\\d)') - .replace(/m{1,2}/ig, '(\\d?\\d)') - .replace(/s{1,2}/ig, '(\\d?\\d)') - .replace(/l{1}/ig, '(\\d?\\d?\\d)') - .replace(/t{1,2}/ig, this._getPatternAmpm()) - .replace(/z{1}/ig, '(z|[-+]\\d\\d:?\\d\\d)?') - .replace(/\s/g, '\\s?') + this._defaults.timeSuffix + '$', - order = this._getFormatPositions(), - ampm = '', - treg; - - if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]); - - if (withDate || !this._defaults.timeOnly) { - // the time should come after x number of characters and a space. - // x = at least the length of text specified by the date format - var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat'); - // escape special regex characters in the seperator - var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); - regstr = '^.{' + dp_dateFormat.length + ',}?' + this._defaults.separator.replace(specials, "\\$&") + regstr; - } - - treg = timeString.match(new RegExp(regstr, 'i')); - - if (treg) { - if (order.t !== -1) { - if (treg[order.t] === undefined || treg[order.t].length === 0) { - ampm = ''; - this.ampm = ''; - } else { - ampm = $.inArray(treg[order.t].toUpperCase(), this.amNames) !== -1 ? 'AM' : 'PM'; - this.ampm = this._defaults[ampm == 'AM' ? 'amNames' : 'pmNames'][0]; - } - } - - if (order.h !== -1) { - if (ampm == 'AM' && treg[order.h] == '12') - this.hour = 0; // 12am = 0 hour - else if (ampm == 'PM' && treg[order.h] != '12') - this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12 - else this.hour = Number(treg[order.h]); - } - - if (order.m !== -1) this.minute = Number(treg[order.m]); - if (order.s !== -1) this.second = Number(treg[order.s]); - if (order.l !== -1) this.millisec = Number(treg[order.l]); - if (order.z !== -1 && treg[order.z] !== undefined) { - var tz = treg[order.z].toUpperCase(); - switch (tz.length) { - case 1: // Z - tz = this._defaults.timezoneIso8609 ? 'Z' : '+0000'; - break; - case 5: // +hhmm - if (this._defaults.timezoneIso8609) - tz = tz.substring(1) == '0000' - ? 'Z' - : tz.substring(0, 3) + ':' + tz.substring(3); - break; - case 6: // +hh:mm - if (!this._defaults.timezoneIso8609) - tz = tz == 'Z' || tz.substring(1) == '00:00' - ? '+0000' - : tz.replace(/:/, ''); - else if (tz.substring(1) == '00:00') - tz = 'Z'; - break; - } - this.timezone = tz; - } - - return true; - - } - return false; - }, - - //######################################################################## - // pattern for standard and localized AM/PM markers - //######################################################################## - _getPatternAmpm: function() { - var markers = []; - o = this._defaults; - if (o.amNames) - $.merge(markers, o.amNames); - if (o.pmNames) - $.merge(markers, o.pmNames); - markers = $.map(markers, function(val) { return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&') }); - return '(' + markers.join('|') + ')?'; - }, - - //######################################################################## - // figure out position of time elements.. cause js cant do named captures - //######################################################################## - _getFormatPositions: function() { - var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|t{1,2}|z)/g), - orders = { h: -1, m: -1, s: -1, l: -1, t: -1, z: -1 }; - - if (finds) - for (var i = 0; i < finds.length; i++) - if (orders[finds[i].toString().charAt(0)] == -1) - orders[finds[i].toString().charAt(0)] = i + 1; - - return orders; - }, - - //######################################################################## - // generate and inject html for timepicker into ui datepicker - //######################################################################## - _injectTimePicker: function() { - var $dp = this.inst.dpDiv, - o = this._defaults, - tp_inst = this, - // Added by Peter Medeiros: - // - Figure out what the hour/minute/second max should be based on the step values. - // - Example: if stepMinute is 15, then minMax is 45. - hourMax = parseInt((o.hourMax - ((o.hourMax - o.hourMin) % o.stepHour)) ,10), - minMax = parseInt((o.minuteMax - ((o.minuteMax - o.minuteMin) % o.stepMinute)) ,10), - secMax = parseInt((o.secondMax - ((o.secondMax - o.secondMin) % o.stepSecond)) ,10), - millisecMax = parseInt((o.millisecMax - ((o.millisecMax - o.millisecMin) % o.stepMillisec)) ,10), - dp_id = this.inst.id.toString().replace(/([^A-Za-z0-9_])/g, ''); - - // Prevent displaying twice - //if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0) { - if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0 && o.showTimepicker) { - var noDisplay = ' style="display:none;"', - html = '<div class="ui-timepicker-div" id="ui-timepicker-div-' + dp_id + '"><dl>' + - '<dt class="ui_tpicker_time_label" id="ui_tpicker_time_label_' + dp_id + '"' + - ((o.showTime) ? '' : noDisplay) + '>' + o.timeText + '</dt>' + - '<dd class="ui_tpicker_time" id="ui_tpicker_time_' + dp_id + '"' + - ((o.showTime) ? '' : noDisplay) + '></dd>' + - '<dt class="ui_tpicker_hour_label" id="ui_tpicker_hour_label_' + dp_id + '"' + - ((o.showHour) ? '' : noDisplay) + '>' + o.hourText + '</dt>', - hourGridSize = 0, - minuteGridSize = 0, - secondGridSize = 0, - millisecGridSize = 0, - size; - - // Hours - html += '<dd class="ui_tpicker_hour"><div id="ui_tpicker_hour_' + dp_id + '"' + - ((o.showHour) ? '' : noDisplay) + '></div>'; - if (o.showHour && o.hourGrid > 0) { - html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>'; - - for (var h = o.hourMin; h <= hourMax; h += parseInt(o.hourGrid,10)) { - hourGridSize++; - var tmph = (o.ampm && h > 12) ? h-12 : h; - if (tmph < 10) tmph = '0' + tmph; - if (o.ampm) { - if (h == 0) tmph = 12 +'a'; - else if (h < 12) tmph += 'a'; - else tmph += 'p'; - } - html += '<td>' + tmph + '</td>'; - } - - html += '</tr></table></div>'; - } - html += '</dd>'; - - // Minutes - html += '<dt class="ui_tpicker_minute_label" id="ui_tpicker_minute_label_' + dp_id + '"' + - ((o.showMinute) ? '' : noDisplay) + '>' + o.minuteText + '</dt>'+ - '<dd class="ui_tpicker_minute"><div id="ui_tpicker_minute_' + dp_id + '"' + - ((o.showMinute) ? '' : noDisplay) + '></div>'; - - if (o.showMinute && o.minuteGrid > 0) { - html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>'; - - for (var m = o.minuteMin; m <= minMax; m += parseInt(o.minuteGrid,10)) { - minuteGridSize++; - html += '<td>' + ((m < 10) ? '0' : '') + m + '</td>'; - } - - html += '</tr></table></div>'; - } - html += '</dd>'; - - // Seconds - html += '<dt class="ui_tpicker_second_label" id="ui_tpicker_second_label_' + dp_id + '"' + - ((o.showSecond) ? '' : noDisplay) + '>' + o.secondText + '</dt>'+ - '<dd class="ui_tpicker_second"><div id="ui_tpicker_second_' + dp_id + '"'+ - ((o.showSecond) ? '' : noDisplay) + '></div>'; - - if (o.showSecond && o.secondGrid > 0) { - html += '<div style="padding-left: 1px"><table><tr>'; - - for (var s = o.secondMin; s <= secMax; s += parseInt(o.secondGrid,10)) { - secondGridSize++; - html += '<td>' + ((s < 10) ? '0' : '') + s + '</td>'; - } - - html += '</tr></table></div>'; - } - html += '</dd>'; - - // Milliseconds - html += '<dt class="ui_tpicker_millisec_label" id="ui_tpicker_millisec_label_' + dp_id + '"' + - ((o.showMillisec) ? '' : noDisplay) + '>' + o.millisecText + '</dt>'+ - '<dd class="ui_tpicker_millisec"><div id="ui_tpicker_millisec_' + dp_id + '"'+ - ((o.showMillisec) ? '' : noDisplay) + '></div>'; - - if (o.showMillisec && o.millisecGrid > 0) { - html += '<div style="padding-left: 1px"><table><tr>'; - - for (var l = o.millisecMin; l <= millisecMax; l += parseInt(o.millisecGrid,10)) { - millisecGridSize++; - html += '<td>' + ((l < 10) ? '0' : '') + l + '</td>'; - } - - html += '</tr></table></div>'; - } - html += '</dd>'; - - // Timezone - html += '<dt class="ui_tpicker_timezone_label" id="ui_tpicker_timezone_label_' + dp_id + '"' + - ((o.showTimezone) ? '' : noDisplay) + '>' + o.timezoneText + '</dt>'; - html += '<dd class="ui_tpicker_timezone" id="ui_tpicker_timezone_' + dp_id + '"' + - ((o.showTimezone) ? '' : noDisplay) + '></dd>'; - - html += '</dl></div>'; - $tp = $(html); - - // if we only want time picker... - if (o.timeOnly === true) { - $tp.prepend( - '<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' + - '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' + - '</div>'); - $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); - } - - this.hour_slider = $tp.find('#ui_tpicker_hour_'+ dp_id).slider({ - orientation: "horizontal", - value: this.hour, - min: o.hourMin, - max: hourMax, - step: o.stepHour, - slide: function(event, ui) { - tp_inst.hour_slider.slider( "option", "value", ui.value); - tp_inst._onTimeChange(); - } - }); - - - // Updated by Peter Medeiros: - // - Pass in Event and UI instance into slide function - this.minute_slider = $tp.find('#ui_tpicker_minute_'+ dp_id).slider({ - orientation: "horizontal", - value: this.minute, - min: o.minuteMin, - max: minMax, - step: o.stepMinute, - slide: function(event, ui) { - tp_inst.minute_slider.slider( "option", "value", ui.value); - tp_inst._onTimeChange(); - } - }); - - this.second_slider = $tp.find('#ui_tpicker_second_'+ dp_id).slider({ - orientation: "horizontal", - value: this.second, - min: o.secondMin, - max: secMax, - step: o.stepSecond, - slide: function(event, ui) { - tp_inst.second_slider.slider( "option", "value", ui.value); - tp_inst._onTimeChange(); - } - }); - - this.millisec_slider = $tp.find('#ui_tpicker_millisec_'+ dp_id).slider({ - orientation: "horizontal", - value: this.millisec, - min: o.millisecMin, - max: millisecMax, - step: o.stepMillisec, - slide: function(event, ui) { - tp_inst.millisec_slider.slider( "option", "value", ui.value); - tp_inst._onTimeChange(); - } - }); - - this.timezone_select = $tp.find('#ui_tpicker_timezone_'+ dp_id).append('<select></select>').find("select"); - $.fn.append.apply(this.timezone_select, - $.map(o.timezoneList, function(val, idx) { - return $("<option />") - .val(typeof val == "object" ? val.value : val) - .text(typeof val == "object" ? val.label : val); - }) - ); - this.timezone_select.val((typeof this.timezone != "undefined" && this.timezone != null && this.timezone != "") ? this.timezone : o.timezone); - this.timezone_select.change(function() { - tp_inst._onTimeChange(); - }); - - // Add grid functionality - if (o.showHour && o.hourGrid > 0) { - size = 100 * hourGridSize * o.hourGrid / (hourMax - o.hourMin); - - $tp.find(".ui_tpicker_hour table").css({ - width: size + "%", - marginLeft: (size / (-2 * hourGridSize)) + "%", - borderCollapse: 'collapse' - }).find("td").each( function(index) { - $(this).click(function() { - var h = $(this).html(); - if(o.ampm) { - var ap = h.substring(2).toLowerCase(), - aph = parseInt(h.substring(0,2), 10); - if (ap == 'a') { - if (aph == 12) h = 0; - else h = aph; - } else if (aph == 12) h = 12; - else h = aph + 12; - } - tp_inst.hour_slider.slider("option", "value", h); - tp_inst._onTimeChange(); - tp_inst._onSelectHandler(); - }).css({ - cursor: 'pointer', - width: (100 / hourGridSize) + '%', - textAlign: 'center', - overflow: 'hidden' - }); - }); - } - - if (o.showMinute && o.minuteGrid > 0) { - size = 100 * minuteGridSize * o.minuteGrid / (minMax - o.minuteMin); - $tp.find(".ui_tpicker_minute table").css({ - width: size + "%", - marginLeft: (size / (-2 * minuteGridSize)) + "%", - borderCollapse: 'collapse' - }).find("td").each(function(index) { - $(this).click(function() { - tp_inst.minute_slider.slider("option", "value", $(this).html()); - tp_inst._onTimeChange(); - tp_inst._onSelectHandler(); - }).css({ - cursor: 'pointer', - width: (100 / minuteGridSize) + '%', - textAlign: 'center', - overflow: 'hidden' - }); - }); - } - - if (o.showSecond && o.secondGrid > 0) { - $tp.find(".ui_tpicker_second table").css({ - width: size + "%", - marginLeft: (size / (-2 * secondGridSize)) + "%", - borderCollapse: 'collapse' - }).find("td").each(function(index) { - $(this).click(function() { - tp_inst.second_slider.slider("option", "value", $(this).html()); - tp_inst._onTimeChange(); - tp_inst._onSelectHandler(); - }).css({ - cursor: 'pointer', - width: (100 / secondGridSize) + '%', - textAlign: 'center', - overflow: 'hidden' - }); - }); - } - - if (o.showMillisec && o.millisecGrid > 0) { - $tp.find(".ui_tpicker_millisec table").css({ - width: size + "%", - marginLeft: (size / (-2 * millisecGridSize)) + "%", - borderCollapse: 'collapse' - }).find("td").each(function(index) { - $(this).click(function() { - tp_inst.millisec_slider.slider("option", "value", $(this).html()); - tp_inst._onTimeChange(); - tp_inst._onSelectHandler(); - }).css({ - cursor: 'pointer', - width: (100 / millisecGridSize) + '%', - textAlign: 'center', - overflow: 'hidden' - }); - }); - } - - var $buttonPanel = $dp.find('.ui-datepicker-buttonpane'); - if ($buttonPanel.length) $buttonPanel.before($tp); - else $dp.append($tp); - - this.$timeObj = $tp.find('#ui_tpicker_time_'+ dp_id); - - if (this.inst !== null) { - var timeDefined = this.timeDefined; - this._onTimeChange(); - this.timeDefined = timeDefined; - } - - //Emulate datepicker onSelect behavior. Call on slidestop. - var onSelectDelegate = function() { - tp_inst._onSelectHandler(); - }; - this.hour_slider.bind('slidestop',onSelectDelegate); - this.minute_slider.bind('slidestop',onSelectDelegate); - this.second_slider.bind('slidestop',onSelectDelegate); - this.millisec_slider.bind('slidestop',onSelectDelegate); - - // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/ - if (this._defaults.addSliderAccess){ - var sliderAccessArgs = this._defaults.sliderAccessArgs; - setTimeout(function(){ // fix for inline mode - if($tp.find('.ui-slider-access').length == 0){ - $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs); - - // fix any grids since sliders are shorter - var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true); - if(sliderAccessWidth){ - $tp.find('table:visible').each(function(){ - var $g = $(this), - oldWidth = $g.outerWidth(), - oldMarginLeft = $g.css('marginLeft').toString().replace('%',''), - newWidth = oldWidth - sliderAccessWidth, - newMarginLeft = ((oldMarginLeft * newWidth)/oldWidth) + '%'; - - $g.css({ width: newWidth, marginLeft: newMarginLeft }); - }); - } - } - },0); - } - // end slideAccess integration - - } - }, - - //######################################################################## - // This function tries to limit the ability to go outside the - // min/max date range - //######################################################################## - _limitMinMaxDateTime: function(dp_inst, adjustSliders){ - var o = this._defaults, - dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay); - - if(!this._defaults.showTimepicker) return; // No time so nothing to check here - - if($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date){ - var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'), - minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0); - - if(this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null){ - this.hourMinOriginal = o.hourMin; - this.minuteMinOriginal = o.minuteMin; - this.secondMinOriginal = o.secondMin; - this.millisecMinOriginal = o.millisecMin; - } - - if(dp_inst.settings.timeOnly || minDateTimeDate.getTime() == dp_date.getTime()) { - this._defaults.hourMin = minDateTime.getHours(); - if (this.hour <= this._defaults.hourMin) { - this.hour = this._defaults.hourMin; - this._defaults.minuteMin = minDateTime.getMinutes(); - if (this.minute <= this._defaults.minuteMin) { - this.minute = this._defaults.minuteMin; - this._defaults.secondMin = minDateTime.getSeconds(); - } else if (this.second <= this._defaults.secondMin){ - this.second = this._defaults.secondMin; - this._defaults.millisecMin = minDateTime.getMilliseconds(); - } else { - if(this.millisec < this._defaults.millisecMin) - this.millisec = this._defaults.millisecMin; - this._defaults.millisecMin = this.millisecMinOriginal; - } - } else { - this._defaults.minuteMin = this.minuteMinOriginal; - this._defaults.secondMin = this.secondMinOriginal; - this._defaults.millisecMin = this.millisecMinOriginal; - } - }else{ - this._defaults.hourMin = this.hourMinOriginal; - this._defaults.minuteMin = this.minuteMinOriginal; - this._defaults.secondMin = this.secondMinOriginal; - this._defaults.millisecMin = this.millisecMinOriginal; - } - } - - if($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date){ - var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'), - maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0); - - if(this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null){ - this.hourMaxOriginal = o.hourMax; - this.minuteMaxOriginal = o.minuteMax; - this.secondMaxOriginal = o.secondMax; - this.millisecMaxOriginal = o.millisecMax; - } - - if(dp_inst.settings.timeOnly || maxDateTimeDate.getTime() == dp_date.getTime()){ - this._defaults.hourMax = maxDateTime.getHours(); - if (this.hour >= this._defaults.hourMax) { - this.hour = this._defaults.hourMax; - this._defaults.minuteMax = maxDateTime.getMinutes(); - if (this.minute >= this._defaults.minuteMax) { - this.minute = this._defaults.minuteMax; - this._defaults.secondMax = maxDateTime.getSeconds(); - } else if (this.second >= this._defaults.secondMax) { - this.second = this._defaults.secondMax; - this._defaults.millisecMax = maxDateTime.getMilliseconds(); - } else { - if(this.millisec > this._defaults.millisecMax) this.millisec = this._defaults.millisecMax; - this._defaults.millisecMax = this.millisecMaxOriginal; - } - } else { - this._defaults.minuteMax = this.minuteMaxOriginal; - this._defaults.secondMax = this.secondMaxOriginal; - this._defaults.millisecMax = this.millisecMaxOriginal; - } - }else{ - this._defaults.hourMax = this.hourMaxOriginal; - this._defaults.minuteMax = this.minuteMaxOriginal; - this._defaults.secondMax = this.secondMaxOriginal; - this._defaults.millisecMax = this.millisecMaxOriginal; - } - } - - if(adjustSliders !== undefined && adjustSliders === true){ - var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)) ,10), - minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)) ,10), - secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)) ,10), - millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)) ,10); - - if(this.hour_slider) - this.hour_slider.slider("option", { min: this._defaults.hourMin, max: hourMax }).slider('value', this.hour); - if(this.minute_slider) - this.minute_slider.slider("option", { min: this._defaults.minuteMin, max: minMax }).slider('value', this.minute); - if(this.second_slider) - this.second_slider.slider("option", { min: this._defaults.secondMin, max: secMax }).slider('value', this.second); - if(this.millisec_slider) - this.millisec_slider.slider("option", { min: this._defaults.millisecMin, max: millisecMax }).slider('value', this.millisec); - } - - }, - - - //######################################################################## - // when a slider moves, set the internal time... - // on time change is also called when the time is updated in the text field - //######################################################################## - _onTimeChange: function() { - var hour = (this.hour_slider) ? this.hour_slider.slider('value') : false, - minute = (this.minute_slider) ? this.minute_slider.slider('value') : false, - second = (this.second_slider) ? this.second_slider.slider('value') : false, - millisec = (this.millisec_slider) ? this.millisec_slider.slider('value') : false, - timezone = (this.timezone_select) ? this.timezone_select.val() : false, - o = this._defaults; - - if (typeof(hour) == 'object') hour = false; - if (typeof(minute) == 'object') minute = false; - if (typeof(second) == 'object') second = false; - if (typeof(millisec) == 'object') millisec = false; - if (typeof(timezone) == 'object') timezone = false; - - if (hour !== false) hour = parseInt(hour,10); - if (minute !== false) minute = parseInt(minute,10); - if (second !== false) second = parseInt(second,10); - if (millisec !== false) millisec = parseInt(millisec,10); - - var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0]; - - // If the update was done in the input field, the input field should not be updated. - // If the update was done using the sliders, update the input field. - var hasChanged = (hour != this.hour || minute != this.minute - || second != this.second || millisec != this.millisec - || (this.ampm.length > 0 - && (hour < 12) != ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) - || timezone != this.timezone); - - if (hasChanged) { - - if (hour !== false)this.hour = hour; - if (minute !== false) this.minute = minute; - if (second !== false) this.second = second; - if (millisec !== false) this.millisec = millisec; - if (timezone !== false) this.timezone = timezone; - - if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]); - - this._limitMinMaxDateTime(this.inst, true); - } - if (o.ampm) this.ampm = ampm; - - //this._formatTime(); - this.formattedTime = $.datepicker.formatTime(this._defaults.timeFormat, this, this._defaults); - if (this.$timeObj) this.$timeObj.text(this.formattedTime + o.timeSuffix); - this.timeDefined = true; - if (hasChanged) this._updateDateTime(); - }, - - //######################################################################## - // call custom onSelect. - // bind to sliders slidestop, and grid click. - //######################################################################## - _onSelectHandler: function() { - var onSelect = this._defaults.onSelect; - var inputEl = this.$input ? this.$input[0] : null; - if (onSelect && inputEl) { - onSelect.apply(inputEl, [this.formattedDateTime, this]); - } - }, - - //######################################################################## - // left for any backwards compatibility - //######################################################################## - _formatTime: function(time, format) { - time = time || { hour: this.hour, minute: this.minute, second: this.second, millisec: this.millisec, ampm: this.ampm, timezone: this.timezone }; - var tmptime = (format || this._defaults.timeFormat).toString(); - - tmptime = $.datepicker.formatTime(tmptime, time, this._defaults); - - if (arguments.length) return tmptime; - else this.formattedTime = tmptime; - }, - - //######################################################################## - // update our input with the new date time.. - //######################################################################## - _updateDateTime: function(dp_inst) { - dp_inst = this.inst || dp_inst; - var dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)), - dateFmt = $.datepicker._get(dp_inst, 'dateFormat'), - formatCfg = $.datepicker._getFormatConfig(dp_inst), - timeAvailable = dt !== null && this.timeDefined; - this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg); - var formattedDateTime = this.formattedDate; - if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) - return; - - if (this._defaults.timeOnly === true) { - formattedDateTime = this.formattedTime; - } else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) { - formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix; - } - - this.formattedDateTime = formattedDateTime; - - if(!this._defaults.showTimepicker) { - this.$input.val(this.formattedDate); - } else if (this.$altInput && this._defaults.altFieldTimeOnly === true) { - this.$altInput.val(this.formattedTime); - this.$input.val(this.formattedDate); - } else if(this.$altInput) { - this.$altInput.val(formattedDateTime); - this.$input.val(formattedDateTime); - } else { - this.$input.val(formattedDateTime); - } - - this.$input.trigger("change"); - } - -}); - -$.fn.extend({ - //######################################################################## - // shorthand just to use timepicker.. - //######################################################################## - timepicker: function(o) { - o = o || {}; - var tmp_args = arguments; - - if (typeof o == 'object') tmp_args[0] = $.extend(o, { timeOnly: true }); - - return $(this).each(function() { - $.fn.datetimepicker.apply($(this), tmp_args); - }); - }, - - //######################################################################## - // extend timepicker to datepicker - //######################################################################## - datetimepicker: function(o) { - o = o || {}; - var $input = this, - tmp_args = arguments; - - if (typeof(o) == 'string'){ - if(o == 'getDate' || o == 'widget') - return $.fn.datepicker.apply($(this[0]), tmp_args); - else - return this.each(function() { - var $t = $(this); - $t.datepicker.apply($t, tmp_args); - }); - } - else - return this.each(function() { - var $t = $(this); - $t.datepicker($.timepicker._newInst($t, o)._defaults); - }); - } -}); - -//######################################################################## -// format the time all pretty... -// format = string format of the time -// time = a {}, not a Date() for timezones -// options = essentially the regional[].. amNames, pmNames, ampm -//######################################################################## -$.datepicker.formatTime = function(format, time, options) { - options = options || {}; - options = $.extend($.timepicker._defaults, options); - time = $.extend({hour:0, minute:0, second:0, millisec:0, timezone:'+0000'}, time); - - var tmptime = format; - var ampmName = options['amNames'][0]; - - var hour = parseInt(time.hour, 10); - if (options.ampm) { - if (hour > 11){ - ampmName = options['pmNames'][0]; - if(hour > 12) - hour = hour % 12; - } - if (hour === 0) - hour = 12; - } - tmptime = tmptime.replace(/(?:hh?|mm?|ss?|[tT]{1,2}|[lz])/g, function(match) { - switch (match.toLowerCase()) { - case 'hh': return ('0' + hour).slice(-2); - case 'h': return hour; - case 'mm': return ('0' + time.minute).slice(-2); - case 'm': return time.minute; - case 'ss': return ('0' + time.second).slice(-2); - case 's': return time.second; - case 'l': return ('00' + time.millisec).slice(-3); - case 'z': return time.timezone; - case 't': case 'tt': - if (options.ampm) { - if (match.length == 1) - ampmName = ampmName.charAt(0); - return match.charAt(0) == 'T' ? ampmName.toUpperCase() : ampmName.toLowerCase(); - } - return ''; - } - }); - - tmptime = $.trim(tmptime); - return tmptime; -} - -//######################################################################## -// the bad hack :/ override datepicker so it doesnt close on select -// inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378 -//######################################################################## -$.datepicker._base_selectDate = $.datepicker._selectDate; -$.datepicker._selectDate = function (id, dateStr) { - var inst = this._getInst($(id)[0]), - tp_inst = this._get(inst, 'timepicker'); - - if (tp_inst) { - tp_inst._limitMinMaxDateTime(inst, true); - inst.inline = inst.stay_open = true; - //This way the onSelect handler called from calendarpicker get the full dateTime - this._base_selectDate(id, dateStr); - inst.inline = inst.stay_open = false; - this._notifyChange(inst); - this._updateDatepicker(inst); - } - else this._base_selectDate(id, dateStr); -}; - -//############################################################################################# -// second bad hack :/ override datepicker so it triggers an event when changing the input field -// and does not redraw the datepicker on every selectDate event -//############################################################################################# -$.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker; -$.datepicker._updateDatepicker = function(inst) { - - // don't popup the datepicker if there is another instance already opened - var input = inst.input[0]; - if($.datepicker._curInst && - $.datepicker._curInst != inst && - $.datepicker._datepickerShowing && - $.datepicker._lastInput != input) { - return; - } - - if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) { - - this._base_updateDatepicker(inst); - - // Reload the time control when changing something in the input text field. - var tp_inst = this._get(inst, 'timepicker'); - if(tp_inst) tp_inst._addTimePicker(inst); - } -}; - -//####################################################################################### -// third bad hack :/ override datepicker so it allows spaces and colon in the input field -//####################################################################################### -$.datepicker._base_doKeyPress = $.datepicker._doKeyPress; -$.datepicker._doKeyPress = function(event) { - var inst = $.datepicker._getInst(event.target), - tp_inst = $.datepicker._get(inst, 'timepicker'); - - if (tp_inst) { - if ($.datepicker._get(inst, 'constrainInput')) { - var ampm = tp_inst._defaults.ampm, - dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')), - datetimeChars = tp_inst._defaults.timeFormat.toString() - .replace(/[hms]/g, '') - .replace(/TT/g, ampm ? 'APM' : '') - .replace(/Tt/g, ampm ? 'AaPpMm' : '') - .replace(/tT/g, ampm ? 'AaPpMm' : '') - .replace(/T/g, ampm ? 'AP' : '') - .replace(/tt/g, ampm ? 'apm' : '') - .replace(/t/g, ampm ? 'ap' : '') + - " " + - tp_inst._defaults.separator + - tp_inst._defaults.timeSuffix + - (tp_inst._defaults.showTimezone ? tp_inst._defaults.timezoneList.join('') : '') + - (tp_inst._defaults.amNames.join('')) + - (tp_inst._defaults.pmNames.join('')) + - dateChars, - chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode); - return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1); - } - } - - return $.datepicker._base_doKeyPress(event); -}; - -//####################################################################################### -// Override key up event to sync manual input changes. -//####################################################################################### -$.datepicker._base_doKeyUp = $.datepicker._doKeyUp; -$.datepicker._doKeyUp = function (event) { - var inst = $.datepicker._getInst(event.target), - tp_inst = $.datepicker._get(inst, 'timepicker'); - - if (tp_inst) { - if (tp_inst._defaults.timeOnly && (inst.input.val() != inst.lastVal)) { - try { - $.datepicker._updateDatepicker(inst); - } - catch (err) { - $.datepicker.log(err); - } - } - } - - return $.datepicker._base_doKeyUp(event); -}; - -//####################################################################################### -// override "Today" button to also grab the time. -//####################################################################################### -$.datepicker._base_gotoToday = $.datepicker._gotoToday; -$.datepicker._gotoToday = function(id) { - var inst = this._getInst($(id)[0]), - $dp = inst.dpDiv; - this._base_gotoToday(id); - var now = new Date(); - var tp_inst = this._get(inst, 'timepicker'); - if (tp_inst && tp_inst._defaults.showTimezone && tp_inst.timezone_select) { - var tzoffset = now.getTimezoneOffset(); // If +0100, returns -60 - var tzsign = tzoffset > 0 ? '-' : '+'; - tzoffset = Math.abs(tzoffset); - var tzmin = tzoffset % 60; - tzoffset = tzsign + ('0' + (tzoffset - tzmin) / 60).slice(-2) + ('0' + tzmin).slice(-2); - if (tp_inst._defaults.timezoneIso8609) - tzoffset = tzoffset.substring(0, 3) + ':' + tzoffset.substring(3); - tp_inst.timezone_select.val(tzoffset); - } - this._setTime(inst, now); - $( '.ui-datepicker-today', $dp).click(); -}; - -//####################################################################################### -// Disable & enable the Time in the datetimepicker -//####################################################################################### -$.datepicker._disableTimepickerDatepicker = function(target, date, withDate) { - var inst = this._getInst(target), - tp_inst = this._get(inst, 'timepicker'); - $(target).datepicker('getDate'); // Init selected[Year|Month|Day] - if (tp_inst) { - tp_inst._defaults.showTimepicker = false; - tp_inst._updateDateTime(inst); - } -}; - -$.datepicker._enableTimepickerDatepicker = function(target, date, withDate) { - var inst = this._getInst(target), - tp_inst = this._get(inst, 'timepicker'); - $(target).datepicker('getDate'); // Init selected[Year|Month|Day] - if (tp_inst) { - tp_inst._defaults.showTimepicker = true; - tp_inst._addTimePicker(inst); // Could be disabled on page load - tp_inst._updateDateTime(inst); - } -}; - -//####################################################################################### -// Create our own set time function -//####################################################################################### -$.datepicker._setTime = function(inst, date) { - var tp_inst = this._get(inst, 'timepicker'); - if (tp_inst) { - var defaults = tp_inst._defaults, - // calling _setTime with no date sets time to defaults - hour = date ? date.getHours() : defaults.hour, - minute = date ? date.getMinutes() : defaults.minute, - second = date ? date.getSeconds() : defaults.second, - millisec = date ? date.getMilliseconds() : defaults.millisec; - - //check if within min/max times.. - if ((hour < defaults.hourMin || hour > defaults.hourMax) || (minute < defaults.minuteMin || minute > defaults.minuteMax) || (second < defaults.secondMin || second > defaults.secondMax) || (millisec < defaults.millisecMin || millisec > defaults.millisecMax)) { - hour = defaults.hourMin; - minute = defaults.minuteMin; - second = defaults.secondMin; - millisec = defaults.millisecMin; - } - - tp_inst.hour = hour; - tp_inst.minute = minute; - tp_inst.second = second; - tp_inst.millisec = millisec; - - if (tp_inst.hour_slider) tp_inst.hour_slider.slider('value', hour); - if (tp_inst.minute_slider) tp_inst.minute_slider.slider('value', minute); - if (tp_inst.second_slider) tp_inst.second_slider.slider('value', second); - if (tp_inst.millisec_slider) tp_inst.millisec_slider.slider('value', millisec); - - tp_inst._onTimeChange(); - tp_inst._updateDateTime(inst); - } -}; - -//####################################################################################### -// Create new public method to set only time, callable as $().datepicker('setTime', date) -//####################################################################################### -$.datepicker._setTimeDatepicker = function(target, date, withDate) { - var inst = this._getInst(target), - tp_inst = this._get(inst, 'timepicker'); - - if (tp_inst) { - this._setDateFromField(inst); - var tp_date; - if (date) { - if (typeof date == "string") { - tp_inst._parseTime(date, withDate); - tp_date = new Date(); - tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec); - } - else tp_date = new Date(date.getTime()); - if (tp_date.toString() == 'Invalid Date') tp_date = undefined; - this._setTime(inst, tp_date); - } - } - -}; - -//####################################################################################### -// override setDate() to allow setting time too within Date object -//####################################################################################### -$.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker; -$.datepicker._setDateDatepicker = function(target, date) { - var inst = this._getInst(target), - tp_date = (date instanceof Date) ? new Date(date.getTime()) : date; - - this._updateDatepicker(inst); - this._base_setDateDatepicker.apply(this, arguments); - this._setTimeDatepicker(target, tp_date, true); -}; - -//####################################################################################### -// override getDate() to allow getting time too within Date object -//####################################################################################### -$.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker; -$.datepicker._getDateDatepicker = function(target, noDefault) { - var inst = this._getInst(target), - tp_inst = this._get(inst, 'timepicker'); - - if (tp_inst) { - this._setDateFromField(inst, noDefault); - var date = this._getDate(inst); - if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec); - return date; - } - return this._base_getDateDatepicker(target, noDefault); -}; - -//####################################################################################### -// override parseDate() because UI 1.8.14 throws an error about "Extra characters" -// An option in datapicker to ignore extra format characters would be nicer. -//####################################################################################### -$.datepicker._base_parseDate = $.datepicker.parseDate; -$.datepicker.parseDate = function(format, value, settings) { - var date; - try { - date = this._base_parseDate(format, value, settings); - } catch (err) { - if (err.indexOf(":") >= 0) { - // Hack! The error message ends with a colon, a space, and - // the "extra" characters. We rely on that instead of - // attempting to perfectly reproduce the parsing algorithm. - date = this._base_parseDate(format, value.substring(0,value.length-(err.length-err.indexOf(':')-2)), settings); - } else { - // The underlying error was not related to the time - throw err; - } - } - return date; -}; - -//####################################################################################### -// override formatDate to set date with time to the input -//####################################################################################### -$.datepicker._base_formatDate=$.datepicker._formatDate; -$.datepicker._formatDate = function(inst, day, month, year){ - var tp_inst = this._get(inst, 'timepicker'); - if(tp_inst) - { - if(day) - var b = this._base_formatDate(inst, day, month, year); - tp_inst._updateDateTime(inst); - return tp_inst.$input.val(); - } - return this._base_formatDate(inst); -}; - -//####################################################################################### -// override options setter to add time to maxDate(Time) and minDate(Time). MaxDate -//####################################################################################### -$.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker; -$.datepicker._optionDatepicker = function(target, name, value) { - var inst = this._getInst(target), - tp_inst = this._get(inst, 'timepicker'); - if (tp_inst) { - var min,max,onselect; - if (typeof name == 'string') { // if min/max was set with the string - if (name==='minDate' || name==='minDateTime' ) - min = value; - else if (name==='maxDate' || name==='maxDateTime') - max = value; - else if (name==='onSelect') - onselect=value; - } else if (typeof name == 'object') { //if min/max was set with the JSON - if(name.minDate) - min = name.minDate; - else if (name.minDateTime) - min = name.minDateTime; - else if (name.maxDate) - max = name.maxDate; - else if (name.maxDateTime) - max = name.maxDateTime; - } - if(min){ //if min was set - if(min==0) - min=new Date(); - else - min= new Date(min); - - tp_inst._defaults.minDate = min; - tp_inst._defaults.minDateTime = min; - } else if (max){ //if max was set - if(max==0) - max=new Date(); - else - max= new Date(max); - tp_inst._defaults.maxDate = max; - tp_inst._defaults.maxDateTime = max; - } - else if (onselect) - tp_inst._defaults.onSelect=onselect; - } - if (value === undefined) - return this._base_optionDatepicker(target, name); - return this._base_optionDatepicker(target, name, value); -}; - -//####################################################################################### -// jQuery extend now ignores nulls! -//####################################################################################### -function extendRemove(target, props) { - $.extend(target, props); - for (var name in props) - if (props[name] === null || props[name] === undefined) - target[name] = props[name]; - return target; -}; - -$.timepicker = new Timepicker(); // singleton instance -$.timepicker.version = "0.9.9"; - -})(jQuery); - diff --git a/addons/web/static/lib/moment/locale/af.js b/addons/web/static/lib/moment/locale/af.js new file mode 100644 index 00000000000..2777e58e77f --- /dev/null +++ b/addons/web/static/lib/moment/locale/af.js @@ -0,0 +1,65 @@ +// moment.js locale configuration +// locale : afrikaans (af) +// author : Werner Mollentze : https://github.com/wernerm + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('af', { + months : "Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember".split("_"), + monthsShort : "Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des".split("_"), + weekdays : "Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag".split("_"), + weekdaysShort : "Son_Maa_Din_Woe_Don_Vry_Sat".split("_"), + weekdaysMin : "So_Ma_Di_Wo_Do_Vr_Sa".split("_"), + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower ? 'vm' : 'VM'; + } else { + return isLower ? 'nm' : 'NM'; + } + }, + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd, D MMMM YYYY LT" + }, + calendar : { + sameDay : '[Vandag om] LT', + nextDay : '[Môre om] LT', + nextWeek : 'dddd [om] LT', + lastDay : '[Gister om] LT', + lastWeek : '[Laas] dddd [om] LT', + sameElse : 'L' + }, + relativeTime : { + future : "oor %s", + past : "%s gelede", + s : "'n paar sekondes", + m : "'n minuut", + mm : "%d minute", + h : "'n uur", + hh : "%d ure", + d : "'n dag", + dd : "%d dae", + M : "'n maand", + MM : "%d maande", + y : "'n jaar", + yy : "%d jaar" + }, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter + }, + week : { + dow : 1, // Maandag is die eerste dag van die week. + doy : 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ar-ma.js b/addons/web/static/lib/moment/locale/ar-ma.js new file mode 100644 index 00000000000..c8add2ddeb7 --- /dev/null +++ b/addons/web/static/lib/moment/locale/ar-ma.js @@ -0,0 +1,56 @@ +// moment.js locale configuration +// locale : Moroccan Arabic (ar-ma) +// author : ElFadili Yassine : https://github.com/ElFadiliY +// author : Abdel Said : https://github.com/abdelsaid + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('ar-ma', { + months : "يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"), + monthsShort : "يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"), + weekdays : "الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"), + weekdaysShort : "احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"), + weekdaysMin : "ح_ن_ث_ر_خ_ج_س".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D MMMM YYYY LT" + }, + calendar : { + sameDay: "[اليوم على الساعة] LT", + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : "في %s", + past : "منذ %s", + s : "ثوان", + m : "دقيقة", + mm : "%d دقائق", + h : "ساعة", + hh : "%d ساعات", + d : "يوم", + dd : "%d أيام", + M : "شهر", + MM : "%d أشهر", + y : "سنة", + yy : "%d سنوات" + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ar-sa.js b/addons/web/static/lib/moment/locale/ar-sa.js new file mode 100644 index 00000000000..64e209137ea --- /dev/null +++ b/addons/web/static/lib/moment/locale/ar-sa.js @@ -0,0 +1,96 @@ +// moment.js locale configuration +// locale : Arabic Saudi Arabia (ar-sa) +// author : Suhail Alkowaileet : https://github.com/xsoh + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var symbolMap = { + '1': '١', + '2': '٢', + '3': '٣', + '4': '٤', + '5': '٥', + '6': '٦', + '7': '٧', + '8': '٨', + '9': '٩', + '0': '٠' + }, numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0' + }; + + return moment.defineLocale('ar-sa', { + months : "يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"), + monthsShort : "يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"), + weekdays : "الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"), + weekdaysShort : "أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"), + weekdaysMin : "ح_ن_ث_ر_خ_ج_س".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D MMMM YYYY LT" + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return "ص"; + } else { + return "م"; + } + }, + calendar : { + sameDay: "[اليوم على الساعة] LT", + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : "في %s", + past : "منذ %s", + s : "ثوان", + m : "دقيقة", + mm : "%d دقائق", + h : "ساعة", + hh : "%d ساعات", + d : "يوم", + dd : "%d أيام", + M : "شهر", + MM : "%d أشهر", + y : "سنة", + yy : "%d سنوات" + }, + preparse: function (string) { + return string.replace(/[۰-۹]/g, function (match) { + return numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ar.js b/addons/web/static/lib/moment/locale/ar.js new file mode 100644 index 00000000000..2af64ee3a92 --- /dev/null +++ b/addons/web/static/lib/moment/locale/ar.js @@ -0,0 +1,97 @@ +// moment.js locale configuration +// locale : Arabic (ar) +// author : Abdel Said : https://github.com/abdelsaid +// changes in months, weekdays : Ahmed Elkhatib + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var symbolMap = { + '1': '١', + '2': '٢', + '3': '٣', + '4': '٤', + '5': '٥', + '6': '٦', + '7': '٧', + '8': '٨', + '9': '٩', + '0': '٠' + }, numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0' + }; + + return moment.defineLocale('ar', { + months : "يناير/ كانون الثاني_فبراير/ شباط_مارس/ آذار_أبريل/ نيسان_مايو/ أيار_يونيو/ حزيران_يوليو/ تموز_أغسطس/ آب_سبتمبر/ أيلول_أكتوبر/ تشرين الأول_نوفمبر/ تشرين الثاني_ديسمبر/ كانون الأول".split("_"), + monthsShort : "يناير/ كانون الثاني_فبراير/ شباط_مارس/ آذار_أبريل/ نيسان_مايو/ أيار_يونيو/ حزيران_يوليو/ تموز_أغسطس/ آب_سبتمبر/ أيلول_أكتوبر/ تشرين الأول_نوفمبر/ تشرين الثاني_ديسمبر/ كانون الأول".split("_"), + weekdays : "الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"), + weekdaysShort : "أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"), + weekdaysMin : "ح_ن_ث_ر_خ_ج_س".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D MMMM YYYY LT" + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return "ص"; + } else { + return "م"; + } + }, + calendar : { + sameDay: "[اليوم على الساعة] LT", + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : "في %s", + past : "منذ %s", + s : "ثوان", + m : "دقيقة", + mm : "%d دقائق", + h : "ساعة", + hh : "%d ساعات", + d : "يوم", + dd : "%d أيام", + M : "شهر", + MM : "%d أشهر", + y : "سنة", + yy : "%d سنوات" + }, + preparse: function (string) { + return string.replace(/[۰-۹]/g, function (match) { + return numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/az.js b/addons/web/static/lib/moment/locale/az.js new file mode 100644 index 00000000000..a6a5aff964e --- /dev/null +++ b/addons/web/static/lib/moment/locale/az.js @@ -0,0 +1,101 @@ +// moment.js locale configuration +// locale : azerbaijani (az) +// author : topchiyev : https://github.com/topchiyev + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var suffixes = { + 1: "-inci", + 5: "-inci", + 8: "-inci", + 70: "-inci", + 80: "-inci", + + 2: "-nci", + 7: "-nci", + 20: "-nci", + 50: "-nci", + + 3: "-üncü", + 4: "-üncü", + 100: "-üncü", + + 6: "-ncı", + + 9: "-uncu", + 10: "-uncu", + 30: "-uncu", + + 60: "-ıncı", + 90: "-ıncı" + }; + return moment.defineLocale('az', { + months : "yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"), + monthsShort : "yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"), + weekdays : "Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə".split("_"), + weekdaysShort : "Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən".split("_"), + weekdaysMin : "Bz_BE_ÇA_Çə_CA_Cü_Şə".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD.MM.YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd, D MMMM YYYY LT" + }, + calendar : { + sameDay : '[bugün saat] LT', + nextDay : '[sabah saat] LT', + nextWeek : '[gələn həftə] dddd [saat] LT', + lastDay : '[dünən] LT', + lastWeek : '[keçən həftə] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s sonra", + past : "%s əvvəl", + s : "birneçə saniyyə", + m : "bir dəqiqə", + mm : "%d dəqiqə", + h : "bir saat", + hh : "%d saat", + d : "bir gün", + dd : "%d gün", + M : "bir ay", + MM : "%d ay", + y : "bir il", + yy : "%d il" + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return "gecə"; + } else if (hour < 12) { + return "səhər"; + } else if (hour < 17) { + return "gündüz"; + } else { + return "axşam"; + } + }, + ordinal : function (number) { + if (number === 0) { // special case for zero + return number + "-ıncı"; + } + var a = number % 10, + b = number % 100 - a, + c = number >= 100 ? 100 : null; + + return number + (suffixes[a] || suffixes[b] || suffixes[c]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/be.js b/addons/web/static/lib/moment/locale/be.js new file mode 100644 index 00000000000..6e0aef1b8d1 --- /dev/null +++ b/addons/web/static/lib/moment/locale/be.js @@ -0,0 +1,150 @@ +// moment.js locale configuration +// locale : belarusian (be) +// author : Dmitry Demidov : https://github.com/demidov91 +// author: Praleska: http://praleska.pro/ +// Author : Menelion Elensúle : https://github.com/Oire + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); + } + + function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін', + 'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін', + 'dd': 'дзень_дні_дзён', + 'MM': 'месяц_месяцы_месяцаў', + 'yy': 'год_гады_гадоў' + }; + if (key === 'm') { + return withoutSuffix ? 'хвіліна' : 'хвіліну'; + } + else if (key === 'h') { + return withoutSuffix ? 'гадзіна' : 'гадзіну'; + } + else { + return number + ' ' + plural(format[key], +number); + } + } + + function monthsCaseReplace(m, format) { + var months = { + 'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'), + 'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_') + }, + + nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ? + 'accusative' : + 'nominative'; + + return months[nounCase][m.month()]; + } + + function weekdaysCaseReplace(m, format) { + var weekdays = { + 'nominative': 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'), + 'accusative': 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_') + }, + + nounCase = (/\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/).test(format) ? + 'accusative' : + 'nominative'; + + return weekdays[nounCase][m.day()]; + } + + return moment.defineLocale('be', { + months : monthsCaseReplace, + monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'), + weekdays : weekdaysCaseReplace, + weekdaysShort : "нд_пн_ат_ср_чц_пт_сб".split("_"), + weekdaysMin : "нд_пн_ат_ср_чц_пт_сб".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD.MM.YYYY", + LL : "D MMMM YYYY г.", + LLL : "D MMMM YYYY г., LT", + LLLL : "dddd, D MMMM YYYY г., LT" + }, + calendar : { + sameDay: '[Сёння ў] LT', + nextDay: '[Заўтра ў] LT', + lastDay: '[Учора ў] LT', + nextWeek: function () { + return '[У] dddd [ў] LT'; + }, + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 5: + case 6: + return '[У мінулую] dddd [ў] LT'; + case 1: + case 2: + case 4: + return '[У мінулы] dddd [ў] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : "праз %s", + past : "%s таму", + s : "некалькі секунд", + m : relativeTimeWithPlural, + mm : relativeTimeWithPlural, + h : relativeTimeWithPlural, + hh : relativeTimeWithPlural, + d : "дзень", + dd : relativeTimeWithPlural, + M : "месяц", + MM : relativeTimeWithPlural, + y : "год", + yy : relativeTimeWithPlural + }, + + + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return "ночы"; + } else if (hour < 12) { + return "раніцы"; + } else if (hour < 17) { + return "дня"; + } else { + return "вечара"; + } + }, + + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + case 'w': + case 'W': + return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы'; + case 'D': + return number + '-га'; + default: + return number; + } + }, + + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/bg.js b/addons/web/static/lib/moment/locale/bg.js new file mode 100644 index 00000000000..b8a8c326ad0 --- /dev/null +++ b/addons/web/static/lib/moment/locale/bg.js @@ -0,0 +1,86 @@ +// moment.js locale configuration +// locale : bulgarian (bg) +// author : Krasen Borisov : https://github.com/kraz + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('bg', { + months : "януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември".split("_"), + monthsShort : "янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек".split("_"), + weekdays : "неделя_понеделник_вторник_сряда_четвъртък_петък_събота".split("_"), + weekdaysShort : "нед_пон_вто_сря_чет_пет_съб".split("_"), + weekdaysMin : "нд_пн_вт_ср_чт_пт_сб".split("_"), + longDateFormat : { + LT : "H:mm", + L : "D.MM.YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd, D MMMM YYYY LT" + }, + calendar : { + sameDay : '[Днес в] LT', + nextDay : '[Утре в] LT', + nextWeek : 'dddd [в] LT', + lastDay : '[Вчера в] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + case 6: + return '[В изминалата] dddd [в] LT'; + case 1: + case 2: + case 4: + case 5: + return '[В изминалия] dddd [в] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : "след %s", + past : "преди %s", + s : "няколко секунди", + m : "минута", + mm : "%d минути", + h : "час", + hh : "%d часа", + d : "ден", + dd : "%d дни", + M : "месец", + MM : "%d месеца", + y : "година", + yy : "%d години" + }, + ordinal : function (number) { + var lastDigit = number % 10, + last2Digits = number % 100; + if (number === 0) { + return number + '-ев'; + } else if (last2Digits === 0) { + return number + '-ен'; + } else if (last2Digits > 10 && last2Digits < 20) { + return number + '-ти'; + } else if (lastDigit === 1) { + return number + '-ви'; + } else if (lastDigit === 2) { + return number + '-ри'; + } else if (lastDigit === 7 || lastDigit === 8) { + return number + '-ми'; + } else { + return number + '-ти'; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/bn.js b/addons/web/static/lib/moment/locale/bn.js new file mode 100644 index 00000000000..8ceb8eb0a4f --- /dev/null +++ b/addons/web/static/lib/moment/locale/bn.js @@ -0,0 +1,106 @@ +// moment.js locale configuration +// locale : Bengali (bn) +// author : Kaushik Gandhi : https://github.com/kaushikgandhi + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var symbolMap = { + '1': '১', + '2': '২', + '3': '৩', + '4': '৪', + '5': '৫', + '6': '৬', + '7': '৭', + '8': '৮', + '9': '৯', + '0': '০' + }, + numberMap = { + '১': '1', + '২': '2', + '৩': '3', + '৪': '4', + '৫': '5', + '৬': '6', + '৭': '7', + '৮': '8', + '৯': '9', + '০': '0' + }; + + return moment.defineLocale('bn', { + months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split("_"), + monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split("_"), + weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার'.split("_"), + weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্রু_শনি'.split("_"), + weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split("_"), + longDateFormat : { + LT : "A h:mm সময়", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY, LT", + LLLL : "dddd, D MMMM YYYY, LT" + }, + calendar : { + sameDay : '[আজ] LT', + nextDay : '[আগামীকাল] LT', + nextWeek : 'dddd, LT', + lastDay : '[গতকাল] LT', + lastWeek : '[গত] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s পরে", + past : "%s আগে", + s : "কএক সেকেন্ড", + m : "এক মিনিট", + mm : "%d মিনিট", + h : "এক ঘন্টা", + hh : "%d ঘন্টা", + d : "এক দিন", + dd : "%d দিন", + M : "এক মাস", + MM : "%d মাস", + y : "এক বছর", + yy : "%d বছর" + }, + 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]; + }); + }, + //Bengali is a vast language its spoken + //in different forms in various parts of the world. + //I have just generalized with most common one used + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return "রাত"; + } else if (hour < 10) { + return "শকাল"; + } else if (hour < 17) { + return "দুপুর"; + } else if (hour < 20) { + return "বিকেল"; + } else { + return "রাত"; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/bo.js b/addons/web/static/lib/moment/locale/bo.js new file mode 100644 index 00000000000..f1567abf5ee --- /dev/null +++ b/addons/web/static/lib/moment/locale/bo.js @@ -0,0 +1,103 @@ +// moment.js locale configuration +// locale : tibetan (bo) +// author : Thupten N. Chakrishar : https://github.com/vajradog + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var symbolMap = { + '1': '༡', + '2': '༢', + '3': '༣', + '4': '༤', + '5': '༥', + '6': '༦', + '7': '༧', + '8': '༨', + '9': '༩', + '0': '༠' + }, + numberMap = { + '༡': '1', + '༢': '2', + '༣': '3', + '༤': '4', + '༥': '5', + '༦': '6', + '༧': '7', + '༨': '8', + '༩': '9', + '༠': '0' + }; + + return moment.defineLocale('bo', { + months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split("_"), + monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split("_"), + weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split("_"), + weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split("_"), + weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split("_"), + longDateFormat : { + LT : "A h:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY, LT", + LLLL : "dddd, D MMMM YYYY, LT" + }, + calendar : { + sameDay : '[དི་རིང] LT', + nextDay : '[སང་ཉིན] LT', + nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT', + lastDay : '[ཁ་སང] LT', + lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s ལ་", + past : "%s སྔན་ལ", + s : "ལམ་སང", + m : "སྐར་མ་གཅིག", + mm : "%d སྐར་མ", + h : "ཆུ་ཚོད་གཅིག", + hh : "%d ཆུ་ཚོད", + d : "ཉིན་གཅིག", + dd : "%d ཉིན་", + M : "ཟླ་བ་གཅིག", + MM : "%d ཟླ་བ", + y : "ལོ་གཅིག", + yy : "%d ལོ" + }, + 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]; + }); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return "མཚན་མོ"; + } else if (hour < 10) { + return "ཞོགས་ཀས"; + } else if (hour < 17) { + return "ཉིན་གུང"; + } else if (hour < 20) { + return "དགོང་དག"; + } else { + return "མཚན་མོ"; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/br.js b/addons/web/static/lib/moment/locale/br.js new file mode 100644 index 00000000000..fb11fe1e579 --- /dev/null +++ b/addons/web/static/lib/moment/locale/br.js @@ -0,0 +1,107 @@ +// moment.js locale configuration +// locale : breton (br) +// author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function relativeTimeWithMutation(number, withoutSuffix, key) { + var format = { + 'mm': "munutenn", + 'MM': "miz", + 'dd': "devezh" + }; + return number + ' ' + mutation(format[key], number); + } + + function specialMutationForYears(number) { + switch (lastNumber(number)) { + case 1: + case 3: + case 4: + case 5: + case 9: + return number + ' bloaz'; + default: + return number + ' vloaz'; + } + } + + function lastNumber(number) { + if (number > 9) { + return lastNumber(number % 10); + } + return number; + } + + function mutation(text, number) { + if (number === 2) { + return softMutation(text); + } + return text; + } + + function softMutation(text) { + var mutationTable = { + 'm': 'v', + 'b': 'v', + 'd': 'z' + }; + if (mutationTable[text.charAt(0)] === undefined) { + return text; + } + return mutationTable[text.charAt(0)] + text.substring(1); + } + + return moment.defineLocale('br', { + months : "Genver_C'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"), + monthsShort : "Gen_C'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"), + weekdays : "Sul_Lun_Meurzh_Merc'her_Yaou_Gwener_Sadorn".split("_"), + weekdaysShort : "Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"), + weekdaysMin : "Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"), + longDateFormat : { + LT : "h[e]mm A", + L : "DD/MM/YYYY", + LL : "D [a viz] MMMM YYYY", + LLL : "D [a viz] MMMM YYYY LT", + LLLL : "dddd, D [a viz] MMMM YYYY LT" + }, + calendar : { + sameDay : '[Hiziv da] LT', + nextDay : '[Warc\'hoazh da] LT', + nextWeek : 'dddd [da] LT', + lastDay : '[Dec\'h da] LT', + lastWeek : 'dddd [paset da] LT', + sameElse : 'L' + }, + relativeTime : { + future : "a-benn %s", + past : "%s 'zo", + s : "un nebeud segondennoù", + m : "ur vunutenn", + mm : relativeTimeWithMutation, + h : "un eur", + hh : "%d eur", + d : "un devezh", + dd : relativeTimeWithMutation, + M : "ur miz", + MM : relativeTimeWithMutation, + y : "ur bloaz", + yy : specialMutationForYears + }, + ordinal : function (number) { + var output = (number === 1) ? 'añ' : 'vet'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/bs.js b/addons/web/static/lib/moment/locale/bs.js new file mode 100644 index 00000000000..d69015abbef --- /dev/null +++ b/addons/web/static/lib/moment/locale/bs.js @@ -0,0 +1,138 @@ +// moment.js locale configuration +// locale : bosnian (bs) +// author : Nedim Cholich : https://github.com/frontyard +// based on (hr) translation by Bojan Marković + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function translate(number, withoutSuffix, key) { + var result = number + " "; + switch (key) { + case 'm': + return withoutSuffix ? 'jedna minuta' : 'jedne minute'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minuta'; + } + return result; + case 'h': + return withoutSuffix ? 'jedan sat' : 'jednog sata'; + case 'hh': + if (number === 1) { + result += 'sat'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sata'; + } else { + result += 'sati'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dana'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mjesec'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'mjeseca'; + } else { + result += 'mjeseci'; + } + return result; + case 'yy': + if (number === 1) { + result += 'godina'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'godine'; + } else { + result += 'godina'; + } + return result; + } + } + + return moment.defineLocale('bs', { + months : "januar_februar_mart_april_maj_juni_juli_avgust_septembar_oktobar_novembar_decembar".split("_"), + monthsShort : "jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"), + weekdays : "nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"), + weekdaysShort : "ned._pon._uto._sri._čet._pet._sub.".split("_"), + weekdaysMin : "ne_po_ut_sr_če_pe_su".split("_"), + longDateFormat : { + LT : "H:mm", + L : "DD. MM. YYYY", + LL : "D. MMMM YYYY", + LLL : "D. MMMM YYYY LT", + LLLL : "dddd, D. MMMM YYYY LT" + }, + calendar : { + sameDay : '[danas u] LT', + nextDay : '[sutra u] LT', + + nextWeek : function () { + switch (this.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'; + } + }, + lastDay : '[jučer u] LT', + lastWeek : function () { + switch (this.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'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : "za %s", + past : "prije %s", + s : "par sekundi", + m : translate, + mm : translate, + h : translate, + hh : translate, + d : "dan", + dd : translate, + M : "mjesec", + MM : translate, + y : "godinu", + yy : translate + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ca.js b/addons/web/static/lib/moment/locale/ca.js new file mode 100644 index 00000000000..932c1cbda74 --- /dev/null +++ b/addons/web/static/lib/moment/locale/ca.js @@ -0,0 +1,66 @@ +// moment.js locale configuration +// locale : catalan (ca) +// author : Juan G. Hurtado : https://github.com/juanghurtado + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('ca', { + months : "gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"), + monthsShort : "gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.".split("_"), + weekdays : "diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"), + weekdaysShort : "dg._dl._dt._dc._dj._dv._ds.".split("_"), + weekdaysMin : "Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"), + longDateFormat : { + LT : "H:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D MMMM YYYY LT" + }, + calendar : { + sameDay : function () { + return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + nextDay : function () { + return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + lastDay : function () { + return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : "en %s", + past : "fa %s", + s : "uns segons", + m : "un minut", + mm : "%d minuts", + h : "una hora", + hh : "%d hores", + d : "un dia", + dd : "%d dies", + M : "un mes", + MM : "%d mesos", + y : "un any", + yy : "%d anys" + }, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/cs.js b/addons/web/static/lib/moment/locale/cs.js new file mode 100644 index 00000000000..085bba06f4b --- /dev/null +++ b/addons/web/static/lib/moment/locale/cs.js @@ -0,0 +1,155 @@ +// moment.js locale configuration +// locale : czech (cs) +// author : petrbela : https://github.com/petrbela + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var months = "leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec".split("_"), + monthsShort = "led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro".split("_"); + + function plural(n) { + return (n > 1) && (n < 5) && (~~(n / 10) !== 1); + } + + function translate(number, withoutSuffix, key, isFuture) { + var result = number + " "; + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami'; + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou'); + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'minuty' : 'minut'); + } else { + return result + 'minutami'; + } + break; + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'hodiny' : 'hodin'); + } else { + return result + 'hodinami'; + } + break; + case 'd': // a day / in a day / a day ago + return (withoutSuffix || isFuture) ? 'den' : 'dnem'; + case 'dd': // 9 days / in 9 days / 9 days ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'dny' : 'dní'); + } else { + return result + 'dny'; + } + break; + case 'M': // a month / in a month / a month ago + return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem'; + case 'MM': // 9 months / in 9 months / 9 months ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'měsíce' : 'měsíců'); + } else { + return result + 'měsíci'; + } + break; + case 'y': // a year / in a year / a year ago + return (withoutSuffix || isFuture) ? 'rok' : 'rokem'; + case 'yy': // 9 years / in 9 years / 9 years ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'roky' : 'let'); + } else { + return result + 'lety'; + } + break; + } + } + + return moment.defineLocale('cs', { + months : months, + monthsShort : monthsShort, + monthsParse : (function (months, monthsShort) { + var i, _monthsParse = []; + for (i = 0; i < 12; i++) { + // use custom parser to solve problem with July (červenec) + _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i'); + } + return _monthsParse; + }(months, monthsShort)), + weekdays : "neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota".split("_"), + weekdaysShort : "ne_po_út_st_čt_pá_so".split("_"), + weekdaysMin : "ne_po_út_st_čt_pá_so".split("_"), + longDateFormat : { + LT: "H.mm", + L : "DD. MM. YYYY", + LL : "D. MMMM YYYY", + LLL : "D. MMMM YYYY LT", + LLLL : "dddd D. MMMM YYYY LT" + }, + calendar : { + sameDay: "[dnes v] LT", + nextDay: '[zítra v] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v neděli v] LT'; + case 1: + case 2: + return '[v] dddd [v] LT'; + case 3: + return '[ve středu v] LT'; + case 4: + return '[ve čtvrtek v] LT'; + case 5: + return '[v pátek v] LT'; + case 6: + return '[v sobotu v] LT'; + } + }, + lastDay: '[včera v] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[minulou neděli v] LT'; + case 1: + case 2: + return '[minulé] dddd [v] LT'; + case 3: + return '[minulou středu v] LT'; + case 4: + case 5: + return '[minulý] dddd [v] LT'; + case 6: + return '[minulou sobotu v] LT'; + } + }, + sameElse: "L" + }, + relativeTime : { + future : "za %s", + past : "před %s", + s : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/cv.js b/addons/web/static/lib/moment/locale/cv.js new file mode 100644 index 00000000000..0a290d8fafa --- /dev/null +++ b/addons/web/static/lib/moment/locale/cv.js @@ -0,0 +1,59 @@ +// moment.js locale configuration +// locale : chuvash (cv) +// author : Anatoly Mironov : https://github.com/mirontoli + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('cv', { + months : "кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав".split("_"), + monthsShort : "кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш".split("_"), + weekdays : "вырсарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_эрнекун_шăматкун".split("_"), + weekdaysShort : "выр_тун_ытл_юн_кĕç_эрн_шăм".split("_"), + weekdaysMin : "вр_тн_ыт_юн_кç_эр_шм".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD-MM-YYYY", + LL : "YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ]", + LLL : "YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT", + LLLL : "dddd, YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT" + }, + calendar : { + sameDay: '[Паян] LT [сехетре]', + nextDay: '[Ыран] LT [сехетре]', + lastDay: '[Ĕнер] LT [сехетре]', + nextWeek: '[Çитес] dddd LT [сехетре]', + lastWeek: '[Иртнĕ] dddd LT [сехетре]', + sameElse: 'L' + }, + relativeTime : { + future : function (output) { + var affix = /сехет$/i.exec(output) ? "рен" : /çул$/i.exec(output) ? "тан" : "ран"; + return output + affix; + }, + past : "%s каялла", + s : "пĕр-ик çеккунт", + m : "пĕр минут", + mm : "%d минут", + h : "пĕр сехет", + hh : "%d сехет", + d : "пĕр кун", + dd : "%d кун", + M : "пĕр уйăх", + MM : "%d уйăх", + y : "пĕр çул", + yy : "%d çул" + }, + ordinal : '%d-мĕш', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/cy.js b/addons/web/static/lib/moment/locale/cy.js new file mode 100644 index 00000000000..6231a52e51d --- /dev/null +++ b/addons/web/static/lib/moment/locale/cy.js @@ -0,0 +1,77 @@ +// moment.js locale configuration +// locale : Welsh (cy) +// author : Robert Allen + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale("cy", { + months: "Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr".split("_"), + monthsShort: "Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag".split("_"), + weekdays: "Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn".split("_"), + weekdaysShort: "Sul_Llun_Maw_Mer_Iau_Gwe_Sad".split("_"), + weekdaysMin: "Su_Ll_Ma_Me_Ia_Gw_Sa".split("_"), + // time formats are the same as en-gb + longDateFormat: { + LT: "HH:mm", + L: "DD/MM/YYYY", + LL: "D MMMM YYYY", + LLL: "D MMMM YYYY LT", + LLLL: "dddd, D MMMM YYYY LT" + }, + calendar: { + sameDay: '[Heddiw am] LT', + nextDay: '[Yfory am] LT', + nextWeek: 'dddd [am] LT', + lastDay: '[Ddoe am] LT', + lastWeek: 'dddd [diwethaf am] LT', + sameElse: 'L' + }, + relativeTime: { + future: "mewn %s", + past: "%s yn ôl", + s: "ychydig eiliadau", + m: "munud", + mm: "%d munud", + h: "awr", + hh: "%d awr", + d: "diwrnod", + dd: "%d diwrnod", + M: "mis", + MM: "%d mis", + y: "blwyddyn", + yy: "%d flynedd" + }, + // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh + ordinal: function (number) { + var b = number, + output = '', + lookup = [ + '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed + 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed + ]; + + if (b > 20) { + if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) { + output = 'fed'; // not 30ain, 70ain or 90ain + } else { + output = 'ain'; + } + } else if (b > 0) { + output = lookup[b]; + } + + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/da.js b/addons/web/static/lib/moment/locale/da.js new file mode 100644 index 00000000000..9c1c68fab1d --- /dev/null +++ b/addons/web/static/lib/moment/locale/da.js @@ -0,0 +1,56 @@ +// moment.js locale configuration +// locale : danish (da) +// author : Ulrik Nielsen : https://github.com/mrbase + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('da', { + months : "januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"), + monthsShort : "jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"), + weekdays : "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"), + weekdaysShort : "søn_man_tir_ons_tor_fre_lør".split("_"), + weekdaysMin : "sø_ma_ti_on_to_fr_lø".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D. MMMM YYYY", + LLL : "D. MMMM YYYY LT", + LLLL : "dddd [d.] D. MMMM YYYY LT" + }, + calendar : { + sameDay : '[I dag kl.] LT', + nextDay : '[I morgen kl.] LT', + nextWeek : 'dddd [kl.] LT', + lastDay : '[I går kl.] LT', + lastWeek : '[sidste] dddd [kl] LT', + sameElse : 'L' + }, + relativeTime : { + future : "om %s", + past : "%s siden", + s : "få sekunder", + m : "et minut", + mm : "%d minutter", + h : "en time", + hh : "%d timer", + d : "en dag", + dd : "%d dage", + M : "en måned", + MM : "%d måneder", + y : "et år", + yy : "%d år" + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/de-at.js b/addons/web/static/lib/moment/locale/de-at.js new file mode 100644 index 00000000000..48d1b88135b --- /dev/null +++ b/addons/web/static/lib/moment/locale/de-at.js @@ -0,0 +1,72 @@ +// moment.js locale configuration +// locale : austrian german (de-at) +// author : lluchs : https://github.com/lluchs +// author: Menelion Elensúle: https://github.com/Oire +// author : Martin Groller : https://github.com/MadMG + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + + return moment.defineLocale('de-at', { + months : "Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"), + monthsShort : "Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"), + weekdays : "Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"), + weekdaysShort : "So._Mo._Di._Mi._Do._Fr._Sa.".split("_"), + weekdaysMin : "So_Mo_Di_Mi_Do_Fr_Sa".split("_"), + longDateFormat : { + LT: "HH:mm [Uhr]", + L : "DD.MM.YYYY", + LL : "D. MMMM YYYY", + LLL : "D. MMMM YYYY LT", + LLLL : "dddd, D. MMMM YYYY LT" + }, + calendar : { + sameDay: "[Heute um] LT", + sameElse: "L", + nextDay: '[Morgen um] LT', + nextWeek: 'dddd [um] LT', + lastDay: '[Gestern um] LT', + lastWeek: '[letzten] dddd [um] LT' + }, + relativeTime : { + future : "in %s", + past : "vor %s", + s : "ein paar Sekunden", + m : processRelativeTime, + mm : "%d Minuten", + h : processRelativeTime, + hh : "%d Stunden", + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/de.js b/addons/web/static/lib/moment/locale/de.js new file mode 100644 index 00000000000..0c389f92f4d --- /dev/null +++ b/addons/web/static/lib/moment/locale/de.js @@ -0,0 +1,71 @@ +// moment.js locale configuration +// locale : german (de) +// author : lluchs : https://github.com/lluchs +// author: Menelion Elensúle: https://github.com/Oire + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + + return moment.defineLocale('de', { + months : "Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"), + monthsShort : "Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"), + weekdays : "Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"), + weekdaysShort : "So._Mo._Di._Mi._Do._Fr._Sa.".split("_"), + weekdaysMin : "So_Mo_Di_Mi_Do_Fr_Sa".split("_"), + longDateFormat : { + LT: "HH:mm [Uhr]", + L : "DD.MM.YYYY", + LL : "D. MMMM YYYY", + LLL : "D. MMMM YYYY LT", + LLLL : "dddd, D. MMMM YYYY LT" + }, + calendar : { + sameDay: "[Heute um] LT", + sameElse: "L", + nextDay: '[Morgen um] LT', + nextWeek: 'dddd [um] LT', + lastDay: '[Gestern um] LT', + lastWeek: '[letzten] dddd [um] LT' + }, + relativeTime : { + future : "in %s", + past : "vor %s", + s : "ein paar Sekunden", + m : processRelativeTime, + mm : "%d Minuten", + h : processRelativeTime, + hh : "%d Stunden", + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/el.js b/addons/web/static/lib/moment/locale/el.js new file mode 100644 index 00000000000..7f31628d360 --- /dev/null +++ b/addons/web/static/lib/moment/locale/el.js @@ -0,0 +1,90 @@ +// moment.js locale configuration +// locale : modern greek (el) +// author : Aggelos Karalias : https://github.com/mehiel + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('el', { + monthsNominativeEl : "Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος".split("_"), + monthsGenitiveEl : "Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου".split("_"), + months : function (momentToFormat, format) { + if (/D/.test(format.substring(0, format.indexOf("MMMM")))) { // if there is a day number before 'MMMM' + return this._monthsGenitiveEl[momentToFormat.month()]; + } else { + return this._monthsNominativeEl[momentToFormat.month()]; + } + }, + monthsShort : "Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ".split("_"), + weekdays : "Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο".split("_"), + weekdaysShort : "Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ".split("_"), + weekdaysMin : "Κυ_Δε_Τρ_Τε_Πε_Πα_Σα".split("_"), + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'μμ' : 'ΜΜ'; + } else { + return isLower ? 'πμ' : 'ΠΜ'; + } + }, + longDateFormat : { + LT : "h:mm A", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd, D MMMM YYYY LT" + }, + calendarEl : { + sameDay : '[Σήμερα {}] LT', + nextDay : '[Αύριο {}] LT', + nextWeek : 'dddd [{}] LT', + lastDay : '[Χθες {}] LT', + lastWeek : function () { + switch (this.day()) { + case 6: + return '[το προηγούμενο] dddd [{}] LT'; + default: + return '[την προηγούμενη] dddd [{}] LT'; + } + }, + sameElse : 'L' + }, + calendar : function (key, mom) { + var output = this._calendarEl[key], + hours = mom && mom.hours(); + + if (typeof output === 'function') { + output = output.apply(mom); + } + + return output.replace("{}", (hours % 12 === 1 ? "στη" : "στις")); + }, + relativeTime : { + future : "σε %s", + past : "%s πριν", + s : "δευτερόλεπτα", + m : "ένα λεπτό", + mm : "%d λεπτά", + h : "μία ώρα", + hh : "%d ώρες", + d : "μία μέρα", + dd : "%d μέρες", + M : "ένας μήνας", + MM : "%d μήνες", + y : "ένας χρόνος", + yy : "%d χρόνια" + }, + ordinal : function (number) { + return number + 'η'; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/en-au.js b/addons/web/static/lib/moment/locale/en-au.js new file mode 100644 index 00000000000..852ecc9f033 --- /dev/null +++ b/addons/web/static/lib/moment/locale/en-au.js @@ -0,0 +1,62 @@ +// moment.js locale configuration +// locale : australian english (en-au) + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('en-au', { + months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), + monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), + weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), + weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), + weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), + longDateFormat : { + LT : "h:mm A", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd, D MMMM YYYY LT" + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : "in %s", + past : "%s ago", + s : "a few seconds", + m : "a minute", + mm : "%d minutes", + h : "an hour", + hh : "%d hours", + d : "a day", + dd : "%d days", + M : "a month", + MM : "%d months", + y : "a year", + yy : "%d years" + }, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/en-ca.js b/addons/web/static/lib/moment/locale/en-ca.js new file mode 100644 index 00000000000..ce253a83355 --- /dev/null +++ b/addons/web/static/lib/moment/locale/en-ca.js @@ -0,0 +1,59 @@ +// moment.js locale configuration +// locale : canadian english (en-ca) +// author : Jonathan Abourbih : https://github.com/jonbca + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('en-ca', { + months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), + monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), + weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), + weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), + weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), + longDateFormat : { + LT : "h:mm A", + L : "YYYY-MM-DD", + LL : "D MMMM, YYYY", + LLL : "D MMMM, YYYY LT", + LLLL : "dddd, D MMMM, YYYY LT" + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : "in %s", + past : "%s ago", + s : "a few seconds", + m : "a minute", + mm : "%d minutes", + h : "an hour", + hh : "%d hours", + d : "a day", + dd : "%d days", + M : "a month", + MM : "%d months", + y : "a year", + yy : "%d years" + }, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/en-gb.js b/addons/web/static/lib/moment/locale/en-gb.js new file mode 100644 index 00000000000..14ccbab3ed8 --- /dev/null +++ b/addons/web/static/lib/moment/locale/en-gb.js @@ -0,0 +1,63 @@ +// moment.js locale configuration +// locale : great britain english (en-gb) +// author : Chris Gedrim : https://github.com/chrisgedrim + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('en-gb', { + months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), + monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), + weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), + weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), + weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd, D MMMM YYYY LT" + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : "in %s", + past : "%s ago", + s : "a few seconds", + m : "a minute", + mm : "%d minutes", + h : "an hour", + hh : "%d hours", + d : "a day", + dd : "%d days", + M : "a month", + MM : "%d months", + y : "a year", + yy : "%d years" + }, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/eo.js b/addons/web/static/lib/moment/locale/eo.js new file mode 100644 index 00000000000..318385b9502 --- /dev/null +++ b/addons/web/static/lib/moment/locale/eo.js @@ -0,0 +1,65 @@ +// moment.js locale configuration +// locale : esperanto (eo) +// author : Colin Dean : https://github.com/colindean +// komento: Mi estas malcerta se mi korekte traktis akuzativojn en tiu traduko. +// Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni! + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('eo', { + months : "januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro".split("_"), + monthsShort : "jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec".split("_"), + weekdays : "Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato".split("_"), + weekdaysShort : "Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab".split("_"), + weekdaysMin : "Di_Lu_Ma_Me_Ĵa_Ve_Sa".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "YYYY-MM-DD", + LL : "D[-an de] MMMM, YYYY", + LLL : "D[-an de] MMMM, YYYY LT", + LLLL : "dddd, [la] D[-an de] MMMM, YYYY LT" + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'p.t.m.' : 'P.T.M.'; + } else { + return isLower ? 'a.t.m.' : 'A.T.M.'; + } + }, + calendar : { + sameDay : '[Hodiaŭ je] LT', + nextDay : '[Morgaŭ je] LT', + nextWeek : 'dddd [je] LT', + lastDay : '[Hieraŭ je] LT', + lastWeek : '[pasinta] dddd [je] LT', + sameElse : 'L' + }, + relativeTime : { + future : "je %s", + past : "antaŭ %s", + s : "sekundoj", + m : "minuto", + mm : "%d minutoj", + h : "horo", + hh : "%d horoj", + d : "tago",//ne 'diurno', ĉar estas uzita por proksimumo + dd : "%d tagoj", + M : "monato", + MM : "%d monatoj", + y : "jaro", + yy : "%d jaroj" + }, + ordinal : "%da", + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/es.js b/addons/web/static/lib/moment/locale/es.js new file mode 100644 index 00000000000..ed0b5644506 --- /dev/null +++ b/addons/web/static/lib/moment/locale/es.js @@ -0,0 +1,75 @@ +// moment.js locale configuration +// locale : spanish (es) +// author : Julio Napurí : https://github.com/julionc + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var monthsShortDot = "ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"), + monthsShort = "ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"); + + return moment.defineLocale('es', { + months : "enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"), + monthsShort : function (m, format) { + if (/-MMM-/.test(format)) { + return monthsShort[m.month()]; + } else { + return monthsShortDot[m.month()]; + } + }, + weekdays : "domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"), + weekdaysShort : "dom._lun._mar._mié._jue._vie._sáb.".split("_"), + weekdaysMin : "Do_Lu_Ma_Mi_Ju_Vi_Sá".split("_"), + longDateFormat : { + LT : "H:mm", + L : "DD/MM/YYYY", + LL : "D [de] MMMM [del] YYYY", + LLL : "D [de] MMMM [del] YYYY LT", + LLLL : "dddd, D [de] MMMM [del] YYYY LT" + }, + calendar : { + sameDay : function () { + return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextDay : function () { + return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastDay : function () { + return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : "en %s", + past : "hace %s", + s : "unos segundos", + m : "un minuto", + mm : "%d minutos", + h : "una hora", + hh : "%d horas", + d : "un día", + dd : "%d días", + M : "un mes", + MM : "%d meses", + y : "un año", + yy : "%d años" + }, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/et.js b/addons/web/static/lib/moment/locale/et.js new file mode 100644 index 00000000000..2241529d231 --- /dev/null +++ b/addons/web/static/lib/moment/locale/et.js @@ -0,0 +1,76 @@ +// moment.js locale configuration +// locale : estonian (et) +// author : Henry Kehlmann : https://github.com/madhenry +// improvements : Illimar Tambek : https://github.com/ragulka + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'], + 'm' : ['ühe minuti', 'üks minut'], + 'mm': [number + ' minuti', number + ' minutit'], + 'h' : ['ühe tunni', 'tund aega', 'üks tund'], + 'hh': [number + ' tunni', number + ' tundi'], + 'd' : ['ühe päeva', 'üks päev'], + 'M' : ['kuu aja', 'kuu aega', 'üks kuu'], + 'MM': [number + ' kuu', number + ' kuud'], + 'y' : ['ühe aasta', 'aasta', 'üks aasta'], + 'yy': [number + ' aasta', number + ' aastat'] + }; + if (withoutSuffix) { + return format[key][2] ? format[key][2] : format[key][1]; + } + return isFuture ? format[key][0] : format[key][1]; + } + + return moment.defineLocale('et', { + months : "jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"), + monthsShort : "jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"), + weekdays : "pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev".split("_"), + weekdaysShort : "P_E_T_K_N_R_L".split("_"), + weekdaysMin : "P_E_T_K_N_R_L".split("_"), + longDateFormat : { + LT : "H:mm", + L : "DD.MM.YYYY", + LL : "D. MMMM YYYY", + LLL : "D. MMMM YYYY LT", + LLLL : "dddd, D. MMMM YYYY LT" + }, + calendar : { + sameDay : '[Täna,] LT', + nextDay : '[Homme,] LT', + nextWeek : '[Järgmine] dddd LT', + lastDay : '[Eile,] LT', + lastWeek : '[Eelmine] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s pärast", + past : "%s tagasi", + s : processRelativeTime, + m : processRelativeTime, + mm : processRelativeTime, + h : processRelativeTime, + hh : processRelativeTime, + d : processRelativeTime, + dd : '%d päeva', + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/eu.js b/addons/web/static/lib/moment/locale/eu.js new file mode 100644 index 00000000000..fe2dddb7bf6 --- /dev/null +++ b/addons/web/static/lib/moment/locale/eu.js @@ -0,0 +1,60 @@ +// moment.js locale configuration +// locale : euskara (eu) +// author : Eneko Illarramendi : https://github.com/eillarra + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('eu', { + months : "urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"), + monthsShort : "urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"), + weekdays : "igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"), + weekdaysShort : "ig._al._ar._az._og._ol._lr.".split("_"), + weekdaysMin : "ig_al_ar_az_og_ol_lr".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "YYYY-MM-DD", + LL : "YYYY[ko] MMMM[ren] D[a]", + LLL : "YYYY[ko] MMMM[ren] D[a] LT", + LLLL : "dddd, YYYY[ko] MMMM[ren] D[a] LT", + l : "YYYY-M-D", + ll : "YYYY[ko] MMM D[a]", + lll : "YYYY[ko] MMM D[a] LT", + llll : "ddd, YYYY[ko] MMM D[a] LT" + }, + calendar : { + sameDay : '[gaur] LT[etan]', + nextDay : '[bihar] LT[etan]', + nextWeek : 'dddd LT[etan]', + lastDay : '[atzo] LT[etan]', + lastWeek : '[aurreko] dddd LT[etan]', + sameElse : 'L' + }, + relativeTime : { + future : "%s barru", + past : "duela %s", + s : "segundo batzuk", + m : "minutu bat", + mm : "%d minutu", + h : "ordu bat", + hh : "%d ordu", + d : "egun bat", + dd : "%d egun", + M : "hilabete bat", + MM : "%d hilabete", + y : "urte bat", + yy : "%d urte" + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/fa.js b/addons/web/static/lib/moment/locale/fa.js new file mode 100644 index 00000000000..09c7909514f --- /dev/null +++ b/addons/web/static/lib/moment/locale/fa.js @@ -0,0 +1,97 @@ +// moment.js locale configuration +// locale : Persian +// author : Ebrahim Byagowi : https://github.com/ebraminio + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var symbolMap = { + '1': '۱', + '2': '۲', + '3': '۳', + '4': '۴', + '5': '۵', + '6': '۶', + '7': '۷', + '8': '۸', + '9': '۹', + '0': '۰' + }, numberMap = { + '۱': '1', + '۲': '2', + '۳': '3', + '۴': '4', + '۵': '5', + '۶': '6', + '۷': '7', + '۸': '8', + '۹': '9', + '۰': '0' + }; + + return moment.defineLocale('fa', { + months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), + monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), + weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), + weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), + weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'), + longDateFormat : { + LT : 'HH:mm', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY LT', + LLLL : 'dddd, D MMMM YYYY LT' + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return "قبل از ظهر"; + } else { + return "بعد از ظهر"; + } + }, + calendar : { + sameDay : '[امروز ساعت] LT', + nextDay : '[فردا ساعت] LT', + nextWeek : 'dddd [ساعت] LT', + lastDay : '[دیروز ساعت] LT', + lastWeek : 'dddd [پیش] [ساعت] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'در %s', + past : '%s پیش', + s : 'چندین ثانیه', + m : 'یک دقیقه', + mm : '%d دقیقه', + h : 'یک ساعت', + hh : '%d ساعت', + d : 'یک روز', + dd : '%d روز', + M : 'یک ماه', + MM : '%d ماه', + y : 'یک سال', + yy : '%d سال' + }, + preparse: function (string) { + return string.replace(/[۰-۹]/g, function (match) { + return numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, + ordinal : '%dم', + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/fi.js b/addons/web/static/lib/moment/locale/fi.js new file mode 100644 index 00000000000..2afc5e89ac6 --- /dev/null +++ b/addons/web/static/lib/moment/locale/fi.js @@ -0,0 +1,105 @@ +// moment.js locale configuration +// locale : finnish (fi) +// author : Tarmo Aidantausta : https://github.com/bleadof + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '), + numbersFuture = [ + 'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden', + numbersPast[7], numbersPast[8], numbersPast[9] + ]; + + function translate(number, withoutSuffix, key, isFuture) { + var result = ""; + switch (key) { + case 's': + return isFuture ? 'muutaman sekunnin' : 'muutama sekunti'; + case 'm': + return isFuture ? 'minuutin' : 'minuutti'; + case 'mm': + result = isFuture ? 'minuutin' : 'minuuttia'; + break; + case 'h': + return isFuture ? 'tunnin' : 'tunti'; + case 'hh': + result = isFuture ? 'tunnin' : 'tuntia'; + break; + case 'd': + return isFuture ? 'päivän' : 'päivä'; + case 'dd': + result = isFuture ? 'päivän' : 'päivää'; + break; + case 'M': + return isFuture ? 'kuukauden' : 'kuukausi'; + case 'MM': + result = isFuture ? 'kuukauden' : 'kuukautta'; + break; + case 'y': + return isFuture ? 'vuoden' : 'vuosi'; + case 'yy': + result = isFuture ? 'vuoden' : 'vuotta'; + break; + } + result = verbalNumber(number, isFuture) + " " + result; + return result; + } + + function verbalNumber(number, isFuture) { + return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number; + } + + return moment.defineLocale('fi', { + months : "tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"), + monthsShort : "tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"), + weekdays : "sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"), + weekdaysShort : "su_ma_ti_ke_to_pe_la".split("_"), + weekdaysMin : "su_ma_ti_ke_to_pe_la".split("_"), + longDateFormat : { + LT : "HH.mm", + L : "DD.MM.YYYY", + LL : "Do MMMM[ta] YYYY", + LLL : "Do MMMM[ta] YYYY, [klo] LT", + LLLL : "dddd, Do MMMM[ta] YYYY, [klo] LT", + l : "D.M.YYYY", + ll : "Do MMM YYYY", + lll : "Do MMM YYYY, [klo] LT", + llll : "ddd, Do MMM YYYY, [klo] LT" + }, + calendar : { + sameDay : '[tänään] [klo] LT', + nextDay : '[huomenna] [klo] LT', + nextWeek : 'dddd [klo] LT', + lastDay : '[eilen] [klo] LT', + lastWeek : '[viime] dddd[na] [klo] LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s päästä", + past : "%s sitten", + s : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + ordinal : "%d.", + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/fo.js b/addons/web/static/lib/moment/locale/fo.js new file mode 100644 index 00000000000..cdc9eda1647 --- /dev/null +++ b/addons/web/static/lib/moment/locale/fo.js @@ -0,0 +1,56 @@ +// moment.js locale configuration +// locale : faroese (fo) +// author : Ragnar Johannesen : https://github.com/ragnar123 + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('fo', { + months : "januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember".split("_"), + monthsShort : "jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"), + weekdays : "sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur".split("_"), + weekdaysShort : "sun_mán_týs_mik_hós_frí_ley".split("_"), + weekdaysMin : "su_má_tý_mi_hó_fr_le".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D. MMMM, YYYY LT" + }, + calendar : { + sameDay : '[Í dag kl.] LT', + nextDay : '[Í morgin kl.] LT', + nextWeek : 'dddd [kl.] LT', + lastDay : '[Í gjár kl.] LT', + lastWeek : '[síðstu] dddd [kl] LT', + sameElse : 'L' + }, + relativeTime : { + future : "um %s", + past : "%s síðani", + s : "fá sekund", + m : "ein minutt", + mm : "%d minuttir", + h : "ein tími", + hh : "%d tímar", + d : "ein dagur", + dd : "%d dagar", + M : "ein mánaði", + MM : "%d mánaðir", + y : "eitt ár", + yy : "%d ár" + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/fr-ca.js b/addons/web/static/lib/moment/locale/fr-ca.js new file mode 100644 index 00000000000..714b11b2bfe --- /dev/null +++ b/addons/web/static/lib/moment/locale/fr-ca.js @@ -0,0 +1,54 @@ +// moment.js locale configuration +// locale : canadian french (fr-ca) +// author : Jonathan Abourbih : https://github.com/jonbca + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('fr-ca', { + months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"), + monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"), + 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("_"), + longDateFormat : { + LT : "HH:mm", + L : "YYYY-MM-DD", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D MMMM YYYY LT" + }, + calendar : { + sameDay: "[Aujourd'hui à] LT", + nextDay: '[Demain à] LT', + nextWeek: 'dddd [à] LT', + lastDay: '[Hier à] LT', + lastWeek: 'dddd [dernier à] LT', + sameElse: 'L' + }, + relativeTime : { + future : "dans %s", + past : "il y a %s", + s : "quelques secondes", + m : "une minute", + mm : "%d minutes", + h : "une heure", + hh : "%d heures", + d : "un jour", + dd : "%d jours", + M : "un mois", + MM : "%d mois", + y : "un an", + yy : "%d ans" + }, + ordinal : function (number) { + return number + (number === 1 ? 'er' : ''); + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/fr.js b/addons/web/static/lib/moment/locale/fr.js new file mode 100644 index 00000000000..106ab11bee4 --- /dev/null +++ b/addons/web/static/lib/moment/locale/fr.js @@ -0,0 +1,58 @@ +// moment.js locale configuration +// locale : french (fr) +// author : John Fischer : https://github.com/jfroffice + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('fr', { + months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"), + monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"), + 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("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D MMMM YYYY LT" + }, + calendar : { + sameDay: "[Aujourd'hui à] LT", + nextDay: '[Demain à] LT', + nextWeek: 'dddd [à] LT', + lastDay: '[Hier à] LT', + lastWeek: 'dddd [dernier à] LT', + sameElse: 'L' + }, + relativeTime : { + future : "dans %s", + past : "il y a %s", + s : "quelques secondes", + m : "une minute", + mm : "%d minutes", + h : "une heure", + hh : "%d heures", + d : "un jour", + dd : "%d jours", + M : "un mois", + MM : "%d mois", + y : "un an", + yy : "%d ans" + }, + ordinal : function (number) { + return number + (number === 1 ? 'er' : ''); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/gl.js b/addons/web/static/lib/moment/locale/gl.js new file mode 100644 index 00000000000..e82065f33dc --- /dev/null +++ b/addons/web/static/lib/moment/locale/gl.js @@ -0,0 +1,71 @@ +// moment.js locale configuration +// locale : galician (gl) +// author : Juan G. Hurtado : https://github.com/juanghurtado + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('gl', { + months : "Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro".split("_"), + monthsShort : "Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.".split("_"), + weekdays : "Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado".split("_"), + weekdaysShort : "Dom._Lun._Mar._Mér._Xov._Ven._Sáb.".split("_"), + weekdaysMin : "Do_Lu_Ma_Mé_Xo_Ve_Sá".split("_"), + longDateFormat : { + LT : "H:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D MMMM YYYY LT" + }, + calendar : { + sameDay : function () { + return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; + }, + nextDay : function () { + return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; + }, + nextWeek : function () { + return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; + }, + lastDay : function () { + return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT'; + }, + lastWeek : function () { + return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : function (str) { + if (str === "uns segundos") { + return "nuns segundos"; + } + return "en " + str; + }, + past : "hai %s", + s : "uns segundos", + m : "un minuto", + mm : "%d minutos", + h : "unha hora", + hh : "%d horas", + d : "un día", + dd : "%d días", + M : "un mes", + MM : "%d meses", + y : "un ano", + yy : "%d anos" + }, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/he.js b/addons/web/static/lib/moment/locale/he.js new file mode 100644 index 00000000000..0af4e0988d5 --- /dev/null +++ b/addons/web/static/lib/moment/locale/he.js @@ -0,0 +1,77 @@ +// moment.js locale configuration +// locale : Hebrew (he) +// author : Tomer Cohen : https://github.com/tomer +// author : Moshe Simantov : https://github.com/DevelopmentIL +// author : Tal Ater : https://github.com/TalAter + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('he', { + months : "ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"), + monthsShort : "ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳".split("_"), + weekdays : "ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת".split("_"), + weekdaysShort : "א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳".split("_"), + weekdaysMin : "א_ב_ג_ד_ה_ו_ש".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D [ב]MMMM YYYY", + LLL : "D [ב]MMMM YYYY LT", + LLLL : "dddd, D [ב]MMMM YYYY LT", + l : "D/M/YYYY", + ll : "D MMM YYYY", + lll : "D MMM YYYY LT", + llll : "ddd, D MMM YYYY LT" + }, + calendar : { + sameDay : '[היום ב־]LT', + nextDay : '[מחר ב־]LT', + nextWeek : 'dddd [בשעה] LT', + lastDay : '[אתמול ב־]LT', + lastWeek : '[ביום] dddd [האחרון בשעה] LT', + sameElse : 'L' + }, + relativeTime : { + future : "בעוד %s", + past : "לפני %s", + s : "מספר שניות", + m : "דקה", + mm : "%d דקות", + h : "שעה", + hh : function (number) { + if (number === 2) { + return "שעתיים"; + } + return number + " שעות"; + }, + d : "יום", + dd : function (number) { + if (number === 2) { + return "יומיים"; + } + return number + " ימים"; + }, + M : "חודש", + MM : function (number) { + if (number === 2) { + return "חודשיים"; + } + return number + " חודשים"; + }, + y : "שנה", + yy : function (number) { + if (number === 2) { + return "שנתיים"; + } + return number + " שנים"; + } + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/hi.js b/addons/web/static/lib/moment/locale/hi.js new file mode 100644 index 00000000000..6dd7098c27d --- /dev/null +++ b/addons/web/static/lib/moment/locale/hi.js @@ -0,0 +1,105 @@ +// moment.js locale configuration +// locale : hindi (hi) +// author : Mayank Singhal : https://github.com/mayanksinghal + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var symbolMap = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' + }, + numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' + }; + + return moment.defineLocale('hi', { + months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split("_"), + monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split("_"), + weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split("_"), + weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split("_"), + weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split("_"), + longDateFormat : { + LT : "A h:mm बजे", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY, LT", + LLLL : "dddd, D MMMM YYYY, LT" + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[कल] LT', + nextWeek : 'dddd, LT', + lastDay : '[कल] LT', + lastWeek : '[पिछले] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s में", + past : "%s पहले", + s : "कुछ ही क्षण", + m : "एक मिनट", + mm : "%d मिनट", + h : "एक घंटा", + hh : "%d घंटे", + d : "एक दिन", + dd : "%d दिन", + M : "एक महीने", + MM : "%d महीने", + y : "एक वर्ष", + yy : "%d वर्ष" + }, + 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]; + }); + }, + // Hindi notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi. + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return "रात"; + } else if (hour < 10) { + return "सुबह"; + } else if (hour < 17) { + return "दोपहर"; + } else if (hour < 20) { + return "शाम"; + } else { + return "रात"; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/hr.js b/addons/web/static/lib/moment/locale/hr.js new file mode 100644 index 00000000000..20fe8c1d662 --- /dev/null +++ b/addons/web/static/lib/moment/locale/hr.js @@ -0,0 +1,139 @@ +// moment.js locale configuration +// locale : hrvatski (hr) +// author : Bojan Marković : https://github.com/bmarkovic + +// based on (sl) translation by Robert Sedovšek + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function translate(number, withoutSuffix, key) { + var result = number + " "; + switch (key) { + case 'm': + return withoutSuffix ? 'jedna minuta' : 'jedne minute'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minuta'; + } + return result; + case 'h': + return withoutSuffix ? 'jedan sat' : 'jednog sata'; + case 'hh': + if (number === 1) { + result += 'sat'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sata'; + } else { + result += 'sati'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dana'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mjesec'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'mjeseca'; + } else { + result += 'mjeseci'; + } + return result; + case 'yy': + if (number === 1) { + result += 'godina'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'godine'; + } else { + result += 'godina'; + } + return result; + } + } + + return moment.defineLocale('hr', { + months : "sječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_"), + monthsShort : "sje._vel._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"), + weekdays : "nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"), + weekdaysShort : "ned._pon._uto._sri._čet._pet._sub.".split("_"), + weekdaysMin : "ne_po_ut_sr_če_pe_su".split("_"), + longDateFormat : { + LT : "H:mm", + L : "DD. MM. YYYY", + LL : "D. MMMM YYYY", + LLL : "D. MMMM YYYY LT", + LLLL : "dddd, D. MMMM YYYY LT" + }, + calendar : { + sameDay : '[danas u] LT', + nextDay : '[sutra u] LT', + + nextWeek : function () { + switch (this.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'; + } + }, + lastDay : '[jučer u] LT', + lastWeek : function () { + switch (this.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'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : "za %s", + past : "prije %s", + s : "par sekundi", + m : translate, + mm : translate, + h : translate, + hh : translate, + d : "dan", + dd : translate, + M : "mjesec", + MM : translate, + y : "godinu", + yy : translate + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/hu.js b/addons/web/static/lib/moment/locale/hu.js new file mode 100644 index 00000000000..910f0868b5a --- /dev/null +++ b/addons/web/static/lib/moment/locale/hu.js @@ -0,0 +1,105 @@ +// moment.js locale configuration +// locale : hungarian (hu) +// author : Adam Brunner : https://github.com/adambrunner + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' '); + + function translate(number, withoutSuffix, key, isFuture) { + var num = number, + suffix; + + switch (key) { + case 's': + return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce'; + case 'm': + return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce'); + case 'mm': + return num + (isFuture || withoutSuffix ? ' perc' : ' perce'); + case 'h': + return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája'); + case 'hh': + return num + (isFuture || withoutSuffix ? ' óra' : ' órája'); + case 'd': + return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja'); + case 'dd': + return num + (isFuture || withoutSuffix ? ' nap' : ' napja'); + case 'M': + return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); + case 'MM': + return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); + case 'y': + return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve'); + case 'yy': + return num + (isFuture || withoutSuffix ? ' év' : ' éve'); + } + + return ''; + } + + function week(isFuture) { + return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]'; + } + + return moment.defineLocale('hu', { + months : "január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"), + monthsShort : "jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec".split("_"), + weekdays : "vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"), + weekdaysShort : "vas_hét_kedd_sze_csüt_pén_szo".split("_"), + weekdaysMin : "v_h_k_sze_cs_p_szo".split("_"), + longDateFormat : { + LT : "H:mm", + L : "YYYY.MM.DD.", + LL : "YYYY. MMMM D.", + LLL : "YYYY. MMMM D., LT", + LLLL : "YYYY. MMMM D., dddd LT" + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower === true ? 'de' : 'DE'; + } else { + return isLower === true ? 'du' : 'DU'; + } + }, + calendar : { + sameDay : '[ma] LT[-kor]', + nextDay : '[holnap] LT[-kor]', + nextWeek : function () { + return week.call(this, true); + }, + lastDay : '[tegnap] LT[-kor]', + lastWeek : function () { + return week.call(this, false); + }, + sameElse : 'L' + }, + relativeTime : { + future : "%s múlva", + past : "%s", + s : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/hy-am.js b/addons/web/static/lib/moment/locale/hy-am.js new file mode 100644 index 00000000000..b6984a2794a --- /dev/null +++ b/addons/web/static/lib/moment/locale/hy-am.js @@ -0,0 +1,112 @@ +// moment.js locale configuration +// locale : Armenian (hy-am) +// author : Armendarabyan : https://github.com/armendarabyan + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function monthsCaseReplace(m, format) { + var months = { + 'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'), + 'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_') + }, + + nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ? + 'accusative' : + 'nominative'; + + return months[nounCase][m.month()]; + } + + function monthsShortCaseReplace(m, format) { + var monthsShort = 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'); + + return monthsShort[m.month()]; + } + + function weekdaysCaseReplace(m, format) { + var weekdays = 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'); + + return weekdays[m.day()]; + } + + return moment.defineLocale('hy-am', { + months : monthsCaseReplace, + monthsShort : monthsShortCaseReplace, + weekdays : weekdaysCaseReplace, + weekdaysShort : "կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"), + weekdaysMin : "կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD.MM.YYYY", + LL : "D MMMM YYYY թ.", + LLL : "D MMMM YYYY թ., LT", + LLLL : "dddd, D MMMM YYYY թ., LT" + }, + calendar : { + sameDay: '[այսօր] LT', + nextDay: '[վաղը] LT', + lastDay: '[երեկ] LT', + nextWeek: function () { + return 'dddd [օրը ժամը] LT'; + }, + lastWeek: function () { + return '[անցած] dddd [օրը ժամը] LT'; + }, + sameElse: 'L' + }, + relativeTime : { + future : "%s հետո", + past : "%s առաջ", + s : "մի քանի վայրկյան", + m : "րոպե", + mm : "%d րոպե", + h : "ժամ", + hh : "%d ժամ", + d : "օր", + dd : "%d օր", + M : "ամիս", + MM : "%d ամիս", + y : "տարի", + yy : "%d տարի" + }, + + meridiem : function (hour) { + if (hour < 4) { + return "գիշերվա"; + } else if (hour < 12) { + return "առավոտվա"; + } else if (hour < 17) { + return "ցերեկվա"; + } else { + return "երեկոյան"; + } + }, + + ordinal: function (number, period) { + switch (period) { + case 'DDD': + case 'w': + case 'W': + case 'DDDo': + if (number === 1) { + return number + '-ին'; + } + return number + '-րդ'; + default: + return number; + } + }, + + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/id.js b/addons/web/static/lib/moment/locale/id.js new file mode 100644 index 00000000000..6043f30a239 --- /dev/null +++ b/addons/web/static/lib/moment/locale/id.js @@ -0,0 +1,67 @@ +// moment.js locale configuration +// locale : Bahasa Indonesia (id) +// author : Mohammad Satrio Utomo : https://github.com/tyok +// reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('id', { + months : "Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"), + monthsShort : "Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des".split("_"), + weekdays : "Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"), + weekdaysShort : "Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"), + weekdaysMin : "Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"), + longDateFormat : { + LT : "HH.mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY [pukul] LT", + LLLL : "dddd, D MMMM YYYY [pukul] LT" + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'siang'; + } else if (hours < 19) { + return 'sore'; + } else { + return 'malam'; + } + }, + calendar : { + sameDay : '[Hari ini pukul] LT', + nextDay : '[Besok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kemarin pukul] LT', + lastWeek : 'dddd [lalu pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : "dalam %s", + past : "%s yang lalu", + s : "beberapa detik", + m : "semenit", + mm : "%d menit", + h : "sejam", + hh : "%d jam", + d : "sehari", + dd : "%d hari", + M : "sebulan", + MM : "%d bulan", + y : "setahun", + yy : "%d tahun" + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/is.js b/addons/web/static/lib/moment/locale/is.js new file mode 100644 index 00000000000..ed2240644f9 --- /dev/null +++ b/addons/web/static/lib/moment/locale/is.js @@ -0,0 +1,124 @@ +// moment.js locale configuration +// locale : icelandic (is) +// author : Hinrik Örn Sigurðsson : https://github.com/hinrik + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function plural(n) { + if (n % 100 === 11) { + return true; + } else if (n % 10 === 1) { + return false; + } + return true; + } + + function translate(number, withoutSuffix, key, isFuture) { + var result = number + " "; + switch (key) { + case 's': + return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum'; + case 'm': + return withoutSuffix ? 'mínúta' : 'mínútu'; + case 'mm': + if (plural(number)) { + return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum'); + } else if (withoutSuffix) { + return result + 'mínúta'; + } + return result + 'mínútu'; + case 'hh': + if (plural(number)) { + return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum'); + } + return result + 'klukkustund'; + case 'd': + if (withoutSuffix) { + return 'dagur'; + } + return isFuture ? 'dag' : 'degi'; + case 'dd': + if (plural(number)) { + if (withoutSuffix) { + return result + 'dagar'; + } + return result + (isFuture ? 'daga' : 'dögum'); + } else if (withoutSuffix) { + return result + 'dagur'; + } + return result + (isFuture ? 'dag' : 'degi'); + case 'M': + if (withoutSuffix) { + return 'mánuður'; + } + return isFuture ? 'mánuð' : 'mánuði'; + case 'MM': + if (plural(number)) { + if (withoutSuffix) { + return result + 'mánuðir'; + } + return result + (isFuture ? 'mánuði' : 'mánuðum'); + } else if (withoutSuffix) { + return result + 'mánuður'; + } + return result + (isFuture ? 'mánuð' : 'mánuði'); + case 'y': + return withoutSuffix || isFuture ? 'ár' : 'ári'; + case 'yy': + if (plural(number)) { + return result + (withoutSuffix || isFuture ? 'ár' : 'árum'); + } + return result + (withoutSuffix || isFuture ? 'ár' : 'ári'); + } + } + + return moment.defineLocale('is', { + months : "janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember".split("_"), + monthsShort : "jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des".split("_"), + weekdays : "sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur".split("_"), + weekdaysShort : "sun_mán_þri_mið_fim_fös_lau".split("_"), + weekdaysMin : "Su_Má_Þr_Mi_Fi_Fö_La".split("_"), + longDateFormat : { + LT : "H:mm", + L : "DD/MM/YYYY", + LL : "D. MMMM YYYY", + LLL : "D. MMMM YYYY [kl.] LT", + LLLL : "dddd, D. MMMM YYYY [kl.] LT" + }, + calendar : { + sameDay : '[í dag kl.] LT', + nextDay : '[á morgun kl.] LT', + nextWeek : 'dddd [kl.] LT', + lastDay : '[í gær kl.] LT', + lastWeek : '[síðasta] dddd [kl.] LT', + sameElse : 'L' + }, + relativeTime : { + future : "eftir %s", + past : "fyrir %s síðan", + s : translate, + m : translate, + mm : translate, + h : "klukkustund", + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/it.js b/addons/web/static/lib/moment/locale/it.js new file mode 100644 index 00000000000..a151ccc62ae --- /dev/null +++ b/addons/web/static/lib/moment/locale/it.js @@ -0,0 +1,59 @@ +// moment.js locale configuration +// locale : italian (it) +// author : Lorenzo : https://github.com/aliem +// author: Mattia Larentis: https://github.com/nostalgiaz + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('it', { + months : "gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"), + monthsShort : "gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"), + weekdays : "Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato".split("_"), + weekdaysShort : "Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"), + weekdaysMin : "D_L_Ma_Me_G_V_S".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd, D MMMM YYYY LT" + }, + calendar : { + sameDay: '[Oggi alle] LT', + nextDay: '[Domani alle] LT', + nextWeek: 'dddd [alle] LT', + lastDay: '[Ieri alle] LT', + lastWeek: '[lo scorso] dddd [alle] LT', + sameElse: 'L' + }, + relativeTime : { + future : function (s) { + return ((/^[0-9].+$/).test(s) ? "tra" : "in") + " " + s; + }, + past : "%s fa", + s : "alcuni secondi", + m : "un minuto", + mm : "%d minuti", + h : "un'ora", + hh : "%d ore", + d : "un giorno", + dd : "%d giorni", + M : "un mese", + MM : "%d mesi", + y : "un anno", + yy : "%d anni" + }, + ordinal: '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ja.js b/addons/web/static/lib/moment/locale/ja.js new file mode 100644 index 00000000000..34c4b890d8e --- /dev/null +++ b/addons/web/static/lib/moment/locale/ja.js @@ -0,0 +1,58 @@ +// moment.js locale configuration +// locale : japanese (ja) +// author : LI Long : https://github.com/baryon + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('ja', { + months : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), + monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), + weekdays : "日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"), + weekdaysShort : "日_月_火_水_木_金_土".split("_"), + weekdaysMin : "日_月_火_水_木_金_土".split("_"), + longDateFormat : { + LT : "Ah時m分", + L : "YYYY/MM/DD", + LL : "YYYY年M月D日", + LLL : "YYYY年M月D日LT", + LLLL : "YYYY年M月D日LT dddd" + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return "午前"; + } else { + return "午後"; + } + }, + calendar : { + sameDay : '[今日] LT', + nextDay : '[明日] LT', + nextWeek : '[来週]dddd LT', + lastDay : '[昨日] LT', + lastWeek : '[前週]dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s後", + past : "%s前", + s : "数秒", + m : "1分", + mm : "%d分", + h : "1時間", + hh : "%d時間", + d : "1日", + dd : "%d日", + M : "1ヶ月", + MM : "%dヶ月", + y : "1年", + yy : "%d年" + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ka.js b/addons/web/static/lib/moment/locale/ka.js new file mode 100644 index 00000000000..31345243644 --- /dev/null +++ b/addons/web/static/lib/moment/locale/ka.js @@ -0,0 +1,107 @@ +// moment.js locale configuration +// locale : Georgian (ka) +// author : Irakli Janiashvili : https://github.com/irakli-janiashvili + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function monthsCaseReplace(m, format) { + var months = { + 'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'), + 'accusative': 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_') + }, + + nounCase = (/D[oD] *MMMM?/).test(format) ? + 'accusative' : + 'nominative'; + + return months[nounCase][m.month()]; + } + + function weekdaysCaseReplace(m, format) { + var weekdays = { + 'nominative': 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'), + 'accusative': 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_') + }, + + nounCase = (/(წინა|შემდეგ)/).test(format) ? + 'accusative' : + 'nominative'; + + return weekdays[nounCase][m.day()]; + } + + return moment.defineLocale('ka', { + months : monthsCaseReplace, + monthsShort : "იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ".split("_"), + weekdays : weekdaysCaseReplace, + weekdaysShort : "კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ".split("_"), + weekdaysMin : "კვ_ორ_სა_ოთ_ხუ_პა_შა".split("_"), + longDateFormat : { + LT : "h:mm A", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd, D MMMM YYYY LT" + }, + calendar : { + sameDay : '[დღეს] LT[-ზე]', + nextDay : '[ხვალ] LT[-ზე]', + lastDay : '[გუშინ] LT[-ზე]', + nextWeek : '[შემდეგ] dddd LT[-ზე]', + lastWeek : '[წინა] dddd LT-ზე', + sameElse : 'L' + }, + relativeTime : { + future : function (s) { + return (/(წამი|წუთი|საათი|წელი)/).test(s) ? + s.replace(/ი$/, "ში") : + s + "ში"; + }, + past : function (s) { + if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) { + return s.replace(/(ი|ე)$/, "ის წინ"); + } + if ((/წელი/).test(s)) { + return s.replace(/წელი$/, "წლის წინ"); + } + }, + s : "რამდენიმე წამი", + m : "წუთი", + mm : "%d წუთი", + h : "საათი", + hh : "%d საათი", + d : "დღე", + dd : "%d დღე", + M : "თვე", + MM : "%d თვე", + y : "წელი", + yy : "%d წელი" + }, + ordinal : function (number) { + if (number === 0) { + return number; + } + + if (number === 1) { + return number + "-ლი"; + } + + if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) { + return "მე-" + number; + } + + return number + "-ე"; + }, + week : { + dow : 1, + doy : 7 + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/km.js b/addons/web/static/lib/moment/locale/km.js new file mode 100644 index 00000000000..f457e8d1307 --- /dev/null +++ b/addons/web/static/lib/moment/locale/km.js @@ -0,0 +1,55 @@ +// moment.js locale configuration +// locale : khmer (km) +// author : Kruy Vanna : https://github.com/kruyvanna + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('km', { + months: "មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"), + monthsShort: "មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"), + weekdays: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"), + weekdaysShort: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"), + weekdaysMin: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"), + longDateFormat: { + LT: "HH:mm", + L: "DD/MM/YYYY", + LL: "D MMMM YYYY", + LLL: "D MMMM YYYY LT", + LLLL: "dddd, D MMMM YYYY LT" + }, + calendar: { + sameDay: '[ថ្ងៃនៈ ម៉ោង] LT', + nextDay: '[ស្អែក ម៉ោង] LT', + nextWeek: 'dddd [ម៉ោង] LT', + lastDay: '[ម្សិលមិញ ម៉ោង] LT', + lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT', + sameElse: 'L' + }, + relativeTime: { + future: "%sទៀត", + past: "%sមុន", + s: "ប៉ុន្មានវិនាទី", + m: "មួយនាទី", + mm: "%d នាទី", + h: "មួយម៉ោង", + hh: "%d ម៉ោង", + d: "មួយថ្ងៃ", + dd: "%d ថ្ងៃ", + M: "មួយខែ", + MM: "%d ខែ", + y: "មួយឆ្នាំ", + yy: "%d ឆ្នាំ" + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ko.js b/addons/web/static/lib/moment/locale/ko.js new file mode 100644 index 00000000000..7de2e51033c --- /dev/null +++ b/addons/web/static/lib/moment/locale/ko.js @@ -0,0 +1,63 @@ +// moment.js locale configuration +// locale : korean (ko) +// +// authors +// +// - Kyungwook, Park : https://github.com/kyungw00k +// - Jeeeyul Lee <jeeeyul@gmail.com> +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('ko', { + months : "1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"), + monthsShort : "1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"), + weekdays : "일요일_월요일_화요일_수요일_목요일_금요일_토요일".split("_"), + weekdaysShort : "일_월_화_수_목_금_토".split("_"), + weekdaysMin : "일_월_화_수_목_금_토".split("_"), + longDateFormat : { + LT : "A h시 mm분", + L : "YYYY.MM.DD", + LL : "YYYY년 MMMM D일", + LLL : "YYYY년 MMMM D일 LT", + LLLL : "YYYY년 MMMM D일 dddd LT" + }, + meridiem : function (hour, minute, isUpper) { + return hour < 12 ? '오전' : '오후'; + }, + calendar : { + sameDay : '오늘 LT', + nextDay : '내일 LT', + nextWeek : 'dddd LT', + lastDay : '어제 LT', + lastWeek : '지난주 dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s 후", + past : "%s 전", + s : "몇초", + ss : "%d초", + m : "일분", + mm : "%d분", + h : "한시간", + hh : "%d시간", + d : "하루", + dd : "%d일", + M : "한달", + MM : "%d달", + y : "일년", + yy : "%d년" + }, + ordinal : '%d일', + meridiemParse : /(오전|오후)/, + isPM : function (token) { + return token === "오후"; + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/lb.js b/addons/web/static/lib/moment/locale/lb.js new file mode 100644 index 00000000000..c878b79c134 --- /dev/null +++ b/addons/web/static/lib/moment/locale/lb.js @@ -0,0 +1,137 @@ +// moment.js locale configuration +// locale : Luxembourgish (lb) +// author : mweimerskirch : https://github.com/mweimerskirch, David Raison : https://github.com/kwisatz + +// Note: Luxembourgish has a very particular phonological rule ("Eifeler Regel") that causes the +// deletion of the final "n" in certain contexts. That's what the "eifelerRegelAppliesToWeekday" +// and "eifelerRegelAppliesToNumber" methods are meant for + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eng Minutt', 'enger Minutt'], + 'h': ['eng Stonn', 'enger Stonn'], + 'd': ['een Dag', 'engem Dag'], + 'M': ['ee Mount', 'engem Mount'], + 'y': ['ee Joer', 'engem Joer'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + + function processFutureTime(string) { + var number = string.substr(0, string.indexOf(' ')); + if (eifelerRegelAppliesToNumber(number)) { + return "a " + string; + } + return "an " + string; + } + + function processPastTime(string) { + var number = string.substr(0, string.indexOf(' ')); + if (eifelerRegelAppliesToNumber(number)) { + return "viru " + string; + } + return "virun " + string; + } + + /** + * Returns true if the word before the given number loses the "-n" ending. + * e.g. "an 10 Deeg" but "a 5 Deeg" + * + * @param number {integer} + * @returns {boolean} + */ + function eifelerRegelAppliesToNumber(number) { + number = parseInt(number, 10); + if (isNaN(number)) { + return false; + } + if (number < 0) { + // Negative Number --> always true + return true; + } else if (number < 10) { + // Only 1 digit + if (4 <= number && number <= 7) { + return true; + } + return false; + } else if (number < 100) { + // 2 digits + var lastDigit = number % 10, firstDigit = number / 10; + if (lastDigit === 0) { + return eifelerRegelAppliesToNumber(firstDigit); + } + return eifelerRegelAppliesToNumber(lastDigit); + } else if (number < 10000) { + // 3 or 4 digits --> recursively check first digit + while (number >= 10) { + number = number / 10; + } + return eifelerRegelAppliesToNumber(number); + } else { + // Anything larger than 4 digits: recursively check first n-3 digits + number = number / 1000; + return eifelerRegelAppliesToNumber(number); + } + } + + return moment.defineLocale('lb', { + months: "Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"), + monthsShort: "Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"), + weekdays: "Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg".split("_"), + weekdaysShort: "So._Mé._Dë._Më._Do._Fr._Sa.".split("_"), + weekdaysMin: "So_Mé_Dë_Më_Do_Fr_Sa".split("_"), + longDateFormat: { + LT: "H:mm [Auer]", + L: "DD.MM.YYYY", + LL: "D. MMMM YYYY", + LLL: "D. MMMM YYYY LT", + LLLL: "dddd, D. MMMM YYYY LT" + }, + calendar: { + sameDay: "[Haut um] LT", + sameElse: "L", + nextDay: '[Muer um] LT', + nextWeek: 'dddd [um] LT', + lastDay: '[Gëschter um] LT', + lastWeek: function () { + // Different date string for "Dënschdeg" (Tuesday) and "Donneschdeg" (Thursday) due to phonological rule + switch (this.day()) { + case 2: + case 4: + return '[Leschten] dddd [um] LT'; + default: + return '[Leschte] dddd [um] LT'; + } + } + }, + relativeTime : { + future : processFutureTime, + past : processPastTime, + s : "e puer Sekonnen", + m : processRelativeTime, + mm : "%d Minutten", + h : processRelativeTime, + hh : "%d Stonnen", + d : processRelativeTime, + dd : "%d Deeg", + M : processRelativeTime, + MM : "%d Méint", + y : processRelativeTime, + yy : "%d Joer" + }, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/lt.js b/addons/web/static/lib/moment/locale/lt.js new file mode 100644 index 00000000000..7d7b93f10a9 --- /dev/null +++ b/addons/web/static/lib/moment/locale/lt.js @@ -0,0 +1,118 @@ +// moment.js locale configuration +// locale : Lithuanian (lt) +// author : Mindaugas Mozūras : https://github.com/mmozuras + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var units = { + "m" : "minutė_minutės_minutę", + "mm": "minutės_minučių_minutes", + "h" : "valanda_valandos_valandą", + "hh": "valandos_valandų_valandas", + "d" : "diena_dienos_dieną", + "dd": "dienos_dienų_dienas", + "M" : "mėnuo_mėnesio_mėnesį", + "MM": "mėnesiai_mėnesių_mėnesius", + "y" : "metai_metų_metus", + "yy": "metai_metų_metus" + }, + weekDays = "sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis".split("_"); + + function translateSeconds(number, withoutSuffix, key, isFuture) { + if (withoutSuffix) { + return "kelios sekundės"; + } else { + return isFuture ? "kelių sekundžių" : "kelias sekundes"; + } + } + + function translateSingular(number, withoutSuffix, key, isFuture) { + return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]); + } + + function special(number) { + return number % 10 === 0 || (number > 10 && number < 20); + } + + function forms(key) { + return units[key].split("_"); + } + + function translate(number, withoutSuffix, key, isFuture) { + var result = number + " "; + if (number === 1) { + return result + translateSingular(number, withoutSuffix, key[0], isFuture); + } else if (withoutSuffix) { + return result + (special(number) ? forms(key)[1] : forms(key)[0]); + } else { + if (isFuture) { + return result + forms(key)[1]; + } else { + return result + (special(number) ? forms(key)[1] : forms(key)[2]); + } + } + } + + function relativeWeekDay(moment, format) { + var nominative = format.indexOf('dddd HH:mm') === -1, + weekDay = weekDays[moment.day()]; + + return nominative ? weekDay : weekDay.substring(0, weekDay.length - 2) + "į"; + } + + return moment.defineLocale("lt", { + months : "sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio".split("_"), + monthsShort : "sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"), + weekdays : relativeWeekDay, + weekdaysShort : "Sek_Pir_Ant_Tre_Ket_Pen_Šeš".split("_"), + weekdaysMin : "S_P_A_T_K_Pn_Š".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "YYYY-MM-DD", + LL : "YYYY [m.] MMMM D [d.]", + LLL : "YYYY [m.] MMMM D [d.], LT [val.]", + LLLL : "YYYY [m.] MMMM D [d.], dddd, LT [val.]", + l : "YYYY-MM-DD", + ll : "YYYY [m.] MMMM D [d.]", + lll : "YYYY [m.] MMMM D [d.], LT [val.]", + llll : "YYYY [m.] MMMM D [d.], ddd, LT [val.]" + }, + calendar : { + sameDay : "[Šiandien] LT", + nextDay : "[Rytoj] LT", + nextWeek : "dddd LT", + lastDay : "[Vakar] LT", + lastWeek : "[Praėjusį] dddd LT", + sameElse : "L" + }, + relativeTime : { + future : "po %s", + past : "prieš %s", + s : translateSeconds, + m : translateSingular, + mm : translate, + h : translateSingular, + hh : translate, + d : translateSingular, + dd : translate, + M : translateSingular, + MM : translate, + y : translateSingular, + yy : translate + }, + ordinal : function (number) { + return number + '-oji'; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/lv.js b/addons/web/static/lib/moment/locale/lv.js new file mode 100644 index 00000000000..0df007d7480 --- /dev/null +++ b/addons/web/static/lib/moment/locale/lv.js @@ -0,0 +1,77 @@ +// moment.js locale configuration +// locale : latvian (lv) +// author : Kristaps Karlsons : https://github.com/skakri + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var units = { + 'mm': 'minūti_minūtes_minūte_minūtes', + 'hh': 'stundu_stundas_stunda_stundas', + 'dd': 'dienu_dienas_diena_dienas', + 'MM': 'mēnesi_mēnešus_mēnesis_mēneši', + 'yy': 'gadu_gadus_gads_gadi' + }; + + function format(word, number, withoutSuffix) { + var forms = word.split('_'); + if (withoutSuffix) { + return number % 10 === 1 && number !== 11 ? forms[2] : forms[3]; + } else { + return number % 10 === 1 && number !== 11 ? forms[0] : forms[1]; + } + } + + function relativeTimeWithPlural(number, withoutSuffix, key) { + return number + ' ' + format(units[key], number, withoutSuffix); + } + + return moment.defineLocale('lv', { + months : "janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris".split("_"), + monthsShort : "jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec".split("_"), + weekdays : "svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena".split("_"), + weekdaysShort : "Sv_P_O_T_C_Pk_S".split("_"), + weekdaysMin : "Sv_P_O_T_C_Pk_S".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD.MM.YYYY", + LL : "YYYY. [gada] D. MMMM", + LLL : "YYYY. [gada] D. MMMM, LT", + LLLL : "YYYY. [gada] D. MMMM, dddd, LT" + }, + calendar : { + sameDay : '[Šodien pulksten] LT', + nextDay : '[Rīt pulksten] LT', + nextWeek : 'dddd [pulksten] LT', + lastDay : '[Vakar pulksten] LT', + lastWeek : '[Pagājušā] dddd [pulksten] LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s vēlāk", + past : "%s agrāk", + s : "dažas sekundes", + m : "minūti", + mm : relativeTimeWithPlural, + h : "stundu", + hh : relativeTimeWithPlural, + d : "dienu", + dd : relativeTimeWithPlural, + M : "mēnesi", + MM : relativeTimeWithPlural, + y : "gadu", + yy : relativeTimeWithPlural + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/mk.js b/addons/web/static/lib/moment/locale/mk.js new file mode 100644 index 00000000000..2d8a739abb1 --- /dev/null +++ b/addons/web/static/lib/moment/locale/mk.js @@ -0,0 +1,86 @@ +// moment.js locale configuration +// locale : macedonian (mk) +// author : Borislav Mickov : https://github.com/B0k0 + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('mk', { + months : "јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември".split("_"), + monthsShort : "јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек".split("_"), + weekdays : "недела_понеделник_вторник_среда_четврток_петок_сабота".split("_"), + weekdaysShort : "нед_пон_вто_сре_чет_пет_саб".split("_"), + weekdaysMin : "нe_пo_вт_ср_че_пе_сa".split("_"), + longDateFormat : { + LT : "H:mm", + L : "D.MM.YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd, D MMMM YYYY LT" + }, + calendar : { + sameDay : '[Денес во] LT', + nextDay : '[Утре во] LT', + nextWeek : 'dddd [во] LT', + lastDay : '[Вчера во] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + case 6: + return '[Во изминатата] dddd [во] LT'; + case 1: + case 2: + case 4: + case 5: + return '[Во изминатиот] dddd [во] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : "после %s", + past : "пред %s", + s : "неколку секунди", + m : "минута", + mm : "%d минути", + h : "час", + hh : "%d часа", + d : "ден", + dd : "%d дена", + M : "месец", + MM : "%d месеци", + y : "година", + yy : "%d години" + }, + ordinal : function (number) { + var lastDigit = number % 10, + last2Digits = number % 100; + if (number === 0) { + return number + '-ев'; + } else if (last2Digits === 0) { + return number + '-ен'; + } else if (last2Digits > 10 && last2Digits < 20) { + return number + '-ти'; + } else if (lastDigit === 1) { + return number + '-ви'; + } else if (lastDigit === 2) { + return number + '-ри'; + } else if (lastDigit === 7 || lastDigit === 8) { + return number + '-ми'; + } else { + return number + '-ти'; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ml.js b/addons/web/static/lib/moment/locale/ml.js new file mode 100644 index 00000000000..d3cee1d3f30 --- /dev/null +++ b/addons/web/static/lib/moment/locale/ml.js @@ -0,0 +1,64 @@ +// moment.js locale configuration +// locale : malayalam (ml) +// author : Floyd Pink : https://github.com/floydpink + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('ml', { + months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split("_"), + monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split("_"), + weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split("_"), + weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split("_"), + weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split("_"), + longDateFormat : { + LT : "A h:mm -നു", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY, LT", + LLLL : "dddd, D MMMM YYYY, LT" + }, + calendar : { + sameDay : '[ഇന്ന്] LT', + nextDay : '[നാളെ] LT', + nextWeek : 'dddd, LT', + lastDay : '[ഇന്നലെ] LT', + lastWeek : '[കഴിഞ്ഞ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s കഴിഞ്ഞ്", + past : "%s മുൻപ്", + s : "അൽപ നിമിഷങ്ങൾ", + m : "ഒരു മിനിറ്റ്", + mm : "%d മിനിറ്റ്", + h : "ഒരു മണിക്കൂർ", + hh : "%d മണിക്കൂർ", + d : "ഒരു ദിവസം", + dd : "%d ദിവസം", + M : "ഒരു മാസം", + MM : "%d മാസം", + y : "ഒരു വർഷം", + yy : "%d വർഷം" + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return "രാത്രി"; + } else if (hour < 12) { + return "രാവിലെ"; + } else if (hour < 17) { + return "ഉച്ച കഴിഞ്ഞ്"; + } else if (hour < 20) { + return "വൈകുന്നേരം"; + } else { + return "രാത്രി"; + } + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/mr.js b/addons/web/static/lib/moment/locale/mr.js new file mode 100644 index 00000000000..8cbfe7cf97d --- /dev/null +++ b/addons/web/static/lib/moment/locale/mr.js @@ -0,0 +1,104 @@ +// moment.js locale configuration +// locale : Marathi (mr) +// author : Harshad Kale : https://github.com/kalehv + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var symbolMap = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' + }, + numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' + }; + + return moment.defineLocale('mr', { + months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split("_"), + monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split("_"), + weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split("_"), + weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split("_"), + weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split("_"), + longDateFormat : { + LT : "A h:mm वाजता", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY, LT", + LLLL : "dddd, D MMMM YYYY, LT" + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[उद्या] LT', + nextWeek : 'dddd, LT', + lastDay : '[काल] LT', + lastWeek: '[मागील] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s नंतर", + past : "%s पूर्वी", + s : "सेकंद", + m: "एक मिनिट", + mm: "%d मिनिटे", + h : "एक तास", + hh : "%d तास", + d : "एक दिवस", + dd : "%d दिवस", + M : "एक महिना", + MM : "%d महिने", + y : "एक वर्ष", + yy : "%d वर्षे" + }, + 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]; + }); + }, + meridiem: function (hour, minute, isLower) + { + if (hour < 4) { + return "रात्री"; + } else if (hour < 10) { + return "सकाळी"; + } else if (hour < 17) { + return "दुपारी"; + } else if (hour < 20) { + return "सायंकाळी"; + } else { + return "रात्री"; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ms-my.js b/addons/web/static/lib/moment/locale/ms-my.js new file mode 100644 index 00000000000..eee412f6bcd --- /dev/null +++ b/addons/web/static/lib/moment/locale/ms-my.js @@ -0,0 +1,66 @@ +// moment.js locale configuration +// locale : Bahasa Malaysia (ms-MY) +// author : Weldan Jamili : https://github.com/weldan + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('ms-my', { + months : "Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"), + monthsShort : "Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"), + weekdays : "Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"), + weekdaysShort : "Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"), + weekdaysMin : "Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"), + longDateFormat : { + LT : "HH.mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY [pukul] LT", + LLLL : "dddd, D MMMM YYYY [pukul] LT" + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'tengahari'; + } else if (hours < 19) { + return 'petang'; + } else { + return 'malam'; + } + }, + calendar : { + sameDay : '[Hari ini pukul] LT', + nextDay : '[Esok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kelmarin pukul] LT', + lastWeek : 'dddd [lepas pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : "dalam %s", + past : "%s yang lepas", + s : "beberapa saat", + m : "seminit", + mm : "%d minit", + h : "sejam", + hh : "%d jam", + d : "sehari", + dd : "%d hari", + M : "sebulan", + MM : "%d bulan", + y : "setahun", + yy : "%d tahun" + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/my.js b/addons/web/static/lib/moment/locale/my.js new file mode 100644 index 00000000000..442d5693c1e --- /dev/null +++ b/addons/web/static/lib/moment/locale/my.js @@ -0,0 +1,88 @@ +// moment.js locale configuration +// locale : Burmese (my) +// author : Squar team, mysquar.com + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var symbolMap = { + '1': '၁', + '2': '၂', + '3': '၃', + '4': '၄', + '5': '၅', + '6': '၆', + '7': '၇', + '8': '၈', + '9': '၉', + '0': '၀' + }, numberMap = { + '၁': '1', + '၂': '2', + '၃': '3', + '၄': '4', + '၅': '5', + '၆': '6', + '၇': '7', + '၈': '8', + '၉': '9', + '၀': '0' + }; + return moment.defineLocale('my', { + months: "ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ".split("_"), + monthsShort: "ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ".split("_"), + weekdays: "တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ".split("_"), + weekdaysShort: "နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ".split("_"), + weekdaysMin: "နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ".split("_"), + longDateFormat: { + LT: "HH:mm", + L: "DD/MM/YYYY", + LL: "D MMMM YYYY", + LLL: "D MMMM YYYY LT", + LLLL: "dddd D MMMM YYYY LT" + }, + calendar: { + sameDay: '[ယနေ.] LT [မှာ]', + nextDay: '[မနက်ဖြန်] LT [မှာ]', + nextWeek: 'dddd LT [မှာ]', + lastDay: '[မနေ.က] LT [မှာ]', + lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]', + sameElse: 'L' + }, + relativeTime: { + future: "လာမည့် %s မှာ", + past: "လွန်ခဲ့သော %s က", + s: "စက္ကန်.အနည်းငယ်", + m: "တစ်မိနစ်", + mm: "%d မိနစ်", + h: "တစ်နာရီ", + hh: "%d နာရီ", + d: "တစ်ရက်", + dd: "%d ရက်", + M: "တစ်လ", + MM: "%d လ", + y: "တစ်နှစ်", + yy: "%d နှစ်" + }, + 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]; + }); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/nb.js b/addons/web/static/lib/moment/locale/nb.js new file mode 100644 index 00000000000..5e4a511a37f --- /dev/null +++ b/addons/web/static/lib/moment/locale/nb.js @@ -0,0 +1,57 @@ +// moment.js locale configuration +// locale : norwegian bokmål (nb) +// authors : Espen Hovlandsdal : https://github.com/rexxars +// Sigurd Gartmann : https://github.com/sigurdga + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('nb', { + months : "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"), + monthsShort : "jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.".split("_"), + weekdays : "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"), + weekdaysShort : "sø._ma._ti._on._to._fr._lø.".split("_"), + weekdaysMin : "sø_ma_ti_on_to_fr_lø".split("_"), + longDateFormat : { + LT : "H.mm", + L : "DD.MM.YYYY", + LL : "D. MMMM YYYY", + LLL : "D. MMMM YYYY [kl.] LT", + LLLL : "dddd D. MMMM YYYY [kl.] LT" + }, + calendar : { + sameDay: '[i dag kl.] LT', + nextDay: '[i morgen kl.] LT', + nextWeek: 'dddd [kl.] LT', + lastDay: '[i går kl.] LT', + lastWeek: '[forrige] dddd [kl.] LT', + sameElse: 'L' + }, + relativeTime : { + future : "om %s", + past : "for %s siden", + s : "noen sekunder", + m : "ett minutt", + mm : "%d minutter", + h : "en time", + hh : "%d timer", + d : "en dag", + dd : "%d dager", + M : "en måned", + MM : "%d måneder", + y : "ett år", + yy : "%d år" + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ne.js b/addons/web/static/lib/moment/locale/ne.js new file mode 100644 index 00000000000..836fb4d476f --- /dev/null +++ b/addons/web/static/lib/moment/locale/ne.js @@ -0,0 +1,105 @@ +// moment.js locale configuration +// locale : nepali/nepalese +// author : suvash : https://github.com/suvash + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var symbolMap = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' + }, + numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' + }; + + return moment.defineLocale('ne', { + months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split("_"), + monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split("_"), + weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split("_"), + weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split("_"), + weekdaysMin : 'आइ._सो._मङ्_बु._बि._शु._श.'.split("_"), + longDateFormat : { + LT : "Aको h:mm बजे", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY, LT", + LLLL : "dddd, D MMMM YYYY, LT" + }, + 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]; + }); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 3) { + return "राती"; + } else if (hour < 10) { + return "बिहान"; + } else if (hour < 15) { + return "दिउँसो"; + } else if (hour < 18) { + return "बेलुका"; + } else if (hour < 20) { + return "साँझ"; + } else { + return "राती"; + } + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[भोली] LT', + nextWeek : '[आउँदो] dddd[,] LT', + lastDay : '[हिजो] LT', + lastWeek : '[गएको] dddd[,] LT', + sameElse : 'L' + }, + relativeTime : { + future : "%sमा", + past : "%s अगाडी", + s : "केही समय", + m : "एक मिनेट", + mm : "%d मिनेट", + h : "एक घण्टा", + hh : "%d घण्टा", + d : "एक दिन", + dd : "%d दिन", + M : "एक महिना", + MM : "%d महिना", + y : "एक बर्ष", + yy : "%d बर्ष" + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/nl.js b/addons/web/static/lib/moment/locale/nl.js new file mode 100644 index 00000000000..15776736ca8 --- /dev/null +++ b/addons/web/static/lib/moment/locale/nl.js @@ -0,0 +1,67 @@ +// moment.js locale configuration +// locale : dutch (nl) +// author : Joris Röling : https://github.com/jjupiter + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var monthsShortWithDots = "jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"), + monthsShortWithoutDots = "jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"); + + return moment.defineLocale('nl', { + months : "januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"), + monthsShort : function (m, format) { + if (/-MMM-/.test(format)) { + return monthsShortWithoutDots[m.month()]; + } else { + return monthsShortWithDots[m.month()]; + } + }, + weekdays : "zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"), + weekdaysShort : "zo._ma._di._wo._do._vr._za.".split("_"), + weekdaysMin : "Zo_Ma_Di_Wo_Do_Vr_Za".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD-MM-YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D MMMM YYYY LT" + }, + calendar : { + sameDay: '[vandaag om] LT', + nextDay: '[morgen om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[gisteren om] LT', + lastWeek: '[afgelopen] dddd [om] LT', + sameElse: 'L' + }, + relativeTime : { + future : "over %s", + past : "%s geleden", + s : "een paar seconden", + m : "één minuut", + mm : "%d minuten", + h : "één uur", + hh : "%d uur", + d : "één dag", + dd : "%d dagen", + M : "één maand", + MM : "%d maanden", + y : "één jaar", + yy : "%d jaar" + }, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/nn.js b/addons/web/static/lib/moment/locale/nn.js new file mode 100644 index 00000000000..e479b4582cc --- /dev/null +++ b/addons/web/static/lib/moment/locale/nn.js @@ -0,0 +1,56 @@ +// moment.js locale configuration +// locale : norwegian nynorsk (nn) +// author : https://github.com/mechuwind + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('nn', { + months : "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"), + monthsShort : "jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"), + weekdays : "sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"), + weekdaysShort : "sun_mån_tys_ons_tor_fre_lau".split("_"), + weekdaysMin : "su_må_ty_on_to_fr_lø".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD.MM.YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D MMMM YYYY LT" + }, + calendar : { + sameDay: '[I dag klokka] LT', + nextDay: '[I morgon klokka] LT', + nextWeek: 'dddd [klokka] LT', + lastDay: '[I går klokka] LT', + lastWeek: '[Føregåande] dddd [klokka] LT', + sameElse: 'L' + }, + relativeTime : { + future : "om %s", + past : "for %s sidan", + s : "nokre sekund", + m : "eit minutt", + mm : "%d minutt", + h : "ein time", + hh : "%d timar", + d : "ein dag", + dd : "%d dagar", + M : "ein månad", + MM : "%d månader", + y : "eit år", + yy : "%d år" + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/pl.js b/addons/web/static/lib/moment/locale/pl.js new file mode 100644 index 00000000000..75e978bd239 --- /dev/null +++ b/addons/web/static/lib/moment/locale/pl.js @@ -0,0 +1,98 @@ +// moment.js locale configuration +// locale : polish (pl) +// author : Rafal Hirsz : https://github.com/evoL + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var monthsNominative = "styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"), + monthsSubjective = "stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_"); + + function plural(n) { + return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1); + } + + function translate(number, withoutSuffix, key) { + var result = number + " "; + switch (key) { + case 'm': + return withoutSuffix ? 'minuta' : 'minutę'; + case 'mm': + return result + (plural(number) ? 'minuty' : 'minut'); + case 'h': + return withoutSuffix ? 'godzina' : 'godzinę'; + case 'hh': + return result + (plural(number) ? 'godziny' : 'godzin'); + case 'MM': + return result + (plural(number) ? 'miesiące' : 'miesięcy'); + case 'yy': + return result + (plural(number) ? 'lata' : 'lat'); + } + } + + return moment.defineLocale('pl', { + months : function (momentToFormat, format) { + if (/D MMMM/.test(format)) { + return monthsSubjective[momentToFormat.month()]; + } else { + return monthsNominative[momentToFormat.month()]; + } + }, + monthsShort : "sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"), + weekdays : "niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"), + weekdaysShort : "nie_pon_wt_śr_czw_pt_sb".split("_"), + weekdaysMin : "N_Pn_Wt_Śr_Cz_Pt_So".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD.MM.YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd, D MMMM YYYY LT" + }, + calendar : { + sameDay: '[Dziś o] LT', + nextDay: '[Jutro o] LT', + nextWeek: '[W] dddd [o] LT', + lastDay: '[Wczoraj o] LT', + lastWeek: function () { + switch (this.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'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : "za %s", + past : "%s temu", + s : "kilka sekund", + m : translate, + mm : translate, + h : translate, + hh : translate, + d : "1 dzień", + dd : '%d dni', + M : "miesiąc", + MM : translate, + y : "rok", + yy : translate + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/pt-br.js b/addons/web/static/lib/moment/locale/pt-br.js new file mode 100644 index 00000000000..d577018facc --- /dev/null +++ b/addons/web/static/lib/moment/locale/pt-br.js @@ -0,0 +1,56 @@ +// moment.js locale configuration +// locale : brazilian portuguese (pt-br) +// author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('pt-br', { + months : "janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"), + monthsShort : "jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"), + weekdays : "domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"), + weekdaysShort : "dom_seg_ter_qua_qui_sex_sáb".split("_"), + weekdaysMin : "dom_2ª_3ª_4ª_5ª_6ª_sáb".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D [de] MMMM [de] YYYY", + LLL : "D [de] MMMM [de] YYYY [às] LT", + LLLL : "dddd, D [de] MMMM [de] YYYY [às] LT" + }, + calendar : { + sameDay: '[Hoje às] LT', + nextDay: '[Amanhã às] LT', + nextWeek: 'dddd [às] LT', + lastDay: '[Ontem às] LT', + lastWeek: function () { + return (this.day() === 0 || this.day() === 6) ? + '[Último] dddd [às] LT' : // Saturday + Sunday + '[Última] dddd [às] LT'; // Monday - Friday + }, + sameElse: 'L' + }, + relativeTime : { + future : "em %s", + past : "%s atrás", + s : "segundos", + m : "um minuto", + mm : "%d minutos", + h : "uma hora", + hh : "%d horas", + d : "um dia", + dd : "%d dias", + M : "um mês", + MM : "%d meses", + y : "um ano", + yy : "%d anos" + }, + ordinal : '%dº' + }); +})); diff --git a/addons/web/static/lib/moment/locale/pt.js b/addons/web/static/lib/moment/locale/pt.js new file mode 100644 index 00000000000..808641483df --- /dev/null +++ b/addons/web/static/lib/moment/locale/pt.js @@ -0,0 +1,60 @@ +// moment.js locale configuration +// locale : portuguese (pt) +// author : Jefferson : https://github.com/jalex79 + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('pt', { + months : "janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"), + monthsShort : "jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"), + weekdays : "domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"), + weekdaysShort : "dom_seg_ter_qua_qui_sex_sáb".split("_"), + weekdaysMin : "dom_2ª_3ª_4ª_5ª_6ª_sáb".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D [de] MMMM [de] YYYY", + LLL : "D [de] MMMM [de] YYYY LT", + LLLL : "dddd, D [de] MMMM [de] YYYY LT" + }, + calendar : { + sameDay: '[Hoje às] LT', + nextDay: '[Amanhã às] LT', + nextWeek: 'dddd [às] LT', + lastDay: '[Ontem às] LT', + lastWeek: function () { + return (this.day() === 0 || this.day() === 6) ? + '[Último] dddd [às] LT' : // Saturday + Sunday + '[Última] dddd [às] LT'; // Monday - Friday + }, + sameElse: 'L' + }, + relativeTime : { + future : "em %s", + past : "há %s", + s : "segundos", + m : "um minuto", + mm : "%d minutos", + h : "uma hora", + hh : "%d horas", + d : "um dia", + dd : "%d dias", + M : "um mês", + MM : "%d meses", + y : "um ano", + yy : "%d anos" + }, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ro.js b/addons/web/static/lib/moment/locale/ro.js new file mode 100644 index 00000000000..21a3293191a --- /dev/null +++ b/addons/web/static/lib/moment/locale/ro.js @@ -0,0 +1,72 @@ +// moment.js locale configuration +// locale : romanian (ro) +// author : Vlad Gurdiga : https://github.com/gurdiga +// author : Valentin Agachi : https://github.com/avaly + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'mm': 'minute', + 'hh': 'ore', + 'dd': 'zile', + 'MM': 'luni', + 'yy': 'ani' + }, + separator = ' '; + if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) { + separator = ' de '; + } + + return number + separator + format[key]; + } + + return moment.defineLocale('ro', { + months : "ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"), + monthsShort : "ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"), + weekdays : "duminică_luni_marți_miercuri_joi_vineri_sâmbătă".split("_"), + weekdaysShort : "Dum_Lun_Mar_Mie_Joi_Vin_Sâm".split("_"), + weekdaysMin : "Du_Lu_Ma_Mi_Jo_Vi_Sâ".split("_"), + longDateFormat : { + LT : "H:mm", + L : "DD.MM.YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY H:mm", + LLLL : "dddd, D MMMM YYYY H:mm" + }, + calendar : { + sameDay: "[azi la] LT", + nextDay: '[mâine la] LT', + nextWeek: 'dddd [la] LT', + lastDay: '[ieri la] LT', + lastWeek: '[fosta] dddd [la] LT', + sameElse: 'L' + }, + relativeTime : { + future : "peste %s", + past : "%s în urmă", + s : "câteva secunde", + m : "un minut", + mm : relativeTimeWithPlural, + h : "o oră", + hh : relativeTimeWithPlural, + d : "o zi", + dd : relativeTimeWithPlural, + M : "o lună", + MM : relativeTimeWithPlural, + y : "un an", + yy : relativeTimeWithPlural + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ru.js b/addons/web/static/lib/moment/locale/ru.js new file mode 100644 index 00000000000..3ae8d23b7c8 --- /dev/null +++ b/addons/web/static/lib/moment/locale/ru.js @@ -0,0 +1,166 @@ +// moment.js locale configuration +// locale : russian (ru) +// author : Viktorminator : https://github.com/Viktorminator +// Author : Menelion Elensúle : https://github.com/Oire + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); + } + + function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут', + 'hh': 'час_часа_часов', + 'dd': 'день_дня_дней', + 'MM': 'месяц_месяца_месяцев', + 'yy': 'год_года_лет' + }; + if (key === 'm') { + return withoutSuffix ? 'минута' : 'минуту'; + } + else { + return number + ' ' + plural(format[key], +number); + } + } + + function monthsCaseReplace(m, format) { + var months = { + 'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'), + 'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_') + }, + + nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ? + 'accusative' : + 'nominative'; + + return months[nounCase][m.month()]; + } + + function monthsShortCaseReplace(m, format) { + var monthsShort = { + 'nominative': 'янв_фев_мар_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'), + 'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_') + }, + + nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ? + 'accusative' : + 'nominative'; + + return monthsShort[nounCase][m.month()]; + } + + function weekdaysCaseReplace(m, format) { + var weekdays = { + 'nominative': 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'), + 'accusative': 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_') + }, + + nounCase = (/\[ ?[Вв] ?(?:прошлую|следующую)? ?\] ?dddd/).test(format) ? + 'accusative' : + 'nominative'; + + return weekdays[nounCase][m.day()]; + } + + return moment.defineLocale('ru', { + months : monthsCaseReplace, + monthsShort : monthsShortCaseReplace, + weekdays : weekdaysCaseReplace, + weekdaysShort : "вс_пн_вт_ср_чт_пт_сб".split("_"), + weekdaysMin : "вс_пн_вт_ср_чт_пт_сб".split("_"), + monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i], + longDateFormat : { + LT : "HH:mm", + L : "DD.MM.YYYY", + LL : "D MMMM YYYY г.", + LLL : "D MMMM YYYY г., LT", + LLLL : "dddd, D MMMM YYYY г., LT" + }, + calendar : { + sameDay: '[Сегодня в] LT', + nextDay: '[Завтра в] LT', + lastDay: '[Вчера в] LT', + nextWeek: function () { + return this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT'; + }, + lastWeek: function () { + switch (this.day()) { + case 0: + return '[В прошлое] dddd [в] LT'; + case 1: + case 2: + case 4: + return '[В прошлый] dddd [в] LT'; + case 3: + case 5: + case 6: + return '[В прошлую] dddd [в] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : "через %s", + past : "%s назад", + s : "несколько секунд", + m : relativeTimeWithPlural, + mm : relativeTimeWithPlural, + h : "час", + hh : relativeTimeWithPlural, + d : "день", + dd : relativeTimeWithPlural, + M : "месяц", + MM : relativeTimeWithPlural, + y : "год", + yy : relativeTimeWithPlural + }, + + meridiemParse: /ночи|утра|дня|вечера/i, + isPM : function (input) { + return /^(дня|вечера)$/.test(input); + }, + + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return "ночи"; + } else if (hour < 12) { + return "утра"; + } else if (hour < 17) { + return "дня"; + } else { + return "вечера"; + } + }, + + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + return number + '-й'; + case 'D': + return number + '-го'; + case 'w': + case 'W': + return number + '-я'; + default: + return number; + } + }, + + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/sk.js b/addons/web/static/lib/moment/locale/sk.js new file mode 100644 index 00000000000..d03fff875b4 --- /dev/null +++ b/addons/web/static/lib/moment/locale/sk.js @@ -0,0 +1,156 @@ +// moment.js locale configuration +// locale : slovak (sk) +// author : Martin Minka : https://github.com/k2s +// based on work of petrbela : https://github.com/petrbela + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var months = "január_február_marec_apríl_máj_jún_júl_august_september_október_november_december".split("_"), + monthsShort = "jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec".split("_"); + + function plural(n) { + return (n > 1) && (n < 5); + } + + function translate(number, withoutSuffix, key, isFuture) { + var result = number + " "; + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami'; + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou'); + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'minúty' : 'minút'); + } else { + return result + 'minútami'; + } + break; + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'hodiny' : 'hodín'); + } else { + return result + 'hodinami'; + } + break; + case 'd': // a day / in a day / a day ago + return (withoutSuffix || isFuture) ? 'deň' : 'dňom'; + case 'dd': // 9 days / in 9 days / 9 days ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'dni' : 'dní'); + } else { + return result + 'dňami'; + } + break; + case 'M': // a month / in a month / a month ago + return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom'; + case 'MM': // 9 months / in 9 months / 9 months ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'mesiace' : 'mesiacov'); + } else { + return result + 'mesiacmi'; + } + break; + case 'y': // a year / in a year / a year ago + return (withoutSuffix || isFuture) ? 'rok' : 'rokom'; + case 'yy': // 9 years / in 9 years / 9 years ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'roky' : 'rokov'); + } else { + return result + 'rokmi'; + } + break; + } + } + + return moment.defineLocale('sk', { + months : months, + monthsShort : monthsShort, + monthsParse : (function (months, monthsShort) { + var i, _monthsParse = []; + for (i = 0; i < 12; i++) { + // use custom parser to solve problem with July (červenec) + _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i'); + } + return _monthsParse; + }(months, monthsShort)), + weekdays : "nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota".split("_"), + weekdaysShort : "ne_po_ut_st_št_pi_so".split("_"), + weekdaysMin : "ne_po_ut_st_št_pi_so".split("_"), + longDateFormat : { + LT: "H:mm", + L : "DD.MM.YYYY", + LL : "D. MMMM YYYY", + LLL : "D. MMMM YYYY LT", + LLLL : "dddd D. MMMM YYYY LT" + }, + calendar : { + sameDay: "[dnes o] LT", + nextDay: '[zajtra o] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v nedeľu o] LT'; + case 1: + case 2: + return '[v] dddd [o] LT'; + case 3: + return '[v stredu o] LT'; + case 4: + return '[vo štvrtok o] LT'; + case 5: + return '[v piatok o] LT'; + case 6: + return '[v sobotu o] LT'; + } + }, + lastDay: '[včera o] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[minulú nedeľu o] LT'; + case 1: + case 2: + return '[minulý] dddd [o] LT'; + case 3: + return '[minulú stredu o] LT'; + case 4: + case 5: + return '[minulý] dddd [o] LT'; + case 6: + return '[minulú sobotu o] LT'; + } + }, + sameElse: "L" + }, + relativeTime : { + future : "za %s", + past : "pred %s", + s : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/sl.js b/addons/web/static/lib/moment/locale/sl.js new file mode 100644 index 00000000000..6174ae63e2e --- /dev/null +++ b/addons/web/static/lib/moment/locale/sl.js @@ -0,0 +1,144 @@ +// moment.js locale configuration +// locale : slovenian (sl) +// author : Robert Sedovšek : https://github.com/sedovsek + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function translate(number, withoutSuffix, key) { + var result = number + " "; + switch (key) { + case 'm': + return withoutSuffix ? 'ena minuta' : 'eno minuto'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2) { + result += 'minuti'; + } else if (number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minut'; + } + return result; + case 'h': + return withoutSuffix ? 'ena ura' : 'eno uro'; + case 'hh': + if (number === 1) { + result += 'ura'; + } else if (number === 2) { + result += 'uri'; + } else if (number === 3 || number === 4) { + result += 'ure'; + } else { + result += 'ur'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dni'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mesec'; + } else if (number === 2) { + result += 'meseca'; + } else if (number === 3 || number === 4) { + result += 'mesece'; + } else { + result += 'mesecev'; + } + return result; + case 'yy': + if (number === 1) { + result += 'leto'; + } else if (number === 2) { + result += 'leti'; + } else if (number === 3 || number === 4) { + result += 'leta'; + } else { + result += 'let'; + } + return result; + } + } + + return moment.defineLocale('sl', { + months : "januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"), + monthsShort : "jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"), + weekdays : "nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota".split("_"), + weekdaysShort : "ned._pon._tor._sre._čet._pet._sob.".split("_"), + weekdaysMin : "ne_po_to_sr_če_pe_so".split("_"), + longDateFormat : { + LT : "H:mm", + L : "DD. MM. YYYY", + LL : "D. MMMM YYYY", + LLL : "D. MMMM YYYY LT", + LLLL : "dddd, D. MMMM YYYY LT" + }, + calendar : { + sameDay : '[danes ob] LT', + nextDay : '[jutri ob] LT', + + nextWeek : function () { + switch (this.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'; + } + }, + lastDay : '[včeraj ob] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + case 6: + return '[prejšnja] dddd [ob] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prejšnji] dddd [ob] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : "čez %s", + past : "%s nazaj", + s : "nekaj sekund", + m : translate, + mm : translate, + h : translate, + hh : translate, + d : "en dan", + dd : translate, + M : "en mesec", + MM : translate, + y : "eno leto", + yy : translate + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/sq.js b/addons/web/static/lib/moment/locale/sq.js new file mode 100644 index 00000000000..4a3dfea725a --- /dev/null +++ b/addons/web/static/lib/moment/locale/sq.js @@ -0,0 +1,61 @@ +// moment.js locale configuration +// locale : Albanian (sq) +// author : Flakërim Ismani : https://github.com/flakerimi +// author: Menelion Elensúle: https://github.com/Oire (tests) +// author : Oerd Cukalla : https://github.com/oerd (fixes) + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('sq', { + months : "Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor".split("_"), + monthsShort : "Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj".split("_"), + weekdays : "E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë".split("_"), + weekdaysShort : "Die_Hën_Mar_Mër_Enj_Pre_Sht".split("_"), + weekdaysMin : "D_H_Ma_Më_E_P_Sh".split("_"), + meridiem : function (hours, minutes, isLower) { + return hours < 12 ? 'PD' : 'MD'; + }, + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd, D MMMM YYYY LT" + }, + calendar : { + sameDay : '[Sot në] LT', + nextDay : '[Nesër në] LT', + nextWeek : 'dddd [në] LT', + lastDay : '[Dje në] LT', + lastWeek : 'dddd [e kaluar në] LT', + sameElse : 'L' + }, + relativeTime : { + future : "në %s", + past : "%s më parë", + s : "disa sekonda", + m : "një minutë", + mm : "%d minuta", + h : "një orë", + hh : "%d orë", + d : "një ditë", + dd : "%d ditë", + M : "një muaj", + MM : "%d muaj", + y : "një vit", + yy : "%d vite" + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/sr-cyrl.js b/addons/web/static/lib/moment/locale/sr-cyrl.js new file mode 100644 index 00000000000..ef6e7ce4bbc --- /dev/null +++ b/addons/web/static/lib/moment/locale/sr-cyrl.js @@ -0,0 +1,105 @@ +// moment.js locale configuration +// locale : Serbian-cyrillic (sr-cyrl) +// author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var translator = { + words: { //Different grammatical cases + m: ['један минут', 'једне минуте'], + mm: ['минут', 'минуте', 'минута'], + h: ['један сат', 'једног сата'], + hh: ['сат', 'сата', 'сати'], + dd: ['дан', 'дана', 'дана'], + MM: ['месец', 'месеца', 'месеци'], + yy: ['година', 'године', 'година'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + translator.correctGrammaticalCase(number, wordKey); + } + } + }; + + return moment.defineLocale('sr-cyrl', { + months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'], + monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'], + weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'], + weekdaysShort: ['нед.', 'пон.', 'уто.', 'сре.', 'чет.', 'пет.', 'суб.'], + weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'], + longDateFormat: { + LT: "H:mm", + L: "DD. MM. YYYY", + LL: "D. MMMM YYYY", + LLL: "D. MMMM YYYY LT", + LLLL: "dddd, D. MMMM YYYY LT" + }, + calendar: { + sameDay: '[данас у] LT', + nextDay: '[сутра у] LT', + + nextWeek: function () { + switch (this.day()) { + case 0: + return '[у] [недељу] [у] LT'; + case 3: + return '[у] [среду] [у] LT'; + case 6: + return '[у] [суботу] [у] LT'; + case 1: + case 2: + case 4: + case 5: + return '[у] dddd [у] LT'; + } + }, + lastDay : '[јуче у] LT', + lastWeek : function () { + var lastWeekDays = [ + '[прошле] [недеље] [у] LT', + '[прошлог] [понедељка] [у] LT', + '[прошлог] [уторка] [у] LT', + '[прошле] [среде] [у] LT', + '[прошлог] [четвртка] [у] LT', + '[прошлог] [петка] [у] LT', + '[прошле] [суботе] [у] LT' + ]; + return lastWeekDays[this.day()]; + }, + sameElse : 'L' + }, + relativeTime : { + future : "за %s", + past : "пре %s", + s : "неколико секунди", + m : translator.translate, + mm : translator.translate, + h : translator.translate, + hh : translator.translate, + d : "дан", + dd : translator.translate, + M : "месец", + MM : translator.translate, + y : "годину", + yy : translator.translate + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/sr.js b/addons/web/static/lib/moment/locale/sr.js new file mode 100644 index 00000000000..86e8e84a6bf --- /dev/null +++ b/addons/web/static/lib/moment/locale/sr.js @@ -0,0 +1,105 @@ +// moment.js locale configuration +// locale : Serbian-latin (sr) +// author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var translator = { + words: { //Different grammatical cases + m: ['jedan minut', 'jedne minute'], + mm: ['minut', 'minute', 'minuta'], + h: ['jedan sat', 'jednog sata'], + hh: ['sat', 'sata', 'sati'], + dd: ['dan', 'dana', 'dana'], + MM: ['mesec', 'meseca', 'meseci'], + yy: ['godina', 'godine', 'godina'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + translator.correctGrammaticalCase(number, wordKey); + } + } + }; + + return moment.defineLocale('sr', { + months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'], + monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'], + weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'], + weekdaysShort: ['ned.', 'pon.', 'uto.', 'sre.', 'čet.', 'pet.', 'sub.'], + weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'], + longDateFormat: { + LT: "H:mm", + L: "DD. MM. YYYY", + LL: "D. MMMM YYYY", + LLL: "D. MMMM YYYY LT", + LLLL: "dddd, D. MMMM YYYY LT" + }, + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sutra u] LT', + + nextWeek: function () { + switch (this.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'; + } + }, + lastDay : '[juče u] LT', + lastWeek : function () { + var lastWeekDays = [ + '[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 lastWeekDays[this.day()]; + }, + sameElse : 'L' + }, + relativeTime : { + future : "za %s", + past : "pre %s", + s : "nekoliko sekundi", + m : translator.translate, + mm : translator.translate, + h : translator.translate, + hh : translator.translate, + d : "dan", + dd : translator.translate, + M : "mesec", + MM : translator.translate, + y : "godinu", + yy : translator.translate + }, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/sv.js b/addons/web/static/lib/moment/locale/sv.js new file mode 100644 index 00000000000..9e39a30109a --- /dev/null +++ b/addons/web/static/lib/moment/locale/sv.js @@ -0,0 +1,63 @@ +// moment.js locale configuration +// locale : swedish (sv) +// author : Jens Alm : https://github.com/ulmus + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('sv', { + months : "januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"), + monthsShort : "jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"), + weekdays : "söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"), + weekdaysShort : "sön_mån_tis_ons_tor_fre_lör".split("_"), + weekdaysMin : "sö_må_ti_on_to_fr_lö".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "YYYY-MM-DD", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D MMMM YYYY LT" + }, + calendar : { + sameDay: '[Idag] LT', + nextDay: '[Imorgon] LT', + lastDay: '[Igår] LT', + nextWeek: 'dddd LT', + lastWeek: '[Förra] dddd[en] LT', + sameElse: 'L' + }, + relativeTime : { + future : "om %s", + past : "för %s sedan", + s : "några sekunder", + m : "en minut", + mm : "%d minuter", + h : "en timme", + hh : "%d timmar", + d : "en dag", + dd : "%d dagar", + M : "en månad", + MM : "%d månader", + y : "ett år", + yy : "%d år" + }, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'e' : + (b === 1) ? 'a' : + (b === 2) ? 'a' : + (b === 3) ? 'e' : 'e'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/ta.js b/addons/web/static/lib/moment/locale/ta.js new file mode 100644 index 00000000000..963d40349f4 --- /dev/null +++ b/addons/web/static/lib/moment/locale/ta.js @@ -0,0 +1,112 @@ +// moment.js locale configuration +// locale : tamil (ta) +// author : Arjunkumar Krishnamoorthy : https://github.com/tk120404 + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + /*var symbolMap = { + '1': '௧', + '2': '௨', + '3': '௩', + '4': '௪', + '5': '௫', + '6': '௬', + '7': '௭', + '8': '௮', + '9': '௯', + '0': '௦' + }, + numberMap = { + '௧': '1', + '௨': '2', + '௩': '3', + '௪': '4', + '௫': '5', + '௬': '6', + '௭': '7', + '௮': '8', + '௯': '9', + '௦': '0' + }; */ + + return moment.defineLocale('ta', { + months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split("_"), + monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split("_"), + weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split("_"), + weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split("_"), + weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY, LT", + LLLL : "dddd, D MMMM YYYY, LT" + }, + calendar : { + sameDay : '[இன்று] LT', + nextDay : '[நாளை] LT', + nextWeek : 'dddd, LT', + lastDay : '[நேற்று] LT', + lastWeek : '[கடந்த வாரம்] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s இல்", + past : "%s முன்", + s : "ஒரு சில விநாடிகள்", + m : "ஒரு நிமிடம்", + mm : "%d நிமிடங்கள்", + h : "ஒரு மணி நேரம்", + hh : "%d மணி நேரம்", + d : "ஒரு நாள்", + dd : "%d நாட்கள்", + M : "ஒரு மாதம்", + MM : "%d மாதங்கள்", + y : "ஒரு வருடம்", + yy : "%d ஆண்டுகள்" + }, +/* 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]; + }); + },*/ + ordinal : function (number) { + return number + 'வது'; + }, + + + // refer http://ta.wikipedia.org/s/1er1 + + meridiem : function (hour, minute, isLower) { + if (hour >= 6 && hour <= 10) { + return " காலை"; + } else if (hour >= 10 && hour <= 14) { + return " நண்பகல்"; + } else if (hour >= 14 && hour <= 18) { + return " எற்பாடு"; + } else if (hour >= 18 && hour <= 20) { + return " மாலை"; + } else if (hour >= 20 && hour <= 24) { + return " இரவு"; + } else if (hour >= 0 && hour <= 6) { + return " வைகறை"; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/th.js b/addons/web/static/lib/moment/locale/th.js new file mode 100644 index 00000000000..30b41e69aa0 --- /dev/null +++ b/addons/web/static/lib/moment/locale/th.js @@ -0,0 +1,58 @@ +// moment.js locale configuration +// locale : thai (th) +// author : Kridsada Thanabulpong : https://github.com/sirn + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('th', { + months : "มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"), + monthsShort : "มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา".split("_"), + weekdays : "อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"), + weekdaysShort : "อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"), // yes, three characters difference + weekdaysMin : "อา._จ._อ._พ._พฤ._ศ._ส.".split("_"), + longDateFormat : { + LT : "H นาฬิกา m นาที", + L : "YYYY/MM/DD", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY เวลา LT", + LLLL : "วันddddที่ D MMMM YYYY เวลา LT" + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return "ก่อนเที่ยง"; + } else { + return "หลังเที่ยง"; + } + }, + calendar : { + sameDay : '[วันนี้ เวลา] LT', + nextDay : '[พรุ่งนี้ เวลา] LT', + nextWeek : 'dddd[หน้า เวลา] LT', + lastDay : '[เมื่อวานนี้ เวลา] LT', + lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT', + sameElse : 'L' + }, + relativeTime : { + future : "อีก %s", + past : "%sที่แล้ว", + s : "ไม่กี่วินาที", + m : "1 นาที", + mm : "%d นาที", + h : "1 ชั่วโมง", + hh : "%d ชั่วโมง", + d : "1 วัน", + dd : "%d วัน", + M : "1 เดือน", + MM : "%d เดือน", + y : "1 ปี", + yy : "%d ปี" + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/tl-ph.js b/addons/web/static/lib/moment/locale/tl-ph.js new file mode 100644 index 00000000000..dfacf18df33 --- /dev/null +++ b/addons/web/static/lib/moment/locale/tl-ph.js @@ -0,0 +1,58 @@ +// moment.js locale configuration +// locale : Tagalog/Filipino (tl-ph) +// author : Dan Hagman + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('tl-ph', { + months : "Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"), + monthsShort : "Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"), + weekdays : "Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"), + weekdaysShort : "Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"), + weekdaysMin : "Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "MM/D/YYYY", + LL : "MMMM D, YYYY", + LLL : "MMMM D, YYYY LT", + LLLL : "dddd, MMMM DD, YYYY LT" + }, + calendar : { + sameDay: "[Ngayon sa] LT", + nextDay: '[Bukas sa] LT', + nextWeek: 'dddd [sa] LT', + lastDay: '[Kahapon sa] LT', + lastWeek: 'dddd [huling linggo] LT', + sameElse: 'L' + }, + relativeTime : { + future : "sa loob ng %s", + past : "%s ang nakalipas", + s : "ilang segundo", + m : "isang minuto", + mm : "%d minuto", + h : "isang oras", + hh : "%d oras", + d : "isang araw", + dd : "%d araw", + M : "isang buwan", + MM : "%d buwan", + y : "isang taon", + yy : "%d taon" + }, + ordinal : function (number) { + return number; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/tr.js b/addons/web/static/lib/moment/locale/tr.js new file mode 100644 index 00000000000..e6c2adab7cf --- /dev/null +++ b/addons/web/static/lib/moment/locale/tr.js @@ -0,0 +1,92 @@ +// moment.js locale configuration +// locale : turkish (tr) +// authors : Erhan Gundogan : https://github.com/erhangundogan, +// Burak Yiğit Kaya: https://github.com/BYK + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + var suffixes = { + 1: "'inci", + 5: "'inci", + 8: "'inci", + 70: "'inci", + 80: "'inci", + + 2: "'nci", + 7: "'nci", + 20: "'nci", + 50: "'nci", + + 3: "'üncü", + 4: "'üncü", + 100: "'üncü", + + 6: "'ncı", + + 9: "'uncu", + 10: "'uncu", + 30: "'uncu", + + 60: "'ıncı", + 90: "'ıncı" + }; + + return moment.defineLocale('tr', { + months : "Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık".split("_"), + monthsShort : "Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara".split("_"), + weekdays : "Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi".split("_"), + weekdaysShort : "Paz_Pts_Sal_Çar_Per_Cum_Cts".split("_"), + weekdaysMin : "Pz_Pt_Sa_Ça_Pe_Cu_Ct".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD.MM.YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd, D MMMM YYYY LT" + }, + calendar : { + sameDay : '[bugün saat] LT', + nextDay : '[yarın saat] LT', + nextWeek : '[haftaya] dddd [saat] LT', + lastDay : '[dün] LT', + lastWeek : '[geçen hafta] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : "%s sonra", + past : "%s önce", + s : "birkaç saniye", + m : "bir dakika", + mm : "%d dakika", + h : "bir saat", + hh : "%d saat", + d : "bir gün", + dd : "%d gün", + M : "bir ay", + MM : "%d ay", + y : "bir yıl", + yy : "%d yıl" + }, + ordinal : function (number) { + if (number === 0) { // special case for zero + return number + "'ıncı"; + } + var a = number % 10, + b = number % 100 - a, + c = number >= 100 ? 100 : null; + + return number + (suffixes[a] || suffixes[b] || suffixes[c]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/tzm-latn.js b/addons/web/static/lib/moment/locale/tzm-latn.js new file mode 100644 index 00000000000..1411e161b3c --- /dev/null +++ b/addons/web/static/lib/moment/locale/tzm-latn.js @@ -0,0 +1,55 @@ +// moment.js locale configuration +// locale : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn) +// author : Abdel Said : https://github.com/abdelsaid + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('tzm-latn', { + months : "innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"), + monthsShort : "innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"), + weekdays : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"), + weekdaysShort : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"), + weekdaysMin : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D MMMM YYYY LT" + }, + calendar : { + sameDay: "[asdkh g] LT", + nextDay: '[aska g] LT', + nextWeek: 'dddd [g] LT', + lastDay: '[assant g] LT', + lastWeek: 'dddd [g] LT', + sameElse: 'L' + }, + relativeTime : { + future : "dadkh s yan %s", + past : "yan %s", + s : "imik", + m : "minuḍ", + mm : "%d minuḍ", + h : "saɛa", + hh : "%d tassaɛin", + d : "ass", + dd : "%d ossan", + M : "ayowr", + MM : "%d iyyirn", + y : "asgas", + yy : "%d isgasn" + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/tzm.js b/addons/web/static/lib/moment/locale/tzm.js new file mode 100644 index 00000000000..615eb979cda --- /dev/null +++ b/addons/web/static/lib/moment/locale/tzm.js @@ -0,0 +1,55 @@ +// moment.js locale configuration +// locale : Morocco Central Atlas Tamaziɣt (tzm) +// author : Abdel Said : https://github.com/abdelsaid + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('tzm', { + months : "ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"), + monthsShort : "ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"), + weekdays : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"), + weekdaysShort : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"), + weekdaysMin : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "dddd D MMMM YYYY LT" + }, + calendar : { + sameDay: "[ⴰⵙⴷⵅ ⴴ] LT", + nextDay: '[ⴰⵙⴽⴰ ⴴ] LT', + nextWeek: 'dddd [ⴴ] LT', + lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT', + lastWeek: 'dddd [ⴴ] LT', + sameElse: 'L' + }, + relativeTime : { + future : "ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s", + past : "ⵢⴰⵏ %s", + s : "ⵉⵎⵉⴽ", + m : "ⵎⵉⵏⵓⴺ", + mm : "%d ⵎⵉⵏⵓⴺ", + h : "ⵙⴰⵄⴰ", + hh : "%d ⵜⴰⵙⵙⴰⵄⵉⵏ", + d : "ⴰⵙⵙ", + dd : "%d oⵙⵙⴰⵏ", + M : "ⴰⵢoⵓⵔ", + MM : "%d ⵉⵢⵢⵉⵔⵏ", + y : "ⴰⵙⴳⴰⵙ", + yy : "%d ⵉⵙⴳⴰⵙⵏ" + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/uk.js b/addons/web/static/lib/moment/locale/uk.js new file mode 100644 index 00000000000..f27d9f3e311 --- /dev/null +++ b/addons/web/static/lib/moment/locale/uk.js @@ -0,0 +1,157 @@ +// moment.js locale configuration +// locale : ukrainian (uk) +// author : zemlanin : https://github.com/zemlanin +// Author : Menelion Elensúle : https://github.com/Oire + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); + } + + function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'mm': 'хвилина_хвилини_хвилин', + 'hh': 'година_години_годин', + 'dd': 'день_дні_днів', + 'MM': 'місяць_місяці_місяців', + 'yy': 'рік_роки_років' + }; + if (key === 'm') { + return withoutSuffix ? 'хвилина' : 'хвилину'; + } + else if (key === 'h') { + return withoutSuffix ? 'година' : 'годину'; + } + else { + return number + ' ' + plural(format[key], +number); + } + } + + function monthsCaseReplace(m, format) { + var months = { + 'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'), + 'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_') + }, + + nounCase = (/D[oD]? *MMMM?/).test(format) ? + 'accusative' : + 'nominative'; + + return months[nounCase][m.month()]; + } + + function weekdaysCaseReplace(m, format) { + var weekdays = { + 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'), + 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'), + 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_') + }, + + nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ? + 'accusative' : + ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ? + 'genitive' : + 'nominative'); + + return weekdays[nounCase][m.day()]; + } + + function processHoursFunction(str) { + return function () { + return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT'; + }; + } + + return moment.defineLocale('uk', { + months : monthsCaseReplace, + monthsShort : "січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд".split("_"), + weekdays : weekdaysCaseReplace, + weekdaysShort : "нд_пн_вт_ср_чт_пт_сб".split("_"), + weekdaysMin : "нд_пн_вт_ср_чт_пт_сб".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD.MM.YYYY", + LL : "D MMMM YYYY р.", + LLL : "D MMMM YYYY р., LT", + LLLL : "dddd, D MMMM YYYY р., LT" + }, + calendar : { + sameDay: processHoursFunction('[Сьогодні '), + nextDay: processHoursFunction('[Завтра '), + lastDay: processHoursFunction('[Вчора '), + nextWeek: processHoursFunction('[У] dddd ['), + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 5: + case 6: + return processHoursFunction('[Минулої] dddd [').call(this); + case 1: + case 2: + case 4: + return processHoursFunction('[Минулого] dddd [').call(this); + } + }, + sameElse: 'L' + }, + relativeTime : { + future : "за %s", + past : "%s тому", + s : "декілька секунд", + m : relativeTimeWithPlural, + mm : relativeTimeWithPlural, + h : "годину", + hh : relativeTimeWithPlural, + d : "день", + dd : relativeTimeWithPlural, + M : "місяць", + MM : relativeTimeWithPlural, + y : "рік", + yy : relativeTimeWithPlural + }, + + // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason + + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return "ночі"; + } else if (hour < 12) { + return "ранку"; + } else if (hour < 17) { + return "дня"; + } else { + return "вечора"; + } + }, + + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + case 'w': + case 'W': + return number + '-й'; + case 'D': + return number + '-го'; + default: + return number; + } + }, + + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/uz.js b/addons/web/static/lib/moment/locale/uz.js new file mode 100644 index 00000000000..aeaad6339a8 --- /dev/null +++ b/addons/web/static/lib/moment/locale/uz.js @@ -0,0 +1,55 @@ +// moment.js locale configuration +// locale : uzbek +// author : Sardor Muminov : https://github.com/muminoff + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('uz', { + months : "январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_"), + monthsShort : "янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек".split("_"), + weekdays : "Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба".split("_"), + weekdaysShort : "Якш_Душ_Сеш_Чор_Пай_Жум_Шан".split("_"), + weekdaysMin : "Як_Ду_Се_Чо_Па_Жу_Ша".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM YYYY", + LLL : "D MMMM YYYY LT", + LLLL : "D MMMM YYYY, dddd LT" + }, + calendar : { + sameDay : '[Бугун соат] LT [да]', + nextDay : '[Эртага] LT [да]', + nextWeek : 'dddd [куни соат] LT [да]', + lastDay : '[Кеча соат] LT [да]', + lastWeek : '[Утган] dddd [куни соат] LT [да]', + sameElse : 'L' + }, + relativeTime : { + future : "Якин %s ичида", + past : "Бир неча %s олдин", + s : "фурсат", + m : "бир дакика", + mm : "%d дакика", + h : "бир соат", + hh : "%d соат", + d : "бир кун", + dd : "%d кун", + M : "бир ой", + MM : "%d ой", + y : "бир йил", + yy : "%d йил" + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/vi.js b/addons/web/static/lib/moment/locale/vi.js new file mode 100644 index 00000000000..3f8f5f5afc0 --- /dev/null +++ b/addons/web/static/lib/moment/locale/vi.js @@ -0,0 +1,62 @@ +// moment.js locale configuration +// locale : vietnamese (vi) +// author : Bang Nguyen : https://github.com/bangnk + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('vi', { + months : "tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12".split("_"), + monthsShort : "Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12".split("_"), + weekdays : "chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy".split("_"), + weekdaysShort : "CN_T2_T3_T4_T5_T6_T7".split("_"), + weekdaysMin : "CN_T2_T3_T4_T5_T6_T7".split("_"), + longDateFormat : { + LT : "HH:mm", + L : "DD/MM/YYYY", + LL : "D MMMM [năm] YYYY", + LLL : "D MMMM [năm] YYYY LT", + LLLL : "dddd, D MMMM [năm] YYYY LT", + l : "DD/M/YYYY", + ll : "D MMM YYYY", + lll : "D MMM YYYY LT", + llll : "ddd, D MMM YYYY LT" + }, + calendar : { + sameDay: "[Hôm nay lúc] LT", + nextDay: '[Ngày mai lúc] LT', + nextWeek: 'dddd [tuần tới lúc] LT', + lastDay: '[Hôm qua lúc] LT', + lastWeek: 'dddd [tuần rồi lúc] LT', + sameElse: 'L' + }, + relativeTime : { + future : "%s tới", + past : "%s trước", + s : "vài giây", + m : "một phút", + mm : "%d phút", + h : "một giờ", + hh : "%d giờ", + d : "một ngày", + dd : "%d ngày", + M : "một tháng", + MM : "%d tháng", + y : "một năm", + yy : "%d năm" + }, + ordinal : function (number) { + return number; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/zh-cn.js b/addons/web/static/lib/moment/locale/zh-cn.js new file mode 100644 index 00000000000..e73acd70497 --- /dev/null +++ b/addons/web/static/lib/moment/locale/zh-cn.js @@ -0,0 +1,108 @@ +// moment.js locale configuration +// locale : chinese +// author : suupic : https://github.com/suupic +// author : Zeno Zeng : https://github.com/zenozeng + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('zh-cn', { + months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"), + monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), + weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"), + weekdaysShort : "周日_周一_周二_周三_周四_周五_周六".split("_"), + weekdaysMin : "日_一_二_三_四_五_六".split("_"), + longDateFormat : { + LT : "Ah点mm", + L : "YYYY-MM-DD", + LL : "YYYY年MMMD日", + LLL : "YYYY年MMMD日LT", + LLLL : "YYYY年MMMD日ddddLT", + l : "YYYY-MM-DD", + ll : "YYYY年MMMD日", + lll : "YYYY年MMMD日LT", + llll : "YYYY年MMMD日ddddLT" + }, + meridiem : function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return "凌晨"; + } else if (hm < 900) { + return "早上"; + } else if (hm < 1130) { + return "上午"; + } else if (hm < 1230) { + return "中午"; + } else if (hm < 1800) { + return "下午"; + } else { + return "晚上"; + } + }, + calendar : { + sameDay : function () { + return this.minutes() === 0 ? "[今天]Ah[点整]" : "[今天]LT"; + }, + nextDay : function () { + return this.minutes() === 0 ? "[明天]Ah[点整]" : "[明天]LT"; + }, + lastDay : function () { + return this.minutes() === 0 ? "[昨天]Ah[点整]" : "[昨天]LT"; + }, + nextWeek : function () { + var startOfWeek, prefix; + startOfWeek = moment().startOf('week'); + prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]'; + return this.minutes() === 0 ? prefix + "dddAh点整" : prefix + "dddAh点mm"; + }, + lastWeek : function () { + var startOfWeek, prefix; + startOfWeek = moment().startOf('week'); + prefix = this.unix() < startOfWeek.unix() ? '[上]' : '[本]'; + return this.minutes() === 0 ? prefix + "dddAh点整" : prefix + "dddAh点mm"; + }, + sameElse : 'LL' + }, + ordinal : function (number, period) { + switch (period) { + case "d": + case "D": + case "DDD": + return number + "日"; + case "M": + return number + "月"; + case "w": + case "W": + return number + "周"; + default: + return number; + } + }, + relativeTime : { + future : "%s内", + past : "%s前", + s : "几秒", + m : "1分钟", + mm : "%d分钟", + h : "1小时", + hh : "%d小时", + d : "1天", + dd : "%d天", + M : "1个月", + MM : "%d个月", + y : "1年", + yy : "%d年" + }, + week : { + // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); +})); diff --git a/addons/web/static/lib/moment/locale/zh-tw.js b/addons/web/static/lib/moment/locale/zh-tw.js new file mode 100644 index 00000000000..edb1fb9879c --- /dev/null +++ b/addons/web/static/lib/moment/locale/zh-tw.js @@ -0,0 +1,84 @@ +// moment.js locale configuration +// locale : traditional chinese (zh-tw) +// author : Ben : https://github.com/ben-lin + +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['moment'], factory); // AMD + } else if (typeof exports === 'object') { + module.exports = factory(require('../moment')); // Node + } else { + factory(window.moment); // Browser global + } +}(function (moment) { + return moment.defineLocale('zh-tw', { + months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"), + monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), + weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"), + weekdaysShort : "週日_週一_週二_週三_週四_週五_週六".split("_"), + weekdaysMin : "日_一_二_三_四_五_六".split("_"), + longDateFormat : { + LT : "Ah點mm", + L : "YYYY年MMMD日", + LL : "YYYY年MMMD日", + LLL : "YYYY年MMMD日LT", + LLLL : "YYYY年MMMD日ddddLT", + l : "YYYY年MMMD日", + ll : "YYYY年MMMD日", + lll : "YYYY年MMMD日LT", + llll : "YYYY年MMMD日ddddLT" + }, + meridiem : function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 900) { + return "早上"; + } else if (hm < 1130) { + return "上午"; + } else if (hm < 1230) { + return "中午"; + } else if (hm < 1800) { + return "下午"; + } else { + return "晚上"; + } + }, + calendar : { + sameDay : '[今天]LT', + nextDay : '[明天]LT', + nextWeek : '[下]ddddLT', + lastDay : '[昨天]LT', + lastWeek : '[上]ddddLT', + sameElse : 'L' + }, + ordinal : function (number, period) { + switch (period) { + case "d" : + case "D" : + case "DDD" : + return number + "日"; + case "M" : + return number + "月"; + case "w" : + case "W" : + return number + "週"; + default : + return number; + } + }, + relativeTime : { + future : "%s內", + past : "%s前", + s : "幾秒", + m : "一分鐘", + mm : "%d分鐘", + h : "一小時", + hh : "%d小時", + d : "一天", + dd : "%d天", + M : "一個月", + MM : "%d個月", + y : "一年", + yy : "%d年" + } + }); +})); diff --git a/addons/web/static/lib/moment/moment.js b/addons/web/static/lib/moment/moment.js new file mode 100644 index 00000000000..03a2460105d --- /dev/null +++ b/addons/web/static/lib/moment/moment.js @@ -0,0 +1,2808 @@ +//! moment.js +//! version : 2.8.1 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com + +(function (undefined) { + /************************************ + Constants + ************************************/ + + var moment, + VERSION = '2.8.1', + // the global-scope this is NOT the global object in Node.js + globalScope = typeof global !== 'undefined' ? global : this, + oldGlobalMoment, + round = Math.round, + i, + + YEAR = 0, + MONTH = 1, + DATE = 2, + HOUR = 3, + MINUTE = 4, + SECOND = 5, + MILLISECOND = 6, + + // internal storage for locale config files + locales = {}, + + // extra moment internal properties (plugins register props here) + momentProperties = [], + + // check for nodeJS + hasModule = (typeof module !== 'undefined' && module.exports), + + // ASP.NET json date format regex + aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, + aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/, + + // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html + // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere + isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/, + + // format tokens + formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g, + localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, + + // parsing token regexes + parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 + parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999 + parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999 + parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999 + parseTokenDigits = /\d+/, // nonzero number of digits + parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic. + parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z + parseTokenT = /T/i, // T (ISO separator) + parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 + parseTokenOrdinal = /\d{1,2}/, + + //strict parsing regexes + parseTokenOneDigit = /\d/, // 0 - 9 + parseTokenTwoDigits = /\d\d/, // 00 - 99 + parseTokenThreeDigits = /\d{3}/, // 000 - 999 + parseTokenFourDigits = /\d{4}/, // 0000 - 9999 + parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999 + parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf + + // iso 8601 regex + // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) + isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/, + + isoFormat = 'YYYY-MM-DDTHH:mm:ssZ', + + isoDates = [ + ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/], + ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/], + ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/], + ['GGGG-[W]WW', /\d{4}-W\d{2}/], + ['YYYY-DDD', /\d{4}-\d{3}/] + ], + + // iso time formats and regexes + isoTimes = [ + ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/], + ['HH:mm', /(T| )\d\d:\d\d/], + ['HH', /(T| )\d\d/] + ], + + // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"] + parseTimezoneChunker = /([\+\-]|\d\d)/gi, + + // getter and setter names + proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'), + unitMillisecondFactors = { + 'Milliseconds' : 1, + 'Seconds' : 1e3, + 'Minutes' : 6e4, + 'Hours' : 36e5, + 'Days' : 864e5, + 'Months' : 2592e6, + 'Years' : 31536e6 + }, + + unitAliases = { + ms : 'millisecond', + s : 'second', + m : 'minute', + h : 'hour', + d : 'day', + D : 'date', + w : 'week', + W : 'isoWeek', + M : 'month', + Q : 'quarter', + y : 'year', + DDD : 'dayOfYear', + e : 'weekday', + E : 'isoWeekday', + gg: 'weekYear', + GG: 'isoWeekYear' + }, + + camelFunctions = { + dayofyear : 'dayOfYear', + isoweekday : 'isoWeekday', + isoweek : 'isoWeek', + weekyear : 'weekYear', + isoweekyear : 'isoWeekYear' + }, + + // format function strings + formatFunctions = {}, + + // default relative time thresholds + relativeTimeThresholds = { + s: 45, // seconds to minute + m: 45, // minutes to hour + h: 22, // hours to day + d: 26, // days to month + M: 11 // months to year + }, + + // tokens to ordinalize and pad + ordinalizeTokens = 'DDD w W M D d'.split(' '), + paddedTokens = 'M D H h m s w W'.split(' '), + + formatTokenFunctions = { + M : function () { + return this.month() + 1; + }, + MMM : function (format) { + return this.localeData().monthsShort(this, format); + }, + MMMM : function (format) { + return this.localeData().months(this, format); + }, + D : function () { + return this.date(); + }, + DDD : function () { + return this.dayOfYear(); + }, + d : function () { + return this.day(); + }, + dd : function (format) { + return this.localeData().weekdaysMin(this, format); + }, + ddd : function (format) { + return this.localeData().weekdaysShort(this, format); + }, + dddd : function (format) { + return this.localeData().weekdays(this, format); + }, + w : function () { + return this.week(); + }, + W : function () { + return this.isoWeek(); + }, + YY : function () { + return leftZeroFill(this.year() % 100, 2); + }, + YYYY : function () { + return leftZeroFill(this.year(), 4); + }, + YYYYY : function () { + return leftZeroFill(this.year(), 5); + }, + YYYYYY : function () { + var y = this.year(), sign = y >= 0 ? '+' : '-'; + return sign + leftZeroFill(Math.abs(y), 6); + }, + gg : function () { + return leftZeroFill(this.weekYear() % 100, 2); + }, + gggg : function () { + return leftZeroFill(this.weekYear(), 4); + }, + ggggg : function () { + return leftZeroFill(this.weekYear(), 5); + }, + GG : function () { + return leftZeroFill(this.isoWeekYear() % 100, 2); + }, + GGGG : function () { + return leftZeroFill(this.isoWeekYear(), 4); + }, + GGGGG : function () { + return leftZeroFill(this.isoWeekYear(), 5); + }, + e : function () { + return this.weekday(); + }, + E : function () { + return this.isoWeekday(); + }, + a : function () { + return this.localeData().meridiem(this.hours(), this.minutes(), true); + }, + A : function () { + return this.localeData().meridiem(this.hours(), this.minutes(), false); + }, + H : function () { + return this.hours(); + }, + h : function () { + return this.hours() % 12 || 12; + }, + m : function () { + return this.minutes(); + }, + s : function () { + return this.seconds(); + }, + S : function () { + return toInt(this.milliseconds() / 100); + }, + SS : function () { + return leftZeroFill(toInt(this.milliseconds() / 10), 2); + }, + SSS : function () { + return leftZeroFill(this.milliseconds(), 3); + }, + SSSS : function () { + return leftZeroFill(this.milliseconds(), 3); + }, + Z : function () { + var a = -this.zone(), + b = '+'; + if (a < 0) { + a = -a; + b = '-'; + } + return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2); + }, + ZZ : function () { + var a = -this.zone(), + b = '+'; + if (a < 0) { + a = -a; + b = '-'; + } + return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2); + }, + z : function () { + return this.zoneAbbr(); + }, + zz : function () { + return this.zoneName(); + }, + X : function () { + return this.unix(); + }, + Q : function () { + return this.quarter(); + } + }, + + deprecations = {}, + + lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin']; + + // Pick the first defined of two or three arguments. dfl comes from + // default. + function dfl(a, b, c) { + switch (arguments.length) { + case 2: return a != null ? a : b; + case 3: return a != null ? a : b != null ? b : c; + default: throw new Error('Implement me'); + } + } + + function defaultParsingFlags() { + // We need to deep clone this object, and es5 standard is not very + // helpful. + return { + empty : false, + unusedTokens : [], + unusedInput : [], + overflow : -2, + charsLeftOver : 0, + nullInput : false, + invalidMonth : null, + invalidFormat : false, + userInvalidated : false, + iso: false + }; + } + + function printMsg(msg) { + if (moment.suppressDeprecationWarnings === false && + typeof console !== 'undefined' && console.warn) { + console.warn("Deprecation warning: " + msg); + } + } + + function deprecate(msg, fn) { + var firstTime = true; + return extend(function () { + if (firstTime) { + printMsg(msg); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); + } + + function deprecateSimple(name, msg) { + if (!deprecations[name]) { + printMsg(msg); + deprecations[name] = true; + } + } + + function padToken(func, count) { + return function (a) { + return leftZeroFill(func.call(this, a), count); + }; + } + function ordinalizeToken(func, period) { + return function (a) { + return this.localeData().ordinal(func.call(this, a), period); + }; + } + + while (ordinalizeTokens.length) { + i = ordinalizeTokens.pop(); + formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i); + } + while (paddedTokens.length) { + i = paddedTokens.pop(); + formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2); + } + formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3); + + + /************************************ + Constructors + ************************************/ + + function Locale() { + } + + // Moment prototype object + function Moment(config, skipOverflow) { + if (skipOverflow !== false) { + checkOverflow(config); + } + copyConfig(this, config); + this._d = new Date(+config._d); + } + + // Duration Constructor + function Duration(duration) { + var normalizedInput = normalizeObjectUnits(duration), + years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, + months = normalizedInput.month || 0, + weeks = normalizedInput.week || 0, + days = normalizedInput.day || 0, + hours = normalizedInput.hour || 0, + minutes = normalizedInput.minute || 0, + seconds = normalizedInput.second || 0, + milliseconds = normalizedInput.millisecond || 0; + + // representation for dateAddRemove + this._milliseconds = +milliseconds + + seconds * 1e3 + // 1000 + minutes * 6e4 + // 1000 * 60 + hours * 36e5; // 1000 * 60 * 60 + // Because of dateAddRemove treats 24 hours as different from a + // day when working around DST, we need to store them separately + this._days = +days + + weeks * 7; + // It is impossible translate months into days without knowing + // which months you are are talking about, so we have to store + // it separately. + this._months = +months + + quarters * 3 + + years * 12; + + this._data = {}; + + this._locale = moment.localeData(); + + this._bubble(); + } + + /************************************ + Helpers + ************************************/ + + + function extend(a, b) { + for (var i in b) { + if (b.hasOwnProperty(i)) { + a[i] = b[i]; + } + } + + if (b.hasOwnProperty('toString')) { + a.toString = b.toString; + } + + if (b.hasOwnProperty('valueOf')) { + a.valueOf = b.valueOf; + } + + return a; + } + + function copyConfig(to, from) { + var i, prop, val; + + if (typeof from._isAMomentObject !== 'undefined') { + to._isAMomentObject = from._isAMomentObject; + } + if (typeof from._i !== 'undefined') { + to._i = from._i; + } + if (typeof from._f !== 'undefined') { + to._f = from._f; + } + if (typeof from._l !== 'undefined') { + to._l = from._l; + } + if (typeof from._strict !== 'undefined') { + to._strict = from._strict; + } + if (typeof from._tzm !== 'undefined') { + to._tzm = from._tzm; + } + if (typeof from._isUTC !== 'undefined') { + to._isUTC = from._isUTC; + } + if (typeof from._offset !== 'undefined') { + to._offset = from._offset; + } + if (typeof from._pf !== 'undefined') { + to._pf = from._pf; + } + if (typeof from._locale !== 'undefined') { + to._locale = from._locale; + } + + if (momentProperties.length > 0) { + for (i in momentProperties) { + prop = momentProperties[i]; + val = from[prop]; + if (typeof val !== 'undefined') { + to[prop] = val; + } + } + } + + return to; + } + + function absRound(number) { + if (number < 0) { + return Math.ceil(number); + } else { + return Math.floor(number); + } + } + + // left zero fill a number + // see http://jsperf.com/left-zero-filling for performance comparison + function leftZeroFill(number, targetLength, forceSign) { + var output = '' + Math.abs(number), + sign = number >= 0; + + while (output.length < targetLength) { + output = '0' + output; + } + return (sign ? (forceSign ? '+' : '') : '-') + output; + } + + function positiveMomentsDifference(base, other) { + var res = {milliseconds: 0, months: 0}; + + res.months = other.month() - base.month() + + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } + + res.milliseconds = +other - +(base.clone().add(res.months, 'M')); + + return res; + } + + function momentsDifference(base, other) { + var res; + other = makeAs(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } + + return res; + } + + // TODO: remove 'name' arg after deprecation is removed + function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, "moment()." + name + "(period, number) is deprecated. Please use moment()." + name + "(number, period)."); + tmp = val; val = period; period = tmp; + } + + val = typeof val === 'string' ? +val : val; + dur = moment.duration(val, period); + addOrSubtractDurationFromMoment(this, dur, direction); + return this; + }; + } + + function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) { + var milliseconds = duration._milliseconds, + days = duration._days, + months = duration._months; + updateOffset = updateOffset == null ? true : updateOffset; + + if (milliseconds) { + mom._d.setTime(+mom._d + milliseconds * isAdding); + } + if (days) { + rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding); + } + if (months) { + rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding); + } + if (updateOffset) { + moment.updateOffset(mom, days || months); + } + } + + // check if is an array + function isArray(input) { + return Object.prototype.toString.call(input) === '[object Array]'; + } + + function isDate(input) { + return Object.prototype.toString.call(input) === '[object Date]' || + input instanceof Date; + } + + // compare two arrays, return the number of differences + function compareArrays(array1, array2, dontConvert) { + var len = Math.min(array1.length, array2.length), + lengthDiff = Math.abs(array1.length - array2.length), + diffs = 0, + i; + for (i = 0; i < len; i++) { + if ((dontConvert && array1[i] !== array2[i]) || + (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { + diffs++; + } + } + return diffs + lengthDiff; + } + + function normalizeUnits(units) { + if (units) { + var lowered = units.toLowerCase().replace(/(.)s$/, '$1'); + units = unitAliases[units] || camelFunctions[lowered] || lowered; + } + return units; + } + + function normalizeObjectUnits(inputObject) { + var normalizedInput = {}, + normalizedProp, + prop; + + for (prop in inputObject) { + if (inputObject.hasOwnProperty(prop)) { + normalizedProp = normalizeUnits(prop); + if (normalizedProp) { + normalizedInput[normalizedProp] = inputObject[prop]; + } + } + } + + return normalizedInput; + } + + function makeList(field) { + var count, setter; + + if (field.indexOf('week') === 0) { + count = 7; + setter = 'day'; + } + else if (field.indexOf('month') === 0) { + count = 12; + setter = 'month'; + } + else { + return; + } + + moment[field] = function (format, index) { + var i, getter, + method = moment._locale[field], + results = []; + + if (typeof format === 'number') { + index = format; + format = undefined; + } + + getter = function (i) { + var m = moment().utc().set(setter, i); + return method.call(moment._locale, m, format || ''); + }; + + if (index != null) { + return getter(index); + } + else { + for (i = 0; i < count; i++) { + results.push(getter(i)); + } + return results; + } + }; + } + + function toInt(argumentForCoercion) { + var coercedNumber = +argumentForCoercion, + value = 0; + + if (coercedNumber !== 0 && isFinite(coercedNumber)) { + if (coercedNumber >= 0) { + value = Math.floor(coercedNumber); + } else { + value = Math.ceil(coercedNumber); + } + } + + return value; + } + + function daysInMonth(year, month) { + return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); + } + + function weeksInYear(year, dow, doy) { + return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week; + } + + function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; + } + + function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; + } + + function checkOverflow(m) { + var overflow; + if (m._a && m._pf.overflow === -2) { + overflow = + m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH : + m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE : + m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR : + m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE : + m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND : + m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : + -1; + + if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { + overflow = DATE; + } + + m._pf.overflow = overflow; + } + } + + function isValid(m) { + if (m._isValid == null) { + m._isValid = !isNaN(m._d.getTime()) && + m._pf.overflow < 0 && + !m._pf.empty && + !m._pf.invalidMonth && + !m._pf.nullInput && + !m._pf.invalidFormat && + !m._pf.userInvalidated; + + if (m._strict) { + m._isValid = m._isValid && + m._pf.charsLeftOver === 0 && + m._pf.unusedTokens.length === 0; + } + } + return m._isValid; + } + + function normalizeLocale(key) { + return key ? key.toLowerCase().replace('_', '-') : key; + } + + // pick the locale from the array + // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each + // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root + function chooseLocale(names) { + var i = 0, j, next, locale, split; + + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + if (locale) { + return locale; + } + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; + } + return null; + } + + function loadLocale(name) { + var oldLocale = null; + if (!locales[name] && hasModule) { + try { + oldLocale = moment.locale(); + require('./locale/' + name); + // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales + moment.locale(oldLocale); + } catch (e) { } + } + return locales[name]; + } + + // Return a moment from input, that is local/utc/zone equivalent to model. + function makeAs(input, model) { + return model._isUTC ? moment(input).zone(model._offset || 0) : + moment(input).local(); + } + + /************************************ + Locale + ************************************/ + + + extend(Locale.prototype, { + + set : function (config) { + var prop, i; + for (i in config) { + prop = config[i]; + if (typeof prop === 'function') { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + }, + + _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + months : function (m) { + return this._months[m.month()]; + }, + + _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + monthsShort : function (m) { + return this._monthsShort[m.month()]; + }, + + monthsParse : function (monthName) { + var i, mom, regex; + + if (!this._monthsParse) { + this._monthsParse = []; + } + + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + if (!this._monthsParse[i]) { + mom = moment.utc([2000, i]); + regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); + this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (this._monthsParse[i].test(monthName)) { + return i; + } + } + }, + + _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdays : function (m) { + return this._weekdays[m.day()]; + }, + + _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysShort : function (m) { + return this._weekdaysShort[m.day()]; + }, + + _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + weekdaysMin : function (m) { + return this._weekdaysMin[m.day()]; + }, + + weekdaysParse : function (weekdayName) { + var i, mom, regex; + + if (!this._weekdaysParse) { + this._weekdaysParse = []; + } + + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + if (!this._weekdaysParse[i]) { + mom = moment([2000, 1]).day(i); + regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); + this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (this._weekdaysParse[i].test(weekdayName)) { + return i; + } + } + }, + + _longDateFormat : { + LT : 'h:mm A', + L : 'MM/DD/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY LT', + LLLL : 'dddd, MMMM D, YYYY LT' + }, + longDateFormat : function (key) { + var output = this._longDateFormat[key]; + if (!output && this._longDateFormat[key.toUpperCase()]) { + output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) { + return val.slice(1); + }); + this._longDateFormat[key] = output; + } + return output; + }, + + isPM : function (input) { + // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays + // Using charAt should be more compatible. + return ((input + '').toLowerCase().charAt(0) === 'p'); + }, + + _meridiemParse : /[ap]\.?m?\.?/i, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'pm' : 'PM'; + } else { + return isLower ? 'am' : 'AM'; + } + }, + + _calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + calendar : function (key, mom) { + var output = this._calendar[key]; + return typeof output === 'function' ? output.apply(mom) : output; + }, + + _relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + + relativeTime : function (number, withoutSuffix, string, isFuture) { + var output = this._relativeTime[string]; + return (typeof output === 'function') ? + output(number, withoutSuffix, string, isFuture) : + output.replace(/%d/i, number); + }, + + pastFuture : function (diff, output) { + var format = this._relativeTime[diff > 0 ? 'future' : 'past']; + return typeof format === 'function' ? format(output) : format.replace(/%s/i, output); + }, + + ordinal : function (number) { + return this._ordinal.replace('%d', number); + }, + _ordinal : '%d', + + preparse : function (string) { + return string; + }, + + postformat : function (string) { + return string; + }, + + week : function (mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; + }, + + _week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + }, + + _invalidDate: 'Invalid date', + invalidDate: function () { + return this._invalidDate; + } + }); + + /************************************ + Formatting + ************************************/ + + + function removeFormattingTokens(input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|\]$/g, ''); + } + return input.replace(/\\/g, ''); + } + + function makeFormatFunction(format) { + var array = format.match(formattingTokens), i, length; + + for (i = 0, length = array.length; i < length; i++) { + if (formatTokenFunctions[array[i]]) { + array[i] = formatTokenFunctions[array[i]]; + } else { + array[i] = removeFormattingTokens(array[i]); + } + } + + return function (mom) { + var output = ''; + for (i = 0; i < length; i++) { + output += array[i] instanceof Function ? array[i].call(mom, format) : array[i]; + } + return output; + }; + } + + // format date using native date object + function formatMoment(m, format) { + if (!m.isValid()) { + return m.localeData().invalidDate(); + } + + format = expandFormat(format, m.localeData()); + + if (!formatFunctions[format]) { + formatFunctions[format] = makeFormatFunction(format); + } + + return formatFunctions[format](m); + } + + function expandFormat(format, locale) { + var i = 5; + + function replaceLongDateFormatTokens(input) { + return locale.longDateFormat(input) || input; + } + + localFormattingTokens.lastIndex = 0; + while (i >= 0 && localFormattingTokens.test(format)) { + format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); + localFormattingTokens.lastIndex = 0; + i -= 1; + } + + return format; + } + + + /************************************ + Parsing + ************************************/ + + + // get the regex to find the next token + function getParseRegexForToken(token, config) { + var a, strict = config._strict; + switch (token) { + case 'Q': + return parseTokenOneDigit; + case 'DDDD': + return parseTokenThreeDigits; + case 'YYYY': + case 'GGGG': + case 'gggg': + return strict ? parseTokenFourDigits : parseTokenOneToFourDigits; + case 'Y': + case 'G': + case 'g': + return parseTokenSignedNumber; + case 'YYYYYY': + case 'YYYYY': + case 'GGGGG': + case 'ggggg': + return strict ? parseTokenSixDigits : parseTokenOneToSixDigits; + case 'S': + if (strict) { + return parseTokenOneDigit; + } + /* falls through */ + case 'SS': + if (strict) { + return parseTokenTwoDigits; + } + /* falls through */ + case 'SSS': + if (strict) { + return parseTokenThreeDigits; + } + /* falls through */ + case 'DDD': + return parseTokenOneToThreeDigits; + case 'MMM': + case 'MMMM': + case 'dd': + case 'ddd': + case 'dddd': + return parseTokenWord; + case 'a': + case 'A': + return config._locale._meridiemParse; + case 'X': + return parseTokenTimestampMs; + case 'Z': + case 'ZZ': + return parseTokenTimezone; + case 'T': + return parseTokenT; + case 'SSSS': + return parseTokenDigits; + case 'MM': + case 'DD': + case 'YY': + case 'GG': + case 'gg': + case 'HH': + case 'hh': + case 'mm': + case 'ss': + case 'ww': + case 'WW': + return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits; + case 'M': + case 'D': + case 'd': + case 'H': + case 'h': + case 'm': + case 's': + case 'w': + case 'W': + case 'e': + case 'E': + return parseTokenOneOrTwoDigits; + case 'Do': + return parseTokenOrdinal; + default : + a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i')); + return a; + } + } + + function timezoneMinutesFromString(string) { + string = string || ''; + var possibleTzMatches = (string.match(parseTokenTimezone) || []), + tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [], + parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0], + minutes = +(parts[1] * 60) + toInt(parts[2]); + + return parts[0] === '+' ? -minutes : minutes; + } + + // function to convert string input to date + function addTimeToArrayFromToken(token, input, config) { + var a, datePartArray = config._a; + + switch (token) { + // QUARTER + case 'Q': + if (input != null) { + datePartArray[MONTH] = (toInt(input) - 1) * 3; + } + break; + // MONTH + case 'M' : // fall through to MM + case 'MM' : + if (input != null) { + datePartArray[MONTH] = toInt(input) - 1; + } + break; + case 'MMM' : // fall through to MMMM + case 'MMMM' : + a = config._locale.monthsParse(input); + // if we didn't find a month name, mark the date as invalid. + if (a != null) { + datePartArray[MONTH] = a; + } else { + config._pf.invalidMonth = input; + } + break; + // DAY OF MONTH + case 'D' : // fall through to DD + case 'DD' : + if (input != null) { + datePartArray[DATE] = toInt(input); + } + break; + case 'Do' : + if (input != null) { + datePartArray[DATE] = toInt(parseInt(input, 10)); + } + break; + // DAY OF YEAR + case 'DDD' : // fall through to DDDD + case 'DDDD' : + if (input != null) { + config._dayOfYear = toInt(input); + } + + break; + // YEAR + case 'YY' : + datePartArray[YEAR] = moment.parseTwoDigitYear(input); + break; + case 'YYYY' : + case 'YYYYY' : + case 'YYYYYY' : + datePartArray[YEAR] = toInt(input); + break; + // AM / PM + case 'a' : // fall through to A + case 'A' : + config._isPm = config._locale.isPM(input); + break; + // 24 HOUR + case 'H' : // fall through to hh + case 'HH' : // fall through to hh + case 'h' : // fall through to hh + case 'hh' : + datePartArray[HOUR] = toInt(input); + break; + // MINUTE + case 'm' : // fall through to mm + case 'mm' : + datePartArray[MINUTE] = toInt(input); + break; + // SECOND + case 's' : // fall through to ss + case 'ss' : + datePartArray[SECOND] = toInt(input); + break; + // MILLISECOND + case 'S' : + case 'SS' : + case 'SSS' : + case 'SSSS' : + datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000); + break; + // UNIX TIMESTAMP WITH MS + case 'X': + config._d = new Date(parseFloat(input) * 1000); + break; + // TIMEZONE + case 'Z' : // fall through to ZZ + case 'ZZ' : + config._useUTC = true; + config._tzm = timezoneMinutesFromString(input); + break; + // WEEKDAY - human + case 'dd': + case 'ddd': + case 'dddd': + a = config._locale.weekdaysParse(input); + // if we didn't get a weekday name, mark the date as invalid + if (a != null) { + config._w = config._w || {}; + config._w['d'] = a; + } else { + config._pf.invalidWeekday = input; + } + break; + // WEEK, WEEK DAY - numeric + case 'w': + case 'ww': + case 'W': + case 'WW': + case 'd': + case 'e': + case 'E': + token = token.substr(0, 1); + /* falls through */ + case 'gggg': + case 'GGGG': + case 'GGGGG': + token = token.substr(0, 2); + if (input) { + config._w = config._w || {}; + config._w[token] = toInt(input); + } + break; + case 'gg': + case 'GG': + config._w = config._w || {}; + config._w[token] = moment.parseTwoDigitYear(input); + } + } + + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year); + week = dfl(w.W, 1); + weekday = dfl(w.E, 1); + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year); + week = dfl(w.w, 1); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < dow) { + ++week; + } + } else if (w.e != null) { + // local weekday -- counting starts from begining of week + weekday = w.e + dow; + } else { + // default to begining of week + weekday = dow; + } + } + temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow); + + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } + + // convert an array to a date. + // the array should mirror the parameters below + // note: all values past the year are optional and will default to the lowest possible value. + // [year, month, day , hour, minute, second, millisecond] + function dateFromConfig(config) { + var i, date, input = [], currentDate, yearToUse; + + if (config._d) { + return; + } + + currentDate = currentDateArray(config); + + //compute day of the year from weeks and weekdays + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } + + //if the day of the year is set, figure out what it is + if (config._dayOfYear) { + yearToUse = dfl(config._a[YEAR], currentDate[YEAR]); + + if (config._dayOfYear > daysInYear(yearToUse)) { + config._pf._overflowDayOfYear = true; + } + + date = makeUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } + + // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; + } + + // Zero out whatever was not defaulted, including time + for (; i < 7; i++) { + config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; + } + + config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input); + // Apply timezone offset from input. The actual zone can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() + config._tzm); + } + } + + function dateFromObject(config) { + var normalizedInput; + + if (config._d) { + return; + } + + normalizedInput = normalizeObjectUnits(config._i); + config._a = [ + normalizedInput.year, + normalizedInput.month, + normalizedInput.day, + normalizedInput.hour, + normalizedInput.minute, + normalizedInput.second, + normalizedInput.millisecond + ]; + + dateFromConfig(config); + } + + function currentDateArray(config) { + var now = new Date(); + if (config._useUTC) { + return [ + now.getUTCFullYear(), + now.getUTCMonth(), + now.getUTCDate() + ]; + } else { + return [now.getFullYear(), now.getMonth(), now.getDate()]; + } + } + + // date from string and format string + function makeDateFromStringAndFormat(config) { + if (config._f === moment.ISO_8601) { + parseISO(config); + return; + } + + config._a = []; + config._pf.empty = true; + + // This array is used to make a Date, either with `new Date` or `Date.UTC` + var string = '' + config._i, + i, parsedInput, tokens, token, skipped, + stringLength = string.length, + totalParsedInputLength = 0; + + tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; + + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; + if (parsedInput) { + skipped = string.substr(0, string.indexOf(parsedInput)); + if (skipped.length > 0) { + config._pf.unusedInput.push(skipped); + } + string = string.slice(string.indexOf(parsedInput) + parsedInput.length); + totalParsedInputLength += parsedInput.length; + } + // don't parse if it's not a known token + if (formatTokenFunctions[token]) { + if (parsedInput) { + config._pf.empty = false; + } + else { + config._pf.unusedTokens.push(token); + } + addTimeToArrayFromToken(token, parsedInput, config); + } + else if (config._strict && !parsedInput) { + config._pf.unusedTokens.push(token); + } + } + + // add remaining unparsed input length to the string + config._pf.charsLeftOver = stringLength - totalParsedInputLength; + if (string.length > 0) { + config._pf.unusedInput.push(string); + } + + // handle am pm + if (config._isPm && config._a[HOUR] < 12) { + config._a[HOUR] += 12; + } + // if is 12 am, change hours to 0 + if (config._isPm === false && config._a[HOUR] === 12) { + config._a[HOUR] = 0; + } + + dateFromConfig(config); + checkOverflow(config); + } + + function unescapeFormat(s) { + return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + }); + } + + // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript + function regexpEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + } + + // date from string and array of format strings + function makeDateFromStringAndArray(config) { + var tempConfig, + bestMoment, + + scoreToBeat, + i, + currentScore; + + if (config._f.length === 0) { + config._pf.invalidFormat = true; + config._d = new Date(NaN); + return; + } + + for (i = 0; i < config._f.length; i++) { + currentScore = 0; + tempConfig = copyConfig({}, config); + tempConfig._pf = defaultParsingFlags(); + tempConfig._f = config._f[i]; + makeDateFromStringAndFormat(tempConfig); + + if (!isValid(tempConfig)) { + continue; + } + + // if there is any input that was not parsed add a penalty for that format + currentScore += tempConfig._pf.charsLeftOver; + + //or tokens + currentScore += tempConfig._pf.unusedTokens.length * 10; + + tempConfig._pf.score = currentScore; + + if (scoreToBeat == null || currentScore < scoreToBeat) { + scoreToBeat = currentScore; + bestMoment = tempConfig; + } + } + + extend(config, bestMoment || tempConfig); + } + + // date from iso format + function parseISO(config) { + var i, l, + string = config._i, + match = isoRegex.exec(string); + + if (match) { + config._pf.iso = true; + for (i = 0, l = isoDates.length; i < l; i++) { + if (isoDates[i][1].exec(string)) { + // match[5] should be "T" or undefined + config._f = isoDates[i][0] + (match[6] || ' '); + break; + } + } + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(string)) { + config._f += isoTimes[i][0]; + break; + } + } + if (string.match(parseTokenTimezone)) { + config._f += 'Z'; + } + makeDateFromStringAndFormat(config); + } else { + config._isValid = false; + } + } + + // date from iso format or fallback + function makeDateFromString(config) { + parseISO(config); + if (config._isValid === false) { + delete config._isValid; + moment.createFromInputFallback(config); + } + } + + function makeDateFromInput(config) { + var input = config._i, matched; + if (input === undefined) { + config._d = new Date(); + } else if (isDate(input)) { + config._d = new Date(+input); + } else if ((matched = aspNetJsonRegex.exec(input)) !== null) { + config._d = new Date(+matched[1]); + } else if (typeof input === 'string') { + makeDateFromString(config); + } else if (isArray(input)) { + config._a = input.slice(0); + dateFromConfig(config); + } else if (typeof(input) === 'object') { + dateFromObject(config); + } else if (typeof(input) === 'number') { + // from milliseconds + config._d = new Date(input); + } else { + moment.createFromInputFallback(config); + } + } + + function makeDate(y, m, d, h, M, s, ms) { + //can't just apply() to create a date: + //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply + var date = new Date(y, m, d, h, M, s, ms); + + //the date constructor doesn't accept years < 1970 + if (y < 1970) { + date.setFullYear(y); + } + return date; + } + + function makeUTCDate(y) { + var date = new Date(Date.UTC.apply(null, arguments)); + if (y < 1970) { + date.setUTCFullYear(y); + } + return date; + } + + function parseWeekday(input, locale) { + if (typeof input === 'string') { + if (!isNaN(input)) { + input = parseInt(input, 10); + } + else { + input = locale.weekdaysParse(input); + if (typeof input !== 'number') { + return null; + } + } + } + return input; + } + + /************************************ + Relative Time + ************************************/ + + + // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize + function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); + } + + function relativeTime(posNegDuration, withoutSuffix, locale) { + var duration = moment.duration(posNegDuration).abs(), + seconds = round(duration.as('s')), + minutes = round(duration.as('m')), + hours = round(duration.as('h')), + days = round(duration.as('d')), + months = round(duration.as('M')), + years = round(duration.as('y')), + + args = seconds < relativeTimeThresholds.s && ['s', seconds] || + minutes === 1 && ['m'] || + minutes < relativeTimeThresholds.m && ['mm', minutes] || + hours === 1 && ['h'] || + hours < relativeTimeThresholds.h && ['hh', hours] || + days === 1 && ['d'] || + days < relativeTimeThresholds.d && ['dd', days] || + months === 1 && ['M'] || + months < relativeTimeThresholds.M && ['MM', months] || + years === 1 && ['y'] || ['yy', years]; + + args[2] = withoutSuffix; + args[3] = +posNegDuration > 0; + args[4] = locale; + return substituteTimeAgo.apply({}, args); + } + + + /************************************ + Week of Year + ************************************/ + + + // firstDayOfWeek 0 = sun, 6 = sat + // the day of the week that starts the week + // (usually sunday or monday) + // firstDayOfWeekOfYear 0 = sun, 6 = sat + // the first week is the week that contains the first + // of this day of the week + // (eg. ISO weeks use thursday (4)) + function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) { + var end = firstDayOfWeekOfYear - firstDayOfWeek, + daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(), + adjustedMoment; + + + if (daysToDayOfWeek > end) { + daysToDayOfWeek -= 7; + } + + if (daysToDayOfWeek < end - 7) { + daysToDayOfWeek += 7; + } + + adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd'); + return { + week: Math.ceil(adjustedMoment.dayOfYear() / 7), + year: adjustedMoment.year() + }; + } + + //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday + function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) { + var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear; + + d = d === 0 ? 7 : d; + weekday = weekday != null ? weekday : firstDayOfWeek; + daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0); + dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1; + + return { + year: dayOfYear > 0 ? year : year - 1, + dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear + }; + } + + /************************************ + Top Level Functions + ************************************/ + + function makeMoment(config) { + var input = config._i, + format = config._f; + + config._locale = config._locale || moment.localeData(config._l); + + if (input === null || (format === undefined && input === '')) { + return moment.invalid({nullInput: true}); + } + + if (typeof input === 'string') { + config._i = input = config._locale.preparse(input); + } + + if (moment.isMoment(input)) { + return new Moment(input, true); + } else if (format) { + if (isArray(format)) { + makeDateFromStringAndArray(config); + } else { + makeDateFromStringAndFormat(config); + } + } else { + makeDateFromInput(config); + } + + return new Moment(config); + } + + moment = function (input, format, locale, strict) { + var c; + + if (typeof(locale) === "boolean") { + strict = locale; + locale = undefined; + } + // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + c = {}; + c._isAMomentObject = true; + c._i = input; + c._f = format; + c._l = locale; + c._strict = strict; + c._isUTC = false; + c._pf = defaultParsingFlags(); + + return makeMoment(c); + }; + + moment.suppressDeprecationWarnings = false; + + moment.createFromInputFallback = deprecate( + 'moment construction falls back to js Date. This is ' + + 'discouraged and will be removed in upcoming major ' + + 'release. Please refer to ' + + 'https://github.com/moment/moment/issues/1407 for more info.', + function (config) { + config._d = new Date(config._i); + } + ); + + // Pick a moment m from moments so that m[fn](other) is true for all + // other. This relies on the function fn to be transitive. + // + // moments should either be an array of moment objects or an array, whose + // first element is an array of moment objects. + function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return moment(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (moments[i][fn](res)) { + res = moments[i]; + } + } + return res; + } + + moment.min = function () { + var args = [].slice.call(arguments, 0); + + return pickBy('isBefore', args); + }; + + moment.max = function () { + var args = [].slice.call(arguments, 0); + + return pickBy('isAfter', args); + }; + + // creating with utc + moment.utc = function (input, format, locale, strict) { + var c; + + if (typeof(locale) === "boolean") { + strict = locale; + locale = undefined; + } + // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + c = {}; + c._isAMomentObject = true; + c._useUTC = true; + c._isUTC = true; + c._l = locale; + c._i = input; + c._f = format; + c._strict = strict; + c._pf = defaultParsingFlags(); + + return makeMoment(c).utc(); + }; + + // creating with unix timestamp (in seconds) + moment.unix = function (input) { + return moment(input * 1000); + }; + + // duration + moment.duration = function (input, key) { + var duration = input, + // matching against regexp is expensive, do it on demand + match = null, + sign, + ret, + parseIso, + diffRes; + + if (moment.isDuration(input)) { + duration = { + ms: input._milliseconds, + d: input._days, + M: input._months + }; + } else if (typeof input === 'number') { + duration = {}; + if (key) { + duration[key] = input; + } else { + duration.milliseconds = input; + } + } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + duration = { + y: 0, + d: toInt(match[DATE]) * sign, + h: toInt(match[HOUR]) * sign, + m: toInt(match[MINUTE]) * sign, + s: toInt(match[SECOND]) * sign, + ms: toInt(match[MILLISECOND]) * sign + }; + } else if (!!(match = isoDurationRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + parseIso = function (inp) { + // We'd normally use ~~inp for this, but unfortunately it also + // converts floats to ints. + // inp may be undefined, so careful calling replace on it. + var res = inp && parseFloat(inp.replace(',', '.')); + // apply sign while we're at it + return (isNaN(res) ? 0 : res) * sign; + }; + duration = { + y: parseIso(match[2]), + M: parseIso(match[3]), + d: parseIso(match[4]), + h: parseIso(match[5]), + m: parseIso(match[6]), + s: parseIso(match[7]), + w: parseIso(match[8]) + }; + } else if (typeof duration === 'object' && + ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(moment(duration.from), moment(duration.to)); + + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; + } + + ret = new Duration(duration); + + if (moment.isDuration(input) && input.hasOwnProperty('_locale')) { + ret._locale = input._locale; + } + + return ret; + }; + + // version number + moment.version = VERSION; + + // default format + moment.defaultFormat = isoFormat; + + // constant that refers to the ISO standard + moment.ISO_8601 = function () {}; + + // Plugins that add properties should also add the key here (null value), + // so we can properly clone ourselves. + moment.momentProperties = momentProperties; + + // This function will be called whenever a moment is mutated. + // It is intended to keep the offset in sync with the timezone. + moment.updateOffset = function () {}; + + // This function allows you to set a threshold for relative time strings + moment.relativeTimeThreshold = function (threshold, limit) { + if (relativeTimeThresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return relativeTimeThresholds[threshold]; + } + relativeTimeThresholds[threshold] = limit; + return true; + }; + + moment.lang = deprecate( + "moment.lang is deprecated. Use moment.locale instead.", + function (key, value) { + return moment.locale(key, value); + } + ); + + // This function will load locale and then set the global locale. If + // no arguments are passed in, it will simply return the current global + // locale key. + moment.locale = function (key, values) { + var data; + if (key) { + if (typeof(values) !== "undefined") { + data = moment.defineLocale(key, values); + } + else { + data = moment.localeData(key); + } + + if (data) { + moment.duration._locale = moment._locale = data; + } + } + + return moment._locale._abbr; + }; + + moment.defineLocale = function (name, values) { + if (values !== null) { + values.abbr = name; + if (!locales[name]) { + locales[name] = new Locale(); + } + locales[name].set(values); + + // backwards compat for now: also set the locale + moment.locale(name); + + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } + }; + + moment.langData = deprecate( + "moment.langData is deprecated. Use moment.localeData instead.", + function (key) { + return moment.localeData(key); + } + ); + + // returns locale data + moment.localeData = function (key) { + var locale; + + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } + + if (!key) { + return moment._locale; + } + + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; + } + + return chooseLocale(key); + }; + + // compare moment object + moment.isMoment = function (obj) { + return obj instanceof Moment || + (obj != null && obj.hasOwnProperty('_isAMomentObject')); + }; + + // for typechecking Duration objects + moment.isDuration = function (obj) { + return obj instanceof Duration; + }; + + for (i = lists.length - 1; i >= 0; --i) { + makeList(lists[i]); + } + + moment.normalizeUnits = function (units) { + return normalizeUnits(units); + }; + + moment.invalid = function (flags) { + var m = moment.utc(NaN); + if (flags != null) { + extend(m._pf, flags); + } + else { + m._pf.userInvalidated = true; + } + + return m; + }; + + moment.parseZone = function () { + return moment.apply(null, arguments).parseZone(); + }; + + moment.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + }; + + /************************************ + Moment Prototype + ************************************/ + + + extend(moment.fn = Moment.prototype, { + + clone : function () { + return moment(this); + }, + + valueOf : function () { + return +this._d + ((this._offset || 0) * 60000); + }, + + unix : function () { + return Math.floor(+this / 1000); + }, + + toString : function () { + return this.clone().locale('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ"); + }, + + toDate : function () { + return this._offset ? new Date(+this) : this._d; + }, + + toISOString : function () { + var m = moment(this).utc(); + if (0 < m.year() && m.year() <= 9999) { + return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + } else { + return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + } + }, + + toArray : function () { + var m = this; + return [ + m.year(), + m.month(), + m.date(), + m.hours(), + m.minutes(), + m.seconds(), + m.milliseconds() + ]; + }, + + isValid : function () { + return isValid(this); + }, + + isDSTShifted : function () { + if (this._a) { + return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; + } + + return false; + }, + + parsingFlags : function () { + return extend({}, this._pf); + }, + + invalidAt: function () { + return this._pf.overflow; + }, + + utc : function (keepLocalTime) { + return this.zone(0, keepLocalTime); + }, + + local : function (keepLocalTime) { + if (this._isUTC) { + this.zone(0, keepLocalTime); + this._isUTC = false; + + if (keepLocalTime) { + this.add(this._d.getTimezoneOffset(), 'm'); + } + } + return this; + }, + + format : function (inputString) { + var output = formatMoment(this, inputString || moment.defaultFormat); + return this.localeData().postformat(output); + }, + + add : createAdder(1, 'add'), + + subtract : createAdder(-1, 'subtract'), + + diff : function (input, units, asFloat) { + var that = makeAs(input, this), + zoneDiff = (this.zone() - that.zone()) * 6e4, + diff, output; + + units = normalizeUnits(units); + + if (units === 'year' || units === 'month') { + // average number of days in the months in the given dates + diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2 + // difference in months + output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); + // adjust by taking difference in days, average number of days + // and dst in the given months. + output += ((this - moment(this).startOf('month')) - + (that - moment(that).startOf('month'))) / diff; + // same as above but with zones, to negate all dst + output -= ((this.zone() - moment(this).startOf('month').zone()) - + (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff; + if (units === 'year') { + output = output / 12; + } + } else { + diff = (this - that); + output = units === 'second' ? diff / 1e3 : // 1000 + units === 'minute' ? diff / 6e4 : // 1000 * 60 + units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60 + units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst + units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst + diff; + } + return asFloat ? output : absRound(output); + }, + + from : function (time, withoutSuffix) { + return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + }, + + fromNow : function (withoutSuffix) { + return this.from(moment(), withoutSuffix); + }, + + calendar : function (time) { + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're zone'd or not. + var now = time || moment(), + sod = makeAs(now, this).startOf('day'), + diff = this.diff(sod, 'days', true), + format = diff < -6 ? 'sameElse' : + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : 'sameElse'; + return this.format(this.localeData().calendar(format, this)); + }, + + isLeapYear : function () { + return isLeapYear(this.year()); + }, + + isDST : function () { + return (this.zone() < this.clone().month(0).zone() || + this.zone() < this.clone().month(5).zone()); + }, + + day : function (input) { + var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); + if (input != null) { + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); + } else { + return day; + } + }, + + month : makeAccessor('Month', true), + + startOf : function (units) { + units = normalizeUnits(units); + // the following switch intentionally omits break keywords + // to utilize falling through the cases. + switch (units) { + case 'year': + this.month(0); + /* falls through */ + case 'quarter': + case 'month': + this.date(1); + /* falls through */ + case 'week': + case 'isoWeek': + case 'day': + this.hours(0); + /* falls through */ + case 'hour': + this.minutes(0); + /* falls through */ + case 'minute': + this.seconds(0); + /* falls through */ + case 'second': + this.milliseconds(0); + /* falls through */ + } + + // weeks are a special case + if (units === 'week') { + this.weekday(0); + } else if (units === 'isoWeek') { + this.isoWeekday(1); + } + + // quarters are also special + if (units === 'quarter') { + this.month(Math.floor(this.month() / 3) * 3); + } + + return this; + }, + + endOf: function (units) { + units = normalizeUnits(units); + return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); + }, + + isAfter: function (input, units) { + units = typeof units !== 'undefined' ? units : 'millisecond'; + return +this.clone().startOf(units) > +moment(input).startOf(units); + }, + + isBefore: function (input, units) { + units = typeof units !== 'undefined' ? units : 'millisecond'; + return +this.clone().startOf(units) < +moment(input).startOf(units); + }, + + isSame: function (input, units) { + units = units || 'ms'; + return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); + }, + + min: deprecate( + 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548', + function (other) { + other = moment.apply(null, arguments); + return other < this ? this : other; + } + ), + + max: deprecate( + 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548', + function (other) { + other = moment.apply(null, arguments); + return other > this ? this : other; + } + ), + + // keepLocalTime = true means only change the timezone, without + // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]--> + // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone + // +0200, so we adjust the time as needed, to be valid. + // + // Keeping the time actually adds/subtracts (one hour) + // from the actual represented time. That is why we call updateOffset + // a second time. In case it wants us to change the offset again + // _changeInProgress == true case, then we have to adjust, because + // there is no such time in the given timezone. + zone : function (input, keepLocalTime) { + var offset = this._offset || 0, + localAdjust; + if (input != null) { + if (typeof input === 'string') { + input = timezoneMinutesFromString(input); + } + if (Math.abs(input) < 16) { + input = input * 60; + } + if (!this._isUTC && keepLocalTime) { + localAdjust = this._d.getTimezoneOffset(); + } + this._offset = input; + this._isUTC = true; + if (localAdjust != null) { + this.subtract(localAdjust, 'm'); + } + if (offset !== input) { + if (!keepLocalTime || this._changeInProgress) { + addOrSubtractDurationFromMoment(this, + moment.duration(offset - input, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + moment.updateOffset(this, true); + this._changeInProgress = null; + } + } + } else { + return this._isUTC ? offset : this._d.getTimezoneOffset(); + } + return this; + }, + + zoneAbbr : function () { + return this._isUTC ? 'UTC' : ''; + }, + + zoneName : function () { + return this._isUTC ? 'Coordinated Universal Time' : ''; + }, + + parseZone : function () { + if (this._tzm) { + this.zone(this._tzm); + } else if (typeof this._i === 'string') { + this.zone(this._i); + } + return this; + }, + + hasAlignedHourOffset : function (input) { + if (!input) { + input = 0; + } + else { + input = moment(input).zone(); + } + + return (this.zone() - input) % 60 === 0; + }, + + daysInMonth : function () { + return daysInMonth(this.year(), this.month()); + }, + + dayOfYear : function (input) { + var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); + }, + + quarter : function (input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); + }, + + weekYear : function (input) { + var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year; + return input == null ? year : this.add((input - year), 'y'); + }, + + isoWeekYear : function (input) { + var year = weekOfYear(this, 1, 4).year; + return input == null ? year : this.add((input - year), 'y'); + }, + + week : function (input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); + }, + + isoWeek : function (input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); + }, + + weekday : function (input) { + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); + }, + + isoWeekday : function (input) { + // behaves the same as moment#day except + // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) + // as a setter, sunday should belong to the previous week. + return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); + }, + + isoWeeksInYear : function () { + return weeksInYear(this.year(), 1, 4); + }, + + weeksInYear : function () { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); + }, + + get : function (units) { + units = normalizeUnits(units); + return this[units](); + }, + + set : function (units, value) { + units = normalizeUnits(units); + if (typeof this[units] === 'function') { + this[units](value); + } + return this; + }, + + // If passed a locale key, it will set the locale for this + // instance. Otherwise, it will return the locale configuration + // variables for this instance. + locale : function (key) { + if (key === undefined) { + return this._locale._abbr; + } else { + this._locale = moment.localeData(key); + return this; + } + }, + + lang : deprecate( + "moment().lang() is deprecated. Use moment().localeData() instead.", + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + this._locale = moment.localeData(key); + return this; + } + } + ), + + localeData : function () { + return this._locale; + } + }); + + function rawMonthSetter(mom, value) { + var dayOfMonth; + + // TODO: Move this out of here! + if (typeof value === 'string') { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (typeof value !== 'number') { + return mom; + } + } + + dayOfMonth = Math.min(mom.date(), + daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; + } + + function rawGetter(mom, unit) { + return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit](); + } + + function rawSetter(mom, unit, value) { + if (unit === 'Month') { + return rawMonthSetter(mom, value); + } else { + return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } + + function makeAccessor(unit, keepTime) { + return function (value) { + if (value != null) { + rawSetter(this, unit, value); + moment.updateOffset(this, keepTime); + return this; + } else { + return rawGetter(this, unit); + } + }; + } + + moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false); + moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false); + moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false); + // Setting the hour should keep the time, because the user explicitly + // specified which hour he wants. So trying to maintain the same hour (in + // a new timezone) makes sense. Adding/subtracting hours does not follow + // this rule. + moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true); + // moment.fn.month is defined separately + moment.fn.date = makeAccessor('Date', true); + moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true)); + moment.fn.year = makeAccessor('FullYear', true); + moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true)); + + // add plural methods + moment.fn.days = moment.fn.day; + moment.fn.months = moment.fn.month; + moment.fn.weeks = moment.fn.week; + moment.fn.isoWeeks = moment.fn.isoWeek; + moment.fn.quarters = moment.fn.quarter; + + // add aliased format methods + moment.fn.toJSON = moment.fn.toISOString; + + /************************************ + Duration Prototype + ************************************/ + + + function daysToYears (days) { + // 400 years have 146097 days (taking into account leap year rules) + return days * 400 / 146097; + } + + function yearsToDays (years) { + // years * 365 + absRound(years / 4) - + // absRound(years / 100) + absRound(years / 400); + return years * 146097 / 400; + } + + extend(moment.duration.fn = Duration.prototype, { + + _bubble : function () { + var milliseconds = this._milliseconds, + days = this._days, + months = this._months, + data = this._data, + seconds, minutes, hours, years = 0; + + // The following code bubbles up values, see the tests for + // examples of what that means. + data.milliseconds = milliseconds % 1000; + + seconds = absRound(milliseconds / 1000); + data.seconds = seconds % 60; + + minutes = absRound(seconds / 60); + data.minutes = minutes % 60; + + hours = absRound(minutes / 60); + data.hours = hours % 24; + + days += absRound(hours / 24); + + // Accurately convert days to years, assume start from year 0. + years = absRound(daysToYears(days)); + days -= absRound(yearsToDays(years)); + + // 30 days to a month + // TODO (iskren): Use anchor date (like 1st Jan) to compute this. + months += absRound(days / 30); + days %= 30; + + // 12 months -> 1 year + years += absRound(months / 12); + months %= 12; + + data.days = days; + data.months = months; + data.years = years; + }, + + abs : function () { + this._milliseconds = Math.abs(this._milliseconds); + this._days = Math.abs(this._days); + this._months = Math.abs(this._months); + + this._data.milliseconds = Math.abs(this._data.milliseconds); + this._data.seconds = Math.abs(this._data.seconds); + this._data.minutes = Math.abs(this._data.minutes); + this._data.hours = Math.abs(this._data.hours); + this._data.months = Math.abs(this._data.months); + this._data.years = Math.abs(this._data.years); + + return this; + }, + + weeks : function () { + return absRound(this.days() / 7); + }, + + valueOf : function () { + return this._milliseconds + + this._days * 864e5 + + (this._months % 12) * 2592e6 + + toInt(this._months / 12) * 31536e6; + }, + + humanize : function (withSuffix) { + var output = relativeTime(this, !withSuffix, this.localeData()); + + if (withSuffix) { + output = this.localeData().pastFuture(+this, output); + } + + return this.localeData().postformat(output); + }, + + add : function (input, val) { + // supports only 2.0-style add(1, 's') or add(moment) + var dur = moment.duration(input, val); + + this._milliseconds += dur._milliseconds; + this._days += dur._days; + this._months += dur._months; + + this._bubble(); + + return this; + }, + + subtract : function (input, val) { + var dur = moment.duration(input, val); + + this._milliseconds -= dur._milliseconds; + this._days -= dur._days; + this._months -= dur._months; + + this._bubble(); + + return this; + }, + + get : function (units) { + units = normalizeUnits(units); + return this[units.toLowerCase() + 's'](); + }, + + as : function (units) { + var days, months; + units = normalizeUnits(units); + + days = this._days + this._milliseconds / 864e5; + if (units === 'month' || units === 'year') { + months = this._months + daysToYears(days) * 12; + return units === 'month' ? months : months / 12; + } else { + days += yearsToDays(this._months / 12); + switch (units) { + case 'week': return days / 7; + case 'day': return days; + case 'hour': return days * 24; + case 'minute': return days * 24 * 60; + case 'second': return days * 24 * 60 * 60; + case 'millisecond': return days * 24 * 60 * 60 * 1000; + default: throw new Error('Unknown unit ' + units); + } + } + }, + + lang : moment.fn.lang, + locale : moment.fn.locale, + + toIsoString : deprecate( + "toIsoString() is deprecated. Please use toISOString() instead " + + "(notice the capitals)", + function () { + return this.toISOString(); + } + ), + + toISOString : function () { + // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js + var years = Math.abs(this.years()), + months = Math.abs(this.months()), + days = Math.abs(this.days()), + hours = Math.abs(this.hours()), + minutes = Math.abs(this.minutes()), + seconds = Math.abs(this.seconds() + this.milliseconds() / 1000); + + if (!this.asSeconds()) { + // this is the same as C#'s (Noda) and python (isodate)... + // but not other JS (goog.date) + return 'P0D'; + } + + return (this.asSeconds() < 0 ? '-' : '') + + 'P' + + (years ? years + 'Y' : '') + + (months ? months + 'M' : '') + + (days ? days + 'D' : '') + + ((hours || minutes || seconds) ? 'T' : '') + + (hours ? hours + 'H' : '') + + (minutes ? minutes + 'M' : '') + + (seconds ? seconds + 'S' : ''); + }, + + localeData : function () { + return this._locale; + } + }); + + function makeDurationGetter(name) { + moment.duration.fn[name] = function () { + return this._data[name]; + }; + } + + for (i in unitMillisecondFactors) { + if (unitMillisecondFactors.hasOwnProperty(i)) { + makeDurationGetter(i.toLowerCase()); + } + } + + moment.duration.fn.asMilliseconds = function () { + return this.as('ms'); + }; + moment.duration.fn.asSeconds = function () { + return this.as('s'); + }; + moment.duration.fn.asMinutes = function () { + return this.as('m'); + }; + moment.duration.fn.asHours = function () { + return this.as('h'); + }; + moment.duration.fn.asDays = function () { + return this.as('d'); + }; + moment.duration.fn.asWeeks = function () { + return this.as('weeks'); + }; + moment.duration.fn.asMonths = function () { + return this.as('M'); + }; + moment.duration.fn.asYears = function () { + return this.as('y'); + }; + + /************************************ + Default Locale + ************************************/ + + + // Set default locale, other locale will inherit from English. + moment.locale('en', { + ordinal : function (number) { + var b = number % 10, + output = (toInt(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } + }); + + /* EMBED_LOCALES */ + + /************************************ + Exposing Moment + ************************************/ + + function makeGlobal(shouldDeprecate) { + /*global ender:false */ + if (typeof ender !== 'undefined') { + return; + } + oldGlobalMoment = globalScope.moment; + if (shouldDeprecate) { + globalScope.moment = deprecate( + 'Accessing Moment through the global scope is ' + + 'deprecated, and will be removed in an upcoming ' + + 'release.', + moment); + } else { + globalScope.moment = moment; + } + } + + // CommonJS module is defined + if (hasModule) { + module.exports = moment; + } else if (typeof define === 'function' && define.amd) { + define('moment', function (require, exports, module) { + if (module.config && module.config() && module.config().noGlobal === true) { + // release the global variable + globalScope.moment = oldGlobalMoment; + } + + return moment; + }); + makeGlobal(true); + } else { + makeGlobal(); + } +}).call(this); diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index b76bee29a59..06b1e844792 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -8,6 +8,7 @@ font-weight: normal; font-style: normal; } + @font-face { font-family: "EntypoRegular"; src: url("/web/static/src/font/entypo-webfont.eot") format("eot"); @@ -18,6 +19,7 @@ font-weight: normal; font-style: normal; } + #oe_main_menu_navbar { min-height: 34px; z-index: 1001; @@ -134,7 +136,6 @@ vertical-align: top; } .openerp .oe_title { - width: 38%; float: left; } .openerp .oe_title:after { @@ -369,6 +370,16 @@ .openerp .oe_form_dirty button.oe_highlight_on_dirty:hover { background: #ed6f6a; } +.openerp .oe_warning_redirect { + border: none !important; + padding: 0 !important; + margin-left: 20px !important; + background: #f5f7f9 !important; + box-shadow: none !important; +} +.openerp .oe_warning_redirect:hover { + text-decoration: underline !important; +} .openerp .oe_stat_button { font-weight: normal; width: 132px !important; @@ -407,16 +418,6 @@ display: inline; vertical-align: middle; } -.openerp .oe_warning_redirect { - border: none !important; - padding: 0 !important; - margin-left: 20px !important; - background: #f5f7f9 !important; - box-shadow: none !important; -} -.openerp .oe_warning_redirect:hover { - text-decoration: underline !important; -} .openerp .oe_stat_button:hover { background: #7c7bad; color: white; @@ -583,9 +584,10 @@ height: 16px; } .openerp .oe_form_field_radio.oe_vertical label { - margin-left: 4px; + display: inline-block; + margin-left: 20px; } -.openerp .oe_form_field_radio.oe_form_required .oe_radio_input { +.openerp .oe_form_field_radio .oe_radio_input { border: 2px solid transparent; display: inline-block; height: 12px; @@ -593,6 +595,7 @@ vertical-align: top; border-radius: 10px; margin: 1px 0; + position: absolute; } .openerp .oe_form_field_radio.oe_form_required.oe_form_invalid .oe_radio_input { border-color: red; @@ -2147,9 +2150,6 @@ .openerp .oe_form .oe_form_field_boolean { width: auto; } -.openerp .oe_form .oe_datepicker_container { - display: none; -} .openerp .oe_form .oe_datepicker_root { display: inline-block; } @@ -3001,6 +3001,7 @@ top: 0px; } } + .kitten-mode-activated { background-size: cover; background-attachment: fixed; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index f1f948170e5..38e3ebf40ce 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -239,8 +239,7 @@ $sheet-padding: 16px td vertical-align: top .oe_title - width: 38% - float: left + float: left .oe_title:after content: "." display: block @@ -529,19 +528,19 @@ $sheet-padding: 16px height: 16px &.oe_vertical label - margin-left: 4px - &.oe_form_required - .oe_radio_input - border: 2px solid transparent display: inline-block - height: 12px - width: 12px - vertical-align: top - border-radius: 10px - margin: 1px 0 - &.oe_form_invalid - .oe_radio_input - border-color: red + margin-left: 20px + .oe_radio_input + border: 2px solid transparent + display: inline-block + height: 12px + width: 12px + vertical-align: top + border-radius: 10px + margin: 1px 0 + position: absolute + &.oe_form_required.oe_form_invalid .oe_radio_input + border-color: red .oe_tags &.oe_inline min-width: 250px @@ -1762,8 +1761,6 @@ $sheet-padding: 16px white-space: nowrap .oe_form_field_boolean width: auto - .oe_datepicker_container - display: none .oe_datepicker_root display: inline-block .oe_form_required diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index f5f8129d502..608f76cd6ca 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -115,6 +115,7 @@ instance.web.Dialog = instance.web.Widget.extend({ this.init_dialog(); } this.$buttons.insertAfter(this.$dialog_box.find(".modal-body")); + $('.tooltip').remove(); //remove open tooltip if any to prevent them staying when modal is opened //add to list of currently opened modal opened_modal.push(this.$dialog_box); return this; @@ -185,12 +186,12 @@ instance.web.Dialog = instance.web.Widget.extend({ close: function(reason) { if (this.dialog_inited && !this.__tmp_dialog_hiding) { $('.tooltip').remove(); //remove open tooltip if any to prevent them staying when modal has disappeared - this.trigger("closing", reason); if (this.$el.is(":data(bs.modal)")) { // may have been destroyed by closing signal this.__tmp_dialog_hiding = true; this.$dialog_box.modal('hide'); this.__tmp_dialog_hiding = undefined; } + this.trigger("closing", reason); } }, _closing: function() { @@ -230,6 +231,9 @@ instance.web.Dialog = instance.web.Widget.extend({ if (opened_modal.length > 0){ //we still have other opened modal so we should focus it opened_modal[opened_modal.length-1].focus(); + //keep class modal-open (deleted by bootstrap hide fnct) on body + //to allow scrolling inside the modal + $('body').addClass('modal-open'); } },0); } @@ -252,7 +256,7 @@ instance.web.CrashManager = instance.web.Class.extend({ return; } if (error.data.name === "openerp.http.SessionExpiredException" || error.data.name === "werkzeug.exceptions.Forbidden") { - this.show_warning({type: "Session Expired", data: { message: _t("Your OpenERP session expired. Please refresh the current web page.") }}); + this.show_warning({type: "Session Expired", data: { message: _t("Your Odoo session expired. Please refresh the current web page.") }}); return; } if (error.data.exception_type === "except_osv" || error.data.exception_type === "warning" || error.data.exception_type === "access_error") { @@ -270,7 +274,7 @@ instance.web.CrashManager = instance.web.Class.extend({ } new instance.web.Dialog(this, { size: 'medium', - title: "OpenERP " + (_.str.capitalize(error.type) || "Warning"), + title: "Odoo " + (_.str.capitalize(error.type) || "Warning"), buttons: [ {text: _t("Ok"), click: function() { this.parents('.modal').modal('hide'); }} ], @@ -285,7 +289,7 @@ instance.web.CrashManager = instance.web.Class.extend({ this.parents('.modal').modal('hide'); }; new instance.web.Dialog(this, { - title: "OpenERP " + _.str.capitalize(error.type), + title: "Odoo " + _.str.capitalize(error.type), buttons: buttons }, QWeb.render('CrashManager.error', {session: instance.session, error: error})).open(); }, @@ -337,7 +341,7 @@ instance.web.RedirectWarningHandler = instance.web.Dialog.extend(instance.web.Ex new instance.web.Dialog(this, { size: 'medium', - title: "OpenERP " + (_.str.capitalize(error.type) || "Warning"), + title: "Odoo " + (_.str.capitalize(error.type) || "Warning"), buttons: [ {text: _t("Ok"), click: function() { self.$el.parents('.modal').modal('hide'); self.destroy();}}, {text: error.data.arguments[2], @@ -910,7 +914,7 @@ instance.web.Menu = instance.web.Widget.extend({ } // add a tooltip to cropped menu items this.$secondary_menus.find('.oe_secondary_submenu li a span').each(function() { - $(this).tooltip(this.scrollWidth > this.clientWidth ? {title: $(this).text().trim(), placement: 'auto right'} :'destroy'); + $(this).tooltip(this.scrollWidth > this.clientWidth ? {title: $(this).text().trim(), placement: 'right'} :'destroy'); }); }, /** @@ -1156,12 +1160,19 @@ instance.web.Client = instance.web.Widget.extend({ }, 0); }); instance.web.bus.on('click', this, function(ev) { - $.fn.tooltip('destroy'); + $('.tooltip').remove(); if (!$(ev.target).is('input[type=file]')) { self.$el.find('.oe_dropdown_menu.oe_opened, .oe_dropdown_toggle.oe_opened').removeClass('oe_opened'); } }); }, + on_logo_click: function(ev){ + if (!this.has_uncommitted_changes()) { + return; + } else { + ev.preventDefault(); + } + }, show_common: function() { var self = this; this.crashmanager = new instance.web.CrashManager(); @@ -1190,7 +1201,7 @@ instance.web.WebClient = instance.web.Client.extend({ this._current_state = null; this.menu_dm = new instance.web.DropMisordered(); this.action_mutex = new $.Mutex(); - this.set('title_part', {"zopenerp": "OpenERP"}); + this.set('title_part', {"zopenerp": "Odoo"}); }, start: function() { var self = this; @@ -1266,6 +1277,9 @@ instance.web.WebClient = instance.web.Client.extend({ self.logo_edit(ev); }); + this.$('.oe_logo img').click(function(ev) { + self.on_logo_click(ev); + }); // Menu is rendered server-side thus we don't want the widget to create any dom self.menu = new instance.web.Menu(self); self.menu.setElement(this.$el.parents().find('.oe_application_menu_placeholder')); diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 23645e22bf1..169547d78c0 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -311,9 +311,8 @@ instance.web.Session.include( /** @lends instance.web.Session# */{ self.module_list = all_modules; var loaded = self.load_translations(); - var datejs_locale = "/web/static/lib/datejs/globalization/" + self.user_context.lang.replace("_", "-") + ".js"; - - var file_list = [ datejs_locale ]; + var locale = "/web/webclient/locale/" + self.user_context.lang || 'en_US'; + var file_list = [ locale ]; if(to_load.length) { loaded = $.when( loaded, @@ -772,7 +771,7 @@ instance.web.unblockUI = function() { /* Bootstrap defaults overwrite */ $.fn.tooltip.Constructor.DEFAULTS.placement = 'auto top'; $.fn.tooltip.Constructor.DEFAULTS.html = true; -$.fn.tooltip.Constructor.DEFAULTS.container = 'body'; +$.fn.tooltip.Constructor.DEFAULTS.trigger = 'hover focus click'; //overwrite bootstrap tooltip method to prevent showing 2 tooltip at the same time var bootstrap_show_function = $.fn.tooltip.Constructor.prototype.show; $.fn.tooltip.Constructor.prototype.show = function () { @@ -786,6 +785,18 @@ $.fn.tooltip.Constructor.prototype.show = function () { if (e.isDefaultPrevented() || !inDom) return; return bootstrap_show_function.call(this); }; +//overwrite bootstrap tooltip init method in order to check if tooltip is in a modal or not and +//if so it needs to have a container body in order to be visible +var bootstrap_init_tooltip_fnct = $.fn.tooltip.Constructor.prototype.init; +$.fn.tooltip.Constructor.prototype.init = function (type, element, options) { + options = options || {} + if ($('.modal[aria-hidden="false"]').length !== 0){ + if (options && !options.container){ + options = _.extend({container: 'body'},options); + } + } + return bootstrap_init_tooltip_fnct.call(this, type, element, options); +} /** * Registry for all the client actions key: tag value: widget diff --git a/addons/web/static/src/js/data_export.js b/addons/web/static/src/js/data_export.js index 2f7ff81d089..a6cb35423fb 100644 --- a/addons/web/static/src/js/data_export.js +++ b/addons/web/static/src/js/data_export.js @@ -27,6 +27,8 @@ instance.web.DataExport = instance.web.Dialog.extend({ this.$('#fields_list').empty(); }, 'click #export_new_list': 'on_show_save_list', + 'click #move_up':'on_click_move_up', + 'click #move_down':'on_click_move_down', }, init: function(parent, dataset) { var self = this; @@ -79,6 +81,20 @@ instance.web.DataExport = instance.web.Dialog.extend({ this.rpc('/web/export/formats', {}).done(this.do_setup_export_formats), this.show_exports_list()); }, + on_click_move_up: function () { + var prev_row = this.$el.find('#fields_list option:selected').first().prev(); + if(prev_row.length){ + var selected_rows = self.$('#fields_list option:selected').detach(); + prev_row.before(selected_rows); + } + }, + on_click_move_down: function () { + var next_row = this.$el.find('#fields_list option:selected').last().next(); + if(next_row.length){ + var selected_rows = self.$('#fields_list option:selected').detach(); + next_row.after(selected_rows); + } + }, do_setup_export_formats: function (formats) { var $fmts = this.$el.find('#export_format'); _(formats).each(function (format) { diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 3d7b574e56a..14026f17681 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -361,4 +361,52 @@ instance.web.round_decimals = function(value, decimals){ return instance.web.round_precision(value, Math.pow(10,-decimals)); }; +/** ++ * ++ * convert python.strftime format into moment.js format ++ * inspired from : https://github.com/uruz/moment-datetime/blob/master/moment-datetime.js ++*/ +instance.web.convert_to_moment_format = function(format){ + if (!format) + return false; + var replacements = { + 'a': 'ddd', + 'A': 'dddd', + 'b': 'MMM', + 'B': 'MMMM', + //'c': //%c is defined too vaguely + 'd': 'DD', + //'f': JS have no support for microseconds and moment.js have no support for milliseconds + 'H': 'HH', + 'I': 'hh', + 'j': 'DDDD', + 'm': 'MM', + 'M': 'mm', + 'p': 'A', + 'S': 'ss', + 'U': 'ww',//ww is for Sunday-based week + 'w': 'd', + //'W': 'ww',//%W is weeknumber for weeks starting from Monday and it is not implemented in moment.js + //'x': + //'X': //%x and %X are defined too vaguely to be implemented + 'y': 'YY', + 'Y': 'YYYY', + 'z': 'ZZ', + //'Z': 'z', - moment.js does not support timezone names + '%': '%' + } + var moment_format = '', directive_index = 0, replacement, unformatted; + while (format.indexOf('%') !== -1){ + directive_index = format.indexOf('%') + 1; + replacement = replacements[format[directive_index]]; + unformatted = format.substr(0, directive_index-1); + if (unformatted.length){ + unformatted = '[' + unformatted.replace(/(\[|\])/g, '\\$&') +']'; + } + moment_format += unformatted + (replacement ? replacement : format[directive_index]); + format = format.substr(directive_index+1); + } + return moment_format; +}; + })(); diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 1bfdc86fb5a..566179c2a38 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -782,6 +782,7 @@ instance.web.SearchViewDrawer = instance.web.Widget.extend({ start: function() { var self = this; + if (this.searchview.headless) return $.when(this._super(), this.searchview.ready); var filters_ready = this.searchview.fields_view_get .then(this.proxy('prepare_filters')); return $.when(this._super(), filters_ready).then(function () { diff --git a/addons/web/static/src/js/tour.js b/addons/web/static/src/js/tour.js index fec189e06f5..0179d3eda65 100644 --- a/addons/web/static/src/js/tour.js +++ b/addons/web/static/src/js/tour.js @@ -329,18 +329,22 @@ var Tour = { } console.log(message); }, - error: function (step, message) { + logError: function (step, message, all) { var state = Tour.getState(); - message += '\n tour: ' + state.id - + (step ? '\n step: ' + step.id + ": '" + (step._title || step.title) + "'" : '' ) - + '\n href: ' + window.location.href - + '\n referrer: ' + document.referrer - + (step ? '\n element: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) : '' ) - + (step ? '\n waitNot: ' + Boolean(!step.waitNot || !$(step.waitNot).size()) : '' ) - + (step ? '\n waitFor: ' + Boolean(!step.waitFor || $(step.waitFor).size()) : '' ) - + "\n localStorage: " + JSON.stringify(localStorage) - + '\n\n' + $("body").html(); + message += '\ntour: ' + state.id + + (step ? '\nstep: ' + step.id + ": '" + (step._title || step.title) + "'" : '' ) + + (all ? '\nhref: ' + window.location.href : '' ) + + (all ? '\nreferrer: ' + document.referrer : '' ) + + (step ? '\nelement: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) : '' ) + + (step ? '\nwaitNot: ' + Boolean(!step.waitNot || !$(step.waitNot).size()) : '' ) + + (step ? '\nwaitFor: ' + Boolean(!step.waitFor || $(step.waitFor).size()) : '' ) + + (all ? "\nlocalStorage: " + JSON.stringify(localStorage) : '' ) + + (all ? '\n\n' + $("body").html() : '' ); Tour.log(message, true); + }, + error: function (step, message) { + var state = Tour.getState(); + Tour.logError(step, "Error: " + message, true); Tour.endTour(); }, lists: function () { @@ -403,7 +407,7 @@ var Tour = { var state = Tour.getState(); var time = new Date().getTime(); var timer; - var next = state.tour.steps[state.step.id+1]; + var next = state.step.next ? Tour.search_step(state.step.next) : state.tour.steps[state.step.id+1]; var overlaps = state.mode === "test" ? Tour.errorDelay : 0; window.onbeforeunload = function () { @@ -418,20 +422,65 @@ var Tour = { clearTimeout(Tour.timer); if (Tour.check(next)) { + clearTimeout(Tour.currentTimer); // use an other timeout for cke dom loading Tour.saveState(state.id, state.mode, state.step.id, 0); setTimeout(function () { + if (state.step.onend && Tour._goto(state.step.onend())) return; Tour.nextStep(next); }, Tour.defaultDelay); + return; + } else if (!overlaps || new Date().getTime() - time < overlaps) { + Tour.timer = setTimeout(checkNext, Tour.defaultDelay); - } else { - return Tour.error(next, "Can't reach the next step"); + return; + + } else if(next.onerror) { + + Tour.logError(next, "Error: Can't reach the next step (call next step onerror)", false); + var id = next.onerror(); + if (id) { + if (Tour._goto(id)) return; + if (id === true) { + Tour.nextStep(next); + return; + } + } + } + + Tour.error(next, "Can't reach the next step"); + return; + } setTimeout(checkNext, 0); }, + search_step: function (id_or_title) { + var state = Tour.getState(); + if (id_or_title !== undefined) { + if (isNaN(id_or_title)) { + for (var k=0; k<state.tour.steps.length; k++) { + if (state.tour.steps[k].title === id_or_title || state.tour.steps[k]._title === id_or_title) { + return state.tour.steps[k]; + } + } + } else { + return state.tour.steps[id_or_title]; + } + } + return undefined; + }, + _goto: function (id_or_title) { + var state = Tour.getState(); + if (!state) return true; + if (id_or_title === undefined) return false; + var step = Tour.search_step(id_or_title); + Tour.saveState(state.id, state.mode, step.id, 0); + Tour.nextStep(Tour.getState().step); + return true; + }, nextStep: function (step) { var state = Tour.getState(); @@ -440,7 +489,7 @@ var Tour = { } step = step || state.step; - var next = state.tour.steps[step.id+1]; + var next = state.step.next ? Tour.search_step(state.step.next) : state.tour.steps[step.id+1]; if (state.mode === "test" && state.number > 3) { return Tour.error(next, "Cycling. Can't reach the next step"); @@ -448,14 +497,15 @@ var Tour = { Tour.saveState(state.id, state.mode, step.id, state.number); - if (step.id !== state.step_id) { + if (state.number === 1) { Tour.log("Tour '"+state.id+"' Step: '" + (step._title || step.title) + "' (" + (new Date().getTime() - this.time) + "ms)"); } Tour.autoTogglePopover(true); - if (step.onload) { - step.onload(); + // onload a step you can fallback to an other step + if (step.onload && Tour._goto(step.onload())) { + return; } if (state.mode === "test") { diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 5767ffe5489..93ebc8b8167 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -302,6 +302,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM opacity: '1', filter: 'alpha(opacity = 100)' }); + instance.web.bus.trigger('form_view_shown', self); }); }, do_hide: function () { @@ -705,6 +706,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM if (menu) { menu.do_reload_needaction(); } + instance.web.bus.trigger('form_view_saved', self); }); }).always(function(){ $(e.target).attr("disabled", false); @@ -1835,7 +1837,6 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi trigger = trigger || this.$el; options = _.extend({ delay: { show: 500, hide: 0 }, - trigger: 'hover', title: function() { var template = widget.template + '.tooltip'; if (!QWeb.has_template(template)) { @@ -2577,10 +2578,10 @@ instance.web.form.FieldCharDomain = instance.web.form.AbstractField.extend(insta instance.web.DateTimeWidget = instance.web.Widget.extend({ template: "web.datepicker", - jqueryui_object: 'datetimepicker', type_of_date: "datetime", events: { - 'change .oe_datepicker_master': 'change_datetime', + 'dp.change .oe_datepicker_main': 'change_datetime', + 'dp.show .oe_datepicker_main': 'set_datetime_default', 'keypress .oe_datepicker_master': 'change_datetime', }, init: function(parent) { @@ -2589,82 +2590,32 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ }, start: function() { var self = this; + var l10n = _t.database.parameters; + var options = { + pickTime: true, + useSeconds: true, + startDate: new moment({ y: 1900 }), + endDate: new moment().add(200, "y"), + calendarWeeks: true, + icons : { + time: 'fa fa-clock-o', + date: 'fa fa-calendar', + up: 'fa fa-chevron-up', + down: 'fa fa-chevron-down' + }, + language : moment.locale(), + format : instance.web.convert_to_moment_format(l10n.date_format +' '+ l10n.time_format), + }; this.$input = this.$el.find('input.oe_datepicker_master'); - this.$input_picker = this.$el.find('input.oe_datepicker_container'); - - $.datepicker.setDefaults({ - clearText: _t('Clear'), - clearStatus: _t('Erase the current date'), - closeText: _t('Done'), - closeStatus: _t('Close without change'), - prevText: _t('<Prev'), - prevStatus: _t('Show the previous month'), - nextText: _t('Next>'), - nextStatus: _t('Show the next month'), - currentText: _t('Today'), - currentStatus: _t('Show the current month'), - monthNames: Date.CultureInfo.monthNames, - monthNamesShort: Date.CultureInfo.abbreviatedMonthNames, - monthStatus: _t('Show a different month'), - yearStatus: _t('Show a different year'), - weekHeader: _t('Wk'), - weekStatus: _t('Week of the year'), - dayNames: Date.CultureInfo.dayNames, - dayNamesShort: Date.CultureInfo.abbreviatedDayNames, - dayNamesMin: Date.CultureInfo.shortestDayNames, - dayStatus: _t('Set DD as first week day'), - dateStatus: _t('Select D, M d'), - firstDay: Date.CultureInfo.firstDayOfWeek, - initStatus: _t('Select a date'), - isRTL: false - }); - $.timepicker.setDefaults({ - timeOnlyTitle: _t('Choose Time'), - timeText: _t('Time'), - hourText: _t('Hour'), - minuteText: _t('Minute'), - secondText: _t('Second'), - currentText: _t('Now'), - closeText: _t('Done') - }); - - this.picker({ - onClose: this.on_picker_select, - onSelect: this.on_picker_select, - changeMonth: true, - changeYear: true, - showWeek: true, - showButtonPanel: true, - firstDay: Date.CultureInfo.firstDayOfWeek - }); - // Some clicks in the datepicker dialog are not stopped by the - // datepicker and "bubble through", unexpectedly triggering the bus's - // click event. Prevent that. - this.picker('widget').click(function (e) { e.stopPropagation(); }); - - this.$el.find('img.oe_datepicker_trigger').click(function() { - if (self.get("effective_readonly") || self.picker('widget').is(':visible')) { - self.$input.focus(); - return; - } - self.picker('setDate', self.get('value') ? instance.web.auto_str_to_date(self.get('value')) : new Date()); - self.$input_picker.show(); - self.picker('show'); - self.$input_picker.hide(); - }); + if (this.type_of_date === 'date') { + options['pickTime'] = false; + options['useSeconds'] = false; + options['format'] = instance.web.convert_to_moment_format(l10n.date_format); + } + this.picker = this.$('.oe_datepicker_main').datetimepicker(options); this.set_readonly(false); this.set({'value': false}); }, - picker: function() { - return $.fn[this.jqueryui_object].apply(this.$input_picker, arguments); - }, - on_picker_select: function(text, instance_) { - var date = this.picker('getDate'); - this.$input - .val(date ? this.format_client(date) : '') - .change() - .focus(); - }, set_value: function(value_) { this.set({'value': value_}); this.$input.val(value_ ? this.format_client(value_) : ''); @@ -2674,12 +2625,11 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ }, set_value_from_ui_: function() { var value_ = this.$input.val() || false; - this.set({'value': this.parse_client(value_)}); + this.set_value(this.parse_client(value_)); }, set_readonly: function(readonly) { this.readonly = readonly; this.$input.prop('readonly', this.readonly); - this.$el.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', readonly); }, is_valid_: function() { var value_ = this.$input.val(); @@ -2700,6 +2650,17 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ format_client: function(v) { return instance.web.format_value(v, {"widget": this.type_of_date}); }, + set_datetime_default: function(){ + //when opening datetimepicker the date and time by default should be the one from + //the input field if any or the current day otherwise + if (this.type_of_date === 'datetime') { + value = new moment().second(0); + if (this.$input.val().length !== 0 && this.is_valid_()){ + var value = this.$input.val(); + } + this.$('.oe_datepicker_main').data('DateTimePicker').setValue(value); + } + }, change_datetime: function(e) { if ((e.type !== "keypress" || e.which === 13) && this.is_valid_()) { this.set_value_from_ui_(); @@ -2712,7 +2673,6 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ }); instance.web.DateWidget = instance.web.DateTimeWidget.extend({ - jqueryui_object: 'datepicker', type_of_date: "date" }); @@ -3161,9 +3121,9 @@ instance.web.form.FieldRadio = instance.web.form.AbstractField.extend(instance.w this._super(field_manager, node); this.selection = _.clone(this.field.selection) || []; this.domain = false; + this.uniqueId = _.uniqueId("radio"); }, initialize_content: function () { - this.uniqueId = _.uniqueId("radio"); this.on("change:effective_readonly", this, this.render_value); this.field_manager.on("view_content_has_changed", this, this.get_selection); this.get_selection(); diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 9a192e4db90..fca5dd4f969 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -1623,6 +1623,7 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we self.setup_resequence_rows(list, dataset); }).always(function() { if (post_render) { post_render(); } + self.view.trigger('view_list_rendered'); }); }); return $el; diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 8a6c8def9ca..93ca3fe7b4d 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -344,6 +344,8 @@ instance.web.ActionManager = instance.web.Widget.extend({ }); } + instance.web.bus.trigger('action', action); + // Ensure context & domain are evaluated and can be manipulated/used var ncontext = new instance.web.CompoundContext(options.additional_context, action.context || {}); action.context = instance.web.pyeval.eval('context', ncontext); @@ -691,8 +693,8 @@ instance.web.ViewManager = instance.web.Widget.extend({ var container = this.$el.find("> div > div > .oe_view_manager_body > .oe_view_manager_view_" + view_type); var view_promise = controller.appendTo(container); this.views[view_type].controller = controller; - this.views[view_type].deferred.resolve(view_type); return $.when(view_promise).done(function() { + self.views[view_type].deferred.resolve(view_type); if (self.searchview && self.flags.auto_search && view.controller.searchable !== false) { @@ -725,6 +727,7 @@ instance.web.ViewManager = instance.web.Widget.extend({ } views.push(mode); } + instance.web.bus.trigger('view_switch_mode', self, mode); }); var item = _.extend({ widget: this, @@ -1122,7 +1125,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({ ); } - $.when(defs).done(function() { + $.when(this.views[this.active_view] ? this.views[this.active_view].deferred : $.when(), defs).done(function() { self.views[self.active_view].controller.do_load_state(state, warm); }); }, @@ -1481,6 +1484,7 @@ instance.web.View = instance.web.Widget.extend({ }, do_show: function () { this.$el.show(); + instance.web.bus.trigger('view_shown', this); }, do_hide: function () { this.$el.hide(); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 2cce789480c..f37c282b01c 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -40,7 +40,7 @@ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h3 class="modal-title"><t t-raw="title"/></h3> </div> - <div class="modal-body" style="overflow-y: auto;"> + <div class="modal-body"> </div> </div> </div> @@ -85,7 +85,7 @@ </div> </div> <p class="oe_grey" style="margin: 10px"> - Fill in this form to create an OpenERP database. You can + Fill in this form to create an Odoo database. You can create databases for different companies or for different goals (testing, production). Once the database is created, you will be able to install your first application. @@ -112,7 +112,7 @@ <td class="oe_form_group_cell"> <span class="oe_form_field oe_form_field_boolean oe_grey" > <input type="checkbox" name="demo_data" /> - Check this box to evaluate OpenERP. + Check this box to evaluate Odoo. </span> </td> </tr> @@ -372,7 +372,7 @@ <div class="oe_bottom"> <p>Copyright © 2004-TODAY OpenERP SA. All Rights Reserved.<br /> - OpenERP is a trademark of the <a target="_blank" href="https://www.odoo.com" style="text-decoration: underline;">OpenERP SA Company</a>.</p> + Odoo is a trademark of the <a target="_blank" href="https://www.odoo.com" style="text-decoration: underline;">OpenERP SA Company</a>.</p> <p>Licenced under the terms of <a target="_blank" href="http://www.gnu.org/licenses/agpl.html" style="text-decoration: underline;">GNU Affero General Public License</a></p> <p>For more information visit <a target="_blank" href="https://www.odoo.com" style="text-decoration: underline;">Odoo.com</a></p> </div> @@ -1053,14 +1053,15 @@ <t t-name="web.datepicker"> <span> <t t-set="placeholder" t-value="widget.getParent().node and widget.getParent().node.attrs.placeholder"/> - <input type="text" class="oe_datepicker_container" disabled="disabled" style="display: none;"/> - <input type="text" - t-att-name="widget.name" - t-att-placeholder="placeholder" - class="oe_datepicker_master" - /><img class="oe_input_icon oe_datepicker_trigger" draggable="false" - t-att-src='_s + "/web/static/src/img/ui/field_calendar.png"' - title="Select date" width="16" height="16" border="0"/> + <div class="oe_datepicker_main input-group"> + <input type="text" + t-att-name="widget.name" + t-att-placeholder="placeholder" + class="oe_datepicker_master" + /><span><img class="oe_input_icon oe_datepicker_trigger datepickerbutton" draggable="false" + t-att-src='_s + "/web/static/src/img/ui/field_calendar.png"' + title="Select date" width="16" height="16" border="0"/></span> + </div> </span> </t> <t t-name="FieldDate"> @@ -1768,6 +1769,8 @@ <button class="oe_button" id="add_field">Add</button> <button class="oe_button" id="remove_field">Remove</button> <button class="oe_button" id="remove_all_field">Remove All</button> + <button class="oe_button" id="move_up">Move Up</button> + <button class="oe_button" id="move_down">Move Down</button> </td> <td class="oe_export_fields_selector_right"> <select name="fields_list" id="fields_list" diff --git a/addons/web/static/test/fulltest.html b/addons/web/static/test/fulltest.html index 47972dece90..e08d57d4210 100644 --- a/addons/web/static/test/fulltest.html +++ b/addons/web/static/test/fulltest.html @@ -2,7 +2,7 @@ <html style="height: 100%"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - <title>OpenERP Web Full Stack</title> + <title>Odoo Web Full Stack</title> <link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/> <link rel="stylesheet" href="/web/static/lib/qunit/qunit.css"> diff --git a/addons/web/static/test/menu.js b/addons/web/static/test/menu.js new file mode 100644 index 00000000000..3f0bd8f1891 --- /dev/null +++ b/addons/web/static/test/menu.js @@ -0,0 +1,295 @@ +(function () { + 'use strict'; + + + function openmenu () { + setTimeout(function () { + $(".collapse:not(.in)").addClass("in"); + $(".dropdown:not(.open)").addClass("open"); + },3000); + } + + openerp.Tour.register({ + id: 'test_menu', + name: "Test all menu items", + path: '/web', + mode: 'test', + steps: [ + { + title: "begin test", + onload: function () { + localStorage.setItem('active_step', 0); + localStorage.setItem('menu_tested', "[]"); + }, + }, + + // log as admin + + { + title: "log on as admin", + element: ".oe_login_form button", + onload: function () { + $('input[name="login"], input[name="password"]').val("admin"); + }, + }, + { + title: "load web admin", + waitFor: ".oe_view_manager_body", + onload: function () { + localStorage.setItem('active_step', (+localStorage.getItem('active_step'))+1 ); + openmenu(); + }, + }, + { + title: "click on Settings", + element: '.oe_application_menu_placeholder a[data-menu]:contains(Settings)', + waitNot: '.oe_loading:visible, button.oe_form_button:contains(Apply).already_tested', + }, + + // add technical features to admin user + + { + title: "click on User form Admin", + element: '.oe_secondary_menu a:visible:contains(Users)', + waitNot: ".oe_loading:visible", + }, + { + title: "click on Admin", + element: '.oe_list_field_cell:contains(Admin)', + }, + { + waitFor: '.oe_breadcrumb_item:contains(Admin)', + waitNot: ".oe_loading:visible", + }, + { + title: "click on Edit button", + element: 'button.oe_form_button_edit', + }, + { + title: "click on Technical Features", + element: 'td:contains(Technical Features) + td input:not(:disabled):visible', + onend: function () { + $('td:contains(Technical Features) + td input:not(:disabled):visible').attr("checked", true); + }, + }, + { + title: "click on Save User", + waitFor: 'td:contains(Technical Features) + td input:checked:not(:disabled):visible', + element: 'button.oe_form_button_save', + }, + + // add technical features to demo user + + { + title: "click on User", + element: '.oe_secondary_menu a:visible:contains(Users)', + waitFor: 'td:contains(Technical Features) + td input:disabled:visible', + }, + { + title: "click on Demo", + element: '.oe_list_field_cell:contains(Demo)', + }, + { + waitFor: '.oe_breadcrumb_item:contains(Demo)', + waitNot: ".oe_loading:visible", + }, + { + title: "click on Edit button", + element: 'button.oe_form_button_edit', + }, + { + title: "click on Technical Features", + element: 'td:contains(Technical Features) + td input:not(:disabled):visible', + onend: function () { + $('td:contains(Technical Features) + td input:not(:disabled):visible').attr("checked", true); + if (localStorage.getItem('active_step') === "2") { + $('input').attr("checked", true); + $('.oe_view_manager_body td:contains(Portal) + td input:visible').attr("checked", null); + $('.oe_view_manager_body td:contains(Public) + td input:visible').attr("checked", null); + $('select').each(function () { + $('option:last', this).attr('selected', true); + }); + } + }, + }, + { + title: "click on Save User", + waitFor: 'td:contains(Technical Features) + td input:checked:not(:disabled):visible', + element: 'button.oe_form_button_save', + onload: function () { + openmenu(); + }, + }, + + // log out + + { + title: "log out amdin", + waitFor: 'td:contains(Technical Features) + td input:disabled:visible', + element: 'a[data-menu="logout"]', + }, + + // log as demo + + { + title: "log on as demo user", + element: ".oe_login_form button", + onload: function () { + $('input[name="login"], input[name="password"]').val("demo"); + }, + }, + { + title: "load web demo", + waitFor: ".oe_view_manager_body", + onload: function () { + openmenu(); + }, + next: "check", + }, + + // click all menu items + + { + title: "Click on top menu", + element: '.oe_application_menu_placeholder a[data-menu]:not([data-action-model="ir.actions.act_url"]):not(.already_tested):first', + onload: function () { + var $menu = $(this.element); + console.log("Tour 'test_menu' click on: '"+$menu.text().replace(/^\s+|\s+$/g, '')+"'"); + }, + onend: function () { + $(this.element).addClass('already_tested'); + $('.oe_secondary_submenu').show(); + }, + next: "check" + }, + { + title: "Click on sub menu", + element: '.oe_secondary_menu a:not(.oe_menu_toggler):visible:not(.already_tested):first', + onload: function () { + var $menu = $(this.element); + console.log("Tour 'test_menu' click on: '"+$menu.find('span:first').text().replace(/^\s+|\s+$/g, '')+"'"); + }, + onend: function () { + $(this.element).addClass('already_tested'); + }, + next: "check" + }, + { + title: "Click on need action", + element: '.oe_secondary_menu a:not(.oe_menu_toggler) div.badge:visible:not(.already_tested):first', + onload: function () { + var $menu = $(this.element); + console.log("Tour 'test_menu' click on need action: '"+$menu.parent().find('span:first').text().replace(/^\s+|\s+$/g, '')+"'"); + }, + onend: function () { + $(this.element).addClass('already_tested'); + }, + next: "check" + }, + { + title: "Click on switch view", + element: '.oe_view_manager_switch li a:not(.already_tested):first', + onload: function () { + var $menu = $(this.element); + console.log("Tour 'test_menu' click on switch view: '"+$menu.data('original-title')+"'"); + }, + onend: function () { + $(this.element).addClass('already_tested'); + }, + next: "check" + }, + + { + title: "check", + waitNot: "body:has("+ + ".oe_view_manager_body > *:visible:not(:empty).already_loaded:not(.oe_searchview_drawer_container), "+ + ".oe_form_sheetbg.already_loaded"+ + "):not(:has(.modal))", + wait: 100, + onerror: function () { + return "Select next action"; + } + }, + { + title: "add class already tested", + waitNot: "body.oe_wait", + onload: function () { + + var tested = JSON.parse(localStorage.getItem('menu_tested') || "[]"); + + $('.oe_application_menu_placeholder li.active [data-menu]').addClass('already_tested'); + + var $menu = $('.oe_secondary_menus_container li.active [data-action-model]'); + var model = $menu.data('action-model'); + var id = $menu.data('action-id'); + var key = '.oe_secondary_menus_container li [data-action-model="'+model+'"][data-action-id="'+id+'"]'; + if (tested.indexOf(key) === -1) { + tested.push(key); + } + + var type = $('.oe_view_manager_switch li.active [data-view-type]').data('view-type'); + var key = 'body:has(.oe_secondary_menus_container li.active [data-action-model="' + model + '"][data-action-id="' + id + '"]) '+ + '.oe_view_manager_switch li [data-view-type="'+type+'"]'; + if (tested.indexOf(key) === -1) { + tested.push(key); + } + localStorage.setItem('menu_tested', JSON.stringify(tested)); + + + $(tested.join(",")).addClass('already_tested'); + $(".oe_view_manager_body > *:visible:not(:empty), .oe_form_sheet").addClass("already_loaded"); + $('.oe_view_manager_switch li.active a').addClass('already_tested'); + }, + wait: 250, // delay to remove wrong-positive + onerror: function () { + return "Select next action"; + } + }, + { + title: "Select next action", + onload: function () { + if ($(".oe_error_detail").size()) { + console.log("Tour 'test_menu' has detected an error."); + } + if ($(".oe_dialog_warning").size()) { + console.log("Tour 'test_menu' has detected a warning."); + } + + $('.modal').modal('hide').remove(); + + var steps = ["Click on switch view", "Click on sub menu", "Click on need action", "Click on top menu"]; + for (var k in steps) { + var step = openerp.Tour.search_step(steps[k]); + if($(step.element).size()) { + return step.id; + } + } + + openmenu(); + }, + }, + + // log out and re try + + { + title: "log out", + element: 'a[data-menu="logout"]', + onend: function () { + if (localStorage.getItem('active_step') == "1") { + return "log on as admin"; + } + }, + }, + + { + title: "finish", + waitFor: "form.oe_login_form", + onload: function () { + localStorage.removeItem('active_step'); + localStorage.removeItem('menu_tested'); + }, + } + ] + }); + +}()); diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index 984937698ce..48fc2a2770b 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -23,6 +23,7 @@ <script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script> <script type="text/javascript" src="/web/static/src/js/openerpframework.js"></script> <script type="text/javascript" src="/web/static/src/js/tour.js"></script> + <script type="text/javascript" src="/web/static/test/menu.js"></script> <link rel="stylesheet" href="/web/static/lib/fontawesome/css/font-awesome.css"/> </template> @@ -64,6 +65,11 @@ <link rel="stylesheet" href="/web/static/lib/bootstrap/css/bootstrap.css"/> <script type="text/javascript" src="/web/static/lib/bootstrap/js/bootstrap.js"></script> + <!-- Datetime Picker --> + <link rel="stylesheet" href="/web/static/lib/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css"/> + <script type="text/javascript" src="/web/static/lib/moment/moment.js"></script> + <script type="text/javascript" src="/web/static/lib/bootstrap-datetimepicker/src/js/bootstrap-datetimepicker.js"></script> + <!-- jQuery ui --> <link rel="stylesheet" href="/web/static/lib/jquery.ui.bootstrap/css/custom-theme/jquery-ui-1.9.0.custom.css"/> @@ -71,9 +77,6 @@ <script type="text/javascript" src="/web/static/lib/jquery.ui/js/jquery-ui-1.9.1.custom.js"></script> </t> - <link rel="stylesheet" href="/web/static/lib/jquery.ui.timepicker/css/jquery-ui-timepicker-addon.css"/> - <script type="text/javascript" src="/web/static/lib/jquery.ui.timepicker/js/jquery-ui-timepicker-addon.js"></script> - <link rel="stylesheet" href="/web/static/lib/jquery.ui.notify/css/ui.notify.css"/> <script type="text/javascript" src="/web/static/lib/jquery.ui.notify/js/jquery.notify.js"></script> @@ -123,7 +126,7 @@ <head> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - <title>OpenERP</title> + <title>Odoo</title> <link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/> <link rel="stylesheet" href="/web/static/src/css/full.css" /> <t t-raw="head or ''"/> @@ -260,7 +263,7 @@ <a class="oe_login_manage_db" t-attf-href="/web/database/manager{{ '?debug' if debug else '' }}">Manage Databases</a> <span class="oe_footer_seperator"> | </span> </t> - <a href="http://www.openerp.com" target="_blank">Powered by <span>OpenERP</span></a> + <a href="https://www.odoo.com" target="_blank">Powered by <span>Odoo</span></a> </div> </div> </t> @@ -323,7 +326,7 @@ <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> - <title>OpenERP Web Tests</title> + <title>Odoo Web Tests</title> <link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/> <link rel="stylesheet" href="/web/static/lib/qunit/qunit.css"/> |
