tolaria 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -1
  3. data/app/assets/fonts/admin/fontawesome.eot +0 -0
  4. data/app/assets/fonts/admin/fontawesome.svg +39 -24
  5. data/app/assets/fonts/admin/fontawesome.ttf +0 -0
  6. data/app/assets/fonts/admin/fontawesome.woff +0 -0
  7. data/app/assets/fonts/admin/fontawesome.woff2 +0 -0
  8. data/app/assets/javascripts/admin/base.js +1 -0
  9. data/app/assets/javascripts/admin/lib/autosize.js +262 -0
  10. data/app/assets/javascripts/admin/lib/backbone.js +242 -216
  11. data/app/assets/javascripts/admin/lib/jquery.chosen.js +1 -1
  12. data/app/assets/javascripts/admin/lib/jquery.js +1 -1
  13. data/app/assets/javascripts/admin/lib/jquery.selection.js +1 -1
  14. data/app/assets/javascripts/admin/lib/moment.js +301 -189
  15. data/app/assets/javascripts/admin/views/fields/attachment_field.js +1 -0
  16. data/app/assets/javascripts/admin/views/fields/textarea.js +9 -0
  17. data/app/assets/stylesheets/admin/components/_buttons.scss +7 -1
  18. data/app/assets/stylesheets/admin/components/_navigation.scss +7 -12
  19. data/app/assets/stylesheets/admin/settings/_icons.scss +81 -1
  20. data/app/controllers/tolaria/resource_controller.rb +3 -3
  21. data/app/helpers/admin/table_helper.rb +5 -5
  22. data/app/views/admin/administrators/_show.html.erb +2 -2
  23. data/app/views/admin/shared/forms/_markdown_composer.html.erb +3 -1
  24. data/app/views/admin/tolaria_resource/_form_buttons.html.erb +12 -3
  25. data/app/views/admin/tolaria_resource/_search_form.html.erb +1 -1
  26. data/app/views/admin/tolaria_resource/edit.html.erb +7 -1
  27. data/app/views/admin/tolaria_resource/index.html.erb +11 -4
  28. data/app/views/admin/tolaria_resource/show.html.erb +13 -4
  29. data/lib/tasks/admin.rake +16 -7
  30. data/lib/tolaria/default_config.rb +1 -0
  31. data/lib/tolaria/form_buildable.rb +3 -2
  32. data/lib/tolaria/version.rb +1 -1
  33. data/test/integration/{interface_test.rb → crud_test.rb} +19 -3
  34. data/test/integration/filter_preservation_test.rb +61 -0
  35. data/tolaria.gemspec +1 -0
  36. metadata +9 -6
@@ -1,7 +1,7 @@
1
- // Moment.js 2.10.2
1
+ // Moment.js 2.10.6
2
2
  // https://github.com/moment/moment/
3
3
  //
4
- // Copyright (c) 2011-2015 Tim Wood, Iskren Chernev, Moment.js contributors
4
+ // Copyright (c) Tim Wood, Iskren Chernev, Moment.js contributors
5
5
  //
6
6
  // Permission is hereby granted, free of charge, to any person
7
7
  // obtaining a copy of this software and associated documentation
@@ -42,28 +42,12 @@
42
42
  hookCallback = callback;
43
43
  }
44
44
 
45
- function defaultParsingFlags() {
46
- // We need to deep clone this object.
47
- return {
48
- empty : false,
49
- unusedTokens : [],
50
- unusedInput : [],
51
- overflow : -2,
52
- charsLeftOver : 0,
53
- nullInput : false,
54
- invalidMonth : null,
55
- invalidFormat : false,
56
- userInvalidated : false,
57
- iso : false
58
- };
59
- }
60
-
61
45
  function isArray(input) {
62
46
  return Object.prototype.toString.call(input) === '[object Array]';
63
47
  }
64
48
 
65
49
  function isDate(input) {
66
- return Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date;
50
+ return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
67
51
  }
68
52
 
69
53
  function map(arr, fn) {
@@ -100,21 +84,46 @@
100
84
  return createLocalOrUTC(input, format, locale, strict, true).utc();
101
85
  }
102
86
 
87
+ function defaultParsingFlags() {
88
+ // We need to deep clone this object.
89
+ return {
90
+ empty : false,
91
+ unusedTokens : [],
92
+ unusedInput : [],
93
+ overflow : -2,
94
+ charsLeftOver : 0,
95
+ nullInput : false,
96
+ invalidMonth : null,
97
+ invalidFormat : false,
98
+ userInvalidated : false,
99
+ iso : false
100
+ };
101
+ }
102
+
103
+ function getParsingFlags(m) {
104
+ if (m._pf == null) {
105
+ m._pf = defaultParsingFlags();
106
+ }
107
+ return m._pf;
108
+ }
109
+
103
110
  function valid__isValid(m) {
104
111
  if (m._isValid == null) {
112
+ var flags = getParsingFlags(m);
105
113
  m._isValid = !isNaN(m._d.getTime()) &&
106
- m._pf.overflow < 0 &&
107
- !m._pf.empty &&
108
- !m._pf.invalidMonth &&
109
- !m._pf.nullInput &&
110
- !m._pf.invalidFormat &&
111
- !m._pf.userInvalidated;
114
+ flags.overflow < 0 &&
115
+ !flags.empty &&
116
+ !flags.invalidMonth &&
117
+ !flags.invalidWeekday &&
118
+ !flags.nullInput &&
119
+ !flags.invalidFormat &&
120
+ !flags.userInvalidated;
112
121
 
113
122
  if (m._strict) {
114
123
  m._isValid = m._isValid &&
115
- m._pf.charsLeftOver === 0 &&
116
- m._pf.unusedTokens.length === 0 &&
117
- m._pf.bigHour === undefined;
124
+ flags.charsLeftOver === 0 &&
125
+ flags.unusedTokens.length === 0 &&
126
+ flags.bigHour === undefined;
118
127
  }
119
128
  }
120
129
  return m._isValid;
@@ -123,10 +132,10 @@
123
132
  function valid__createInvalid (flags) {
124
133
  var m = create_utc__createUTC(NaN);
125
134
  if (flags != null) {
126
- extend(m._pf, flags);
135
+ extend(getParsingFlags(m), flags);
127
136
  }
128
137
  else {
129
- m._pf.userInvalidated = true;
138
+ getParsingFlags(m).userInvalidated = true;
130
139
  }
131
140
 
132
141
  return m;
@@ -162,7 +171,7 @@
162
171
  to._offset = from._offset;
163
172
  }
164
173
  if (typeof from._pf !== 'undefined') {
165
- to._pf = from._pf;
174
+ to._pf = getParsingFlags(from);
166
175
  }
167
176
  if (typeof from._locale !== 'undefined') {
168
177
  to._locale = from._locale;
@@ -186,7 +195,7 @@
186
195
  // Moment prototype object
187
196
  function Moment(config) {
188
197
  copyConfig(this, config);
189
- this._d = new Date(+config._d);
198
+ this._d = new Date(config._d != null ? config._d.getTime() : NaN);
190
199
  // Prevent infinite loop in case updateOffset creates new moment
191
200
  // objects.
192
201
  if (updateInProgress === false) {
@@ -197,7 +206,15 @@
197
206
  }
198
207
 
199
208
  function isMoment (obj) {
200
- return obj instanceof Moment || (obj != null && hasOwnProp(obj, '_isAMomentObject'));
209
+ return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
210
+ }
211
+
212
+ function absFloor (number) {
213
+ if (number < 0) {
214
+ return Math.ceil(number);
215
+ } else {
216
+ return Math.floor(number);
217
+ }
201
218
  }
202
219
 
203
220
  function toInt(argumentForCoercion) {
@@ -205,11 +222,7 @@
205
222
  value = 0;
206
223
 
207
224
  if (coercedNumber !== 0 && isFinite(coercedNumber)) {
208
- if (coercedNumber >= 0) {
209
- value = Math.floor(coercedNumber);
210
- } else {
211
- value = Math.ceil(coercedNumber);
212
- }
225
+ value = absFloor(coercedNumber);
213
226
  }
214
227
 
215
228
  return value;
@@ -307,9 +320,7 @@
307
320
  function defineLocale (name, values) {
308
321
  if (values !== null) {
309
322
  values.abbr = name;
310
- if (!locales[name]) {
311
- locales[name] = new Locale();
312
- }
323
+ locales[name] = locales[name] || new Locale();
313
324
  locales[name].set(values);
314
325
 
315
326
  // backwards compat for now: also set the locale
@@ -413,16 +424,14 @@
413
424
  }
414
425
 
415
426
  function zeroFill(number, targetLength, forceSign) {
416
- var output = '' + Math.abs(number),
427
+ var absNumber = '' + Math.abs(number),
428
+ zerosToFill = targetLength - absNumber.length,
417
429
  sign = number >= 0;
418
-
419
- while (output.length < targetLength) {
420
- output = '0' + output;
421
- }
422
- return (sign ? (forceSign ? '+' : '') : '-') + output;
430
+ return (sign ? (forceSign ? '+' : '') : '-') +
431
+ Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
423
432
  }
424
433
 
425
- var 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|X|zz?|ZZ?|.)/g;
434
+ var 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,9}|x|X|zz?|ZZ?|.)/g;
426
435
 
427
436
  var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
428
437
 
@@ -490,10 +499,7 @@
490
499
  }
491
500
 
492
501
  format = expandFormat(format, m.localeData());
493
-
494
- if (!formatFunctions[format]) {
495
- formatFunctions[format] = makeFormatFunction(format);
496
- }
502
+ formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
497
503
 
498
504
  return formatFunctions[format](m);
499
505
  }
@@ -537,8 +543,15 @@
537
543
 
538
544
  var regexes = {};
539
545
 
546
+ function isFunction (sth) {
547
+ // https://github.com/moment/moment/issues/2325
548
+ return typeof sth === 'function' &&
549
+ Object.prototype.toString.call(sth) === '[object Function]';
550
+ }
551
+
552
+
540
553
  function addRegexToken (token, regex, strictRegex) {
541
- regexes[token] = typeof regex === 'function' ? regex : function (isStrict) {
554
+ regexes[token] = isFunction(regex) ? regex : function (isStrict) {
542
555
  return (isStrict && strictRegex) ? strictRegex : regex;
543
556
  };
544
557
  }
@@ -635,7 +648,7 @@
635
648
  if (month != null) {
636
649
  array[MONTH] = month;
637
650
  } else {
638
- config._pf.invalidMonth = input;
651
+ getParsingFlags(config).invalidMonth = input;
639
652
  }
640
653
  });
641
654
 
@@ -719,7 +732,7 @@
719
732
  var overflow;
720
733
  var a = m._a;
721
734
 
722
- if (a && m._pf.overflow === -2) {
735
+ if (a && getParsingFlags(m).overflow === -2) {
723
736
  overflow =
724
737
  a[MONTH] < 0 || a[MONTH] > 11 ? MONTH :
725
738
  a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
@@ -729,11 +742,11 @@
729
742
  a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
730
743
  -1;
731
744
 
732
- if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
745
+ if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
733
746
  overflow = DATE;
734
747
  }
735
748
 
736
- m._pf.overflow = overflow;
749
+ getParsingFlags(m).overflow = overflow;
737
750
  }
738
751
 
739
752
  return m;
@@ -747,9 +760,10 @@
747
760
 
748
761
  function deprecate(msg, fn) {
749
762
  var firstTime = true;
763
+
750
764
  return extend(function () {
751
765
  if (firstTime) {
752
- warn(msg);
766
+ warn(msg + '\n' + (new Error()).stack);
753
767
  firstTime = false;
754
768
  }
755
769
  return fn.apply(this, arguments);
@@ -794,17 +808,17 @@
794
808
  match = from_string__isoRegex.exec(string);
795
809
 
796
810
  if (match) {
797
- config._pf.iso = true;
811
+ getParsingFlags(config).iso = true;
798
812
  for (i = 0, l = isoDates.length; i < l; i++) {
799
813
  if (isoDates[i][1].exec(string)) {
800
- // match[5] should be 'T' or undefined
801
- config._f = isoDates[i][0] + (match[6] || ' ');
814
+ config._f = isoDates[i][0];
802
815
  break;
803
816
  }
804
817
  }
805
818
  for (i = 0, l = isoTimes.length; i < l; i++) {
806
819
  if (isoTimes[i][1].exec(string)) {
807
- config._f += isoTimes[i][0];
820
+ // match[6] should be 'T' or space
821
+ config._f += (match[6] || ' ') + isoTimes[i][0];
808
822
  break;
809
823
  }
810
824
  }
@@ -883,7 +897,10 @@
883
897
  addRegexToken('YYYYY', match1to6, match6);
884
898
  addRegexToken('YYYYYY', match1to6, match6);
885
899
 
886
- addParseToken(['YYYY', 'YYYYY', 'YYYYYY'], YEAR);
900
+ addParseToken(['YYYYY', 'YYYYYY'], YEAR);
901
+ addParseToken('YYYY', function (input, array) {
902
+ array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);
903
+ });
887
904
  addParseToken('YY', function (input, array) {
888
905
  array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);
889
906
  });
@@ -1010,18 +1027,18 @@
1010
1027
 
1011
1028
  //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
1012
1029
  function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
1013
- var d = createUTCDate(year, 0, 1).getUTCDay();
1014
- var daysToAdd;
1015
- var dayOfYear;
1030
+ var week1Jan = 6 + firstDayOfWeek - firstDayOfWeekOfYear, janX = createUTCDate(year, 0, 1 + week1Jan), d = janX.getUTCDay(), dayOfYear;
1031
+ if (d < firstDayOfWeek) {
1032
+ d += 7;
1033
+ }
1034
+
1035
+ weekday = weekday != null ? 1 * weekday : firstDayOfWeek;
1016
1036
 
1017
- d = d === 0 ? 7 : d;
1018
- weekday = weekday != null ? weekday : firstDayOfWeek;
1019
- daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
1020
- dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
1037
+ dayOfYear = 1 + week1Jan + 7 * (week - 1) - d + weekday;
1021
1038
 
1022
1039
  return {
1023
- year : dayOfYear > 0 ? year : year - 1,
1024
- dayOfYear : dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
1040
+ year: dayOfYear > 0 ? year : year - 1,
1041
+ dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
1025
1042
  };
1026
1043
  }
1027
1044
 
@@ -1074,7 +1091,7 @@
1074
1091
  yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
1075
1092
 
1076
1093
  if (config._dayOfYear > daysInYear(yearToUse)) {
1077
- config._pf._overflowDayOfYear = true;
1094
+ getParsingFlags(config)._overflowDayOfYear = true;
1078
1095
  }
1079
1096
 
1080
1097
  date = createUTCDate(yearToUse, 0, config._dayOfYear);
@@ -1170,7 +1187,7 @@
1170
1187
  }
1171
1188
 
1172
1189
  config._a = [];
1173
- config._pf.empty = true;
1190
+ getParsingFlags(config).empty = true;
1174
1191
 
1175
1192
  // This array is used to make a Date, either with `new Date` or `Date.UTC`
1176
1193
  var string = '' + config._i,
@@ -1186,7 +1203,7 @@
1186
1203
  if (parsedInput) {
1187
1204
  skipped = string.substr(0, string.indexOf(parsedInput));
1188
1205
  if (skipped.length > 0) {
1189
- config._pf.unusedInput.push(skipped);
1206
+ getParsingFlags(config).unusedInput.push(skipped);
1190
1207
  }
1191
1208
  string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
1192
1209
  totalParsedInputLength += parsedInput.length;
@@ -1194,27 +1211,29 @@
1194
1211
  // don't parse if it's not a known token
1195
1212
  if (formatTokenFunctions[token]) {
1196
1213
  if (parsedInput) {
1197
- config._pf.empty = false;
1214
+ getParsingFlags(config).empty = false;
1198
1215
  }
1199
1216
  else {
1200
- config._pf.unusedTokens.push(token);
1217
+ getParsingFlags(config).unusedTokens.push(token);
1201
1218
  }
1202
1219
  addTimeToArrayFromToken(token, parsedInput, config);
1203
1220
  }
1204
1221
  else if (config._strict && !parsedInput) {
1205
- config._pf.unusedTokens.push(token);
1222
+ getParsingFlags(config).unusedTokens.push(token);
1206
1223
  }
1207
1224
  }
1208
1225
 
1209
1226
  // add remaining unparsed input length to the string
1210
- config._pf.charsLeftOver = stringLength - totalParsedInputLength;
1227
+ getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
1211
1228
  if (string.length > 0) {
1212
- config._pf.unusedInput.push(string);
1229
+ getParsingFlags(config).unusedInput.push(string);
1213
1230
  }
1214
1231
 
1215
1232
  // clear _12h flag if hour is <= 12
1216
- if (config._pf.bigHour === true && config._a[HOUR] <= 12) {
1217
- config._pf.bigHour = undefined;
1233
+ if (getParsingFlags(config).bigHour === true &&
1234
+ config._a[HOUR] <= 12 &&
1235
+ config._a[HOUR] > 0) {
1236
+ getParsingFlags(config).bigHour = undefined;
1218
1237
  }
1219
1238
  // handle meridiem
1220
1239
  config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
@@ -1258,7 +1277,7 @@
1258
1277
  currentScore;
1259
1278
 
1260
1279
  if (config._f.length === 0) {
1261
- config._pf.invalidFormat = true;
1280
+ getParsingFlags(config).invalidFormat = true;
1262
1281
  config._d = new Date(NaN);
1263
1282
  return;
1264
1283
  }
@@ -1269,7 +1288,6 @@
1269
1288
  if (config._useUTC != null) {
1270
1289
  tempConfig._useUTC = config._useUTC;
1271
1290
  }
1272
- tempConfig._pf = defaultParsingFlags();
1273
1291
  tempConfig._f = config._f[i];
1274
1292
  configFromStringAndFormat(tempConfig);
1275
1293
 
@@ -1278,12 +1296,12 @@
1278
1296
  }
1279
1297
 
1280
1298
  // if there is any input that was not parsed add a penalty for that format
1281
- currentScore += tempConfig._pf.charsLeftOver;
1299
+ currentScore += getParsingFlags(tempConfig).charsLeftOver;
1282
1300
 
1283
1301
  //or tokens
1284
- currentScore += tempConfig._pf.unusedTokens.length * 10;
1302
+ currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
1285
1303
 
1286
- tempConfig._pf.score = currentScore;
1304
+ getParsingFlags(tempConfig).score = currentScore;
1287
1305
 
1288
1306
  if (scoreToBeat == null || currentScore < scoreToBeat) {
1289
1307
  scoreToBeat = currentScore;
@@ -1306,9 +1324,19 @@
1306
1324
  }
1307
1325
 
1308
1326
  function createFromConfig (config) {
1327
+ var res = new Moment(checkOverflow(prepareConfig(config)));
1328
+ if (res._nextDay) {
1329
+ // Adding is smart enough around DST
1330
+ res.add(1, 'd');
1331
+ res._nextDay = undefined;
1332
+ }
1333
+
1334
+ return res;
1335
+ }
1336
+
1337
+ function prepareConfig (config) {
1309
1338
  var input = config._i,
1310
- format = config._f,
1311
- res;
1339
+ format = config._f;
1312
1340
 
1313
1341
  config._locale = config._locale || locale_locales__getLocale(config._l);
1314
1342
 
@@ -1326,18 +1354,13 @@
1326
1354
  configFromStringAndArray(config);
1327
1355
  } else if (format) {
1328
1356
  configFromStringAndFormat(config);
1357
+ } else if (isDate(input)) {
1358
+ config._d = input;
1329
1359
  } else {
1330
1360
  configFromInput(config);
1331
1361
  }
1332
1362
 
1333
- res = new Moment(checkOverflow(config));
1334
- if (res._nextDay) {
1335
- // Adding is smart enough around DST
1336
- res.add(1, 'd');
1337
- res._nextDay = undefined;
1338
- }
1339
-
1340
- return res;
1363
+ return config;
1341
1364
  }
1342
1365
 
1343
1366
  function configFromInput(config) {
@@ -1378,7 +1401,6 @@
1378
1401
  c._i = input;
1379
1402
  c._f = format;
1380
1403
  c._strict = strict;
1381
- c._pf = defaultParsingFlags();
1382
1404
 
1383
1405
  return createFromConfig(c);
1384
1406
  }
@@ -1418,7 +1440,7 @@
1418
1440
  }
1419
1441
  res = moments[0];
1420
1442
  for (i = 1; i < moments.length; ++i) {
1421
- if (moments[i][fn](res)) {
1443
+ if (!moments[i].isValid() || moments[i][fn](res)) {
1422
1444
  res = moments[i];
1423
1445
  }
1424
1446
  }
@@ -1530,7 +1552,6 @@
1530
1552
  } else {
1531
1553
  return local__createLocal(input).local();
1532
1554
  }
1533
- return model._isUTC ? local__createLocal(input).zone(model._offset || 0) : local__createLocal(input).local();
1534
1555
  }
1535
1556
 
1536
1557
  function getDateOffset (m) {
@@ -1630,12 +1651,7 @@
1630
1651
  }
1631
1652
 
1632
1653
  function hasAlignedHourOffset (input) {
1633
- if (!input) {
1634
- input = 0;
1635
- }
1636
- else {
1637
- input = local__createLocal(input).utcOffset();
1638
- }
1654
+ input = input ? local__createLocal(input).utcOffset() : 0;
1639
1655
 
1640
1656
  return (this.utcOffset() - input) % 60 === 0;
1641
1657
  }
@@ -1648,12 +1664,24 @@
1648
1664
  }
1649
1665
 
1650
1666
  function isDaylightSavingTimeShifted () {
1651
- if (this._a) {
1652
- var other = this._isUTC ? create_utc__createUTC(this._a) : local__createLocal(this._a);
1653
- return this.isValid() && compareArrays(this._a, other.toArray()) > 0;
1667
+ if (typeof this._isDSTShifted !== 'undefined') {
1668
+ return this._isDSTShifted;
1669
+ }
1670
+
1671
+ var c = {};
1672
+
1673
+ copyConfig(c, this);
1674
+ c = prepareConfig(c);
1675
+
1676
+ if (c._a) {
1677
+ var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a);
1678
+ this._isDSTShifted = this.isValid() &&
1679
+ compareArrays(c._a, other.toArray()) > 0;
1680
+ } else {
1681
+ this._isDSTShifted = false;
1654
1682
  }
1655
1683
 
1656
- return false;
1684
+ return this._isDSTShifted;
1657
1685
  }
1658
1686
 
1659
1687
  function isLocal () {
@@ -1813,7 +1841,7 @@
1813
1841
  var add_subtract__add = createAdder(1, 'add');
1814
1842
  var add_subtract__subtract = createAdder(-1, 'subtract');
1815
1843
 
1816
- function moment_calendar__calendar (time) {
1844
+ function moment_calendar__calendar (time, formats) {
1817
1845
  // We want to compare the start of today, vs this.
1818
1846
  // Getting start-of-today depends on whether we're local/utc/offset or not.
1819
1847
  var now = time || local__createLocal(),
@@ -1825,7 +1853,7 @@
1825
1853
  diff < 1 ? 'sameDay' :
1826
1854
  diff < 2 ? 'nextDay' :
1827
1855
  diff < 7 ? 'nextWeek' : 'sameElse';
1828
- return this.format(this.localeData().calendar(format, this, local__createLocal(now)));
1856
+ return this.format(formats && formats[format] || this.localeData().calendar(format, this, local__createLocal(now)));
1829
1857
  }
1830
1858
 
1831
1859
  function clone () {
@@ -1872,14 +1900,6 @@
1872
1900
  }
1873
1901
  }
1874
1902
 
1875
- function absFloor (number) {
1876
- if (number < 0) {
1877
- return Math.ceil(number);
1878
- } else {
1879
- return Math.floor(number);
1880
- }
1881
- }
1882
-
1883
1903
  function diff (input, units, asFloat) {
1884
1904
  var that = cloneWithOffset(input, this),
1885
1905
  zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,
@@ -1952,6 +1972,9 @@
1952
1972
  }
1953
1973
 
1954
1974
  function from (time, withoutSuffix) {
1975
+ if (!this.isValid()) {
1976
+ return this.localeData().invalidDate();
1977
+ }
1955
1978
  return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
1956
1979
  }
1957
1980
 
@@ -1959,6 +1982,17 @@
1959
1982
  return this.from(local__createLocal(), withoutSuffix);
1960
1983
  }
1961
1984
 
1985
+ function to (time, withoutSuffix) {
1986
+ if (!this.isValid()) {
1987
+ return this.localeData().invalidDate();
1988
+ }
1989
+ return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
1990
+ }
1991
+
1992
+ function toNow (withoutSuffix) {
1993
+ return this.to(local__createLocal(), withoutSuffix);
1994
+ }
1995
+
1962
1996
  function locale (key) {
1963
1997
  var newLocaleData;
1964
1998
 
@@ -2056,16 +2090,29 @@
2056
2090
  return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
2057
2091
  }
2058
2092
 
2093
+ function toObject () {
2094
+ var m = this;
2095
+ return {
2096
+ years: m.year(),
2097
+ months: m.month(),
2098
+ date: m.date(),
2099
+ hours: m.hours(),
2100
+ minutes: m.minutes(),
2101
+ seconds: m.seconds(),
2102
+ milliseconds: m.milliseconds()
2103
+ };
2104
+ }
2105
+
2059
2106
  function moment_valid__isValid () {
2060
2107
  return valid__isValid(this);
2061
2108
  }
2062
2109
 
2063
2110
  function parsingFlags () {
2064
- return extend({}, this._pf);
2111
+ return extend({}, getParsingFlags(this));
2065
2112
  }
2066
2113
 
2067
2114
  function invalidAt () {
2068
- return this._pf.overflow;
2115
+ return getParsingFlags(this).overflow;
2069
2116
  }
2070
2117
 
2071
2118
  addFormatToken(0, ['gg', 2], 0, function () {
@@ -2216,7 +2263,7 @@
2216
2263
  if (weekday != null) {
2217
2264
  week.d = weekday;
2218
2265
  } else {
2219
- config._pf.invalidWeekday = input;
2266
+ getParsingFlags(config).invalidWeekday = input;
2220
2267
  }
2221
2268
  });
2222
2269
 
@@ -2227,18 +2274,20 @@
2227
2274
  // HELPERS
2228
2275
 
2229
2276
  function parseWeekday(input, locale) {
2230
- if (typeof input === 'string') {
2231
- if (!isNaN(input)) {
2232
- input = parseInt(input, 10);
2233
- }
2234
- else {
2235
- input = locale.weekdaysParse(input);
2236
- if (typeof input !== 'number') {
2237
- return null;
2238
- }
2239
- }
2277
+ if (typeof input !== 'string') {
2278
+ return input;
2240
2279
  }
2241
- return input;
2280
+
2281
+ if (!isNaN(input)) {
2282
+ return parseInt(input, 10);
2283
+ }
2284
+
2285
+ input = locale.weekdaysParse(input);
2286
+ if (typeof input === 'number') {
2287
+ return input;
2288
+ }
2289
+
2290
+ return null;
2242
2291
  }
2243
2292
 
2244
2293
  // LOCALES
@@ -2261,9 +2310,7 @@
2261
2310
  function localeWeekdaysParse (weekdayName) {
2262
2311
  var i, mom, regex;
2263
2312
 
2264
- if (!this._weekdaysParse) {
2265
- this._weekdaysParse = [];
2266
- }
2313
+ this._weekdaysParse = this._weekdaysParse || [];
2267
2314
 
2268
2315
  for (i = 0; i < 7; i++) {
2269
2316
  // make the regex if we don't have it already
@@ -2341,7 +2388,7 @@
2341
2388
  });
2342
2389
  addParseToken(['h', 'hh'], function (input, array, config) {
2343
2390
  array[HOUR] = toInt(input);
2344
- config._pf.bigHour = true;
2391
+ getParsingFlags(config).bigHour = true;
2345
2392
  });
2346
2393
 
2347
2394
  // LOCALES
@@ -2410,12 +2457,26 @@
2410
2457
  return ~~(this.millisecond() / 10);
2411
2458
  });
2412
2459
 
2413
- function millisecond__milliseconds (token) {
2414
- addFormatToken(0, [token, 3], 0, 'millisecond');
2415
- }
2460
+ addFormatToken(0, ['SSS', 3], 0, 'millisecond');
2461
+ addFormatToken(0, ['SSSS', 4], 0, function () {
2462
+ return this.millisecond() * 10;
2463
+ });
2464
+ addFormatToken(0, ['SSSSS', 5], 0, function () {
2465
+ return this.millisecond() * 100;
2466
+ });
2467
+ addFormatToken(0, ['SSSSSS', 6], 0, function () {
2468
+ return this.millisecond() * 1000;
2469
+ });
2470
+ addFormatToken(0, ['SSSSSSS', 7], 0, function () {
2471
+ return this.millisecond() * 10000;
2472
+ });
2473
+ addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
2474
+ return this.millisecond() * 100000;
2475
+ });
2476
+ addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
2477
+ return this.millisecond() * 1000000;
2478
+ });
2416
2479
 
2417
- millisecond__milliseconds('SSS');
2418
- millisecond__milliseconds('SSSS');
2419
2480
 
2420
2481
  // ALIASES
2421
2482
 
@@ -2426,11 +2487,19 @@
2426
2487
  addRegexToken('S', match1to3, match1);
2427
2488
  addRegexToken('SS', match1to3, match2);
2428
2489
  addRegexToken('SSS', match1to3, match3);
2429
- addRegexToken('SSSS', matchUnsigned);
2430
- addParseToken(['S', 'SS', 'SSS', 'SSSS'], function (input, array) {
2490
+
2491
+ var token;
2492
+ for (token = 'SSSS'; token.length <= 9; token += 'S') {
2493
+ addRegexToken(token, matchUnsigned);
2494
+ }
2495
+
2496
+ function parseMs(input, array) {
2431
2497
  array[MILLISECOND] = toInt(('0.' + input) * 1000);
2432
- });
2498
+ }
2433
2499
 
2500
+ for (token = 'S'; token.length <= 9; token += 'S') {
2501
+ addParseToken(token, parseMs);
2502
+ }
2434
2503
  // MOMENTS
2435
2504
 
2436
2505
  var getSetMillisecond = makeGetSet('Milliseconds', false);
@@ -2458,6 +2527,8 @@
2458
2527
  momentPrototype__proto.format = format;
2459
2528
  momentPrototype__proto.from = from;
2460
2529
  momentPrototype__proto.fromNow = fromNow;
2530
+ momentPrototype__proto.to = to;
2531
+ momentPrototype__proto.toNow = toNow;
2461
2532
  momentPrototype__proto.get = getSet;
2462
2533
  momentPrototype__proto.invalidAt = invalidAt;
2463
2534
  momentPrototype__proto.isAfter = isAfter;
@@ -2475,6 +2546,7 @@
2475
2546
  momentPrototype__proto.startOf = startOf;
2476
2547
  momentPrototype__proto.subtract = add_subtract__subtract;
2477
2548
  momentPrototype__proto.toArray = toArray;
2549
+ momentPrototype__proto.toObject = toObject;
2478
2550
  momentPrototype__proto.toDate = toDate;
2479
2551
  momentPrototype__proto.toISOString = moment_format__toISOString;
2480
2552
  momentPrototype__proto.toJSON = moment_format__toISOString;
@@ -2574,19 +2646,23 @@
2574
2646
  LT : 'h:mm A',
2575
2647
  L : 'MM/DD/YYYY',
2576
2648
  LL : 'MMMM D, YYYY',
2577
- LLL : 'MMMM D, YYYY LT',
2578
- LLLL : 'dddd, MMMM D, YYYY LT'
2649
+ LLL : 'MMMM D, YYYY h:mm A',
2650
+ LLLL : 'dddd, MMMM D, YYYY h:mm A'
2579
2651
  };
2580
2652
 
2581
2653
  function longDateFormat (key) {
2582
- var output = this._longDateFormat[key];
2583
- if (!output && this._longDateFormat[key.toUpperCase()]) {
2584
- output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
2585
- return val.slice(1);
2586
- });
2587
- this._longDateFormat[key] = output;
2654
+ var format = this._longDateFormat[key],
2655
+ formatUpper = this._longDateFormat[key.toUpperCase()];
2656
+
2657
+ if (format || !formatUpper) {
2658
+ return format;
2588
2659
  }
2589
- return output;
2660
+
2661
+ this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
2662
+ return val.slice(1);
2663
+ });
2664
+
2665
+ return this._longDateFormat[key];
2590
2666
  }
2591
2667
 
2592
2668
  var defaultInvalidDate = 'Invalid date';
@@ -2646,7 +2722,7 @@
2646
2722
  }
2647
2723
  // Lenient ordinal parsing accepts just a number in addition to
2648
2724
  // number + (possibly) stuff coming from _ordinalParseLenient.
2649
- this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\d{1,2}/.source);
2725
+ this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source);
2650
2726
  }
2651
2727
 
2652
2728
  var prototype__proto = Locale.prototype;
@@ -2795,12 +2871,29 @@
2795
2871
  return duration_add_subtract__addSubtract(this, input, value, -1);
2796
2872
  }
2797
2873
 
2874
+ function absCeil (number) {
2875
+ if (number < 0) {
2876
+ return Math.floor(number);
2877
+ } else {
2878
+ return Math.ceil(number);
2879
+ }
2880
+ }
2881
+
2798
2882
  function bubble () {
2799
2883
  var milliseconds = this._milliseconds;
2800
2884
  var days = this._days;
2801
2885
  var months = this._months;
2802
2886
  var data = this._data;
2803
- var seconds, minutes, hours, years = 0;
2887
+ var seconds, minutes, hours, years, monthsFromDays;
2888
+
2889
+ // if we have a mix of positive and negative values, bubble down first
2890
+ // check: https://github.com/moment/moment/issues/2166
2891
+ if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
2892
+ (milliseconds <= 0 && days <= 0 && months <= 0))) {
2893
+ milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
2894
+ days = 0;
2895
+ months = 0;
2896
+ }
2804
2897
 
2805
2898
  // The following code bubbles up values, see the tests for
2806
2899
  // examples of what that means.
@@ -2817,17 +2910,13 @@
2817
2910
 
2818
2911
  days += absFloor(hours / 24);
2819
2912
 
2820
- // Accurately convert days to years, assume start from year 0.
2821
- years = absFloor(daysToYears(days));
2822
- days -= absFloor(yearsToDays(years));
2823
-
2824
- // 30 days to a month
2825
- // TODO (iskren): Use anchor date (like 1st Jan) to compute this.
2826
- months += absFloor(days / 30);
2827
- days %= 30;
2913
+ // convert days to months
2914
+ monthsFromDays = absFloor(daysToMonths(days));
2915
+ months += monthsFromDays;
2916
+ days -= absCeil(monthsToDays(monthsFromDays));
2828
2917
 
2829
2918
  // 12 months -> 1 year
2830
- years += absFloor(months / 12);
2919
+ years = absFloor(months / 12);
2831
2920
  months %= 12;
2832
2921
 
2833
2922
  data.days = days;
@@ -2837,15 +2926,15 @@
2837
2926
  return this;
2838
2927
  }
2839
2928
 
2840
- function daysToYears (days) {
2929
+ function daysToMonths (days) {
2841
2930
  // 400 years have 146097 days (taking into account leap year rules)
2842
- return days * 400 / 146097;
2931
+ // 400 years have 12 months === 4800
2932
+ return days * 4800 / 146097;
2843
2933
  }
2844
2934
 
2845
- function yearsToDays (years) {
2846
- // years * 365 + absFloor(years / 4) -
2847
- // absFloor(years / 100) + absFloor(years / 400);
2848
- return years * 146097 / 400;
2935
+ function monthsToDays (months) {
2936
+ // the reverse of daysToMonths
2937
+ return months * 146097 / 4800;
2849
2938
  }
2850
2939
 
2851
2940
  function as (units) {
@@ -2857,19 +2946,19 @@
2857
2946
 
2858
2947
  if (units === 'month' || units === 'year') {
2859
2948
  days = this._days + milliseconds / 864e5;
2860
- months = this._months + daysToYears(days) * 12;
2949
+ months = this._months + daysToMonths(days);
2861
2950
  return units === 'month' ? months : months / 12;
2862
2951
  } else {
2863
2952
  // handle milliseconds separately because of floating point math errors (issue #1867)
2864
- days = this._days + Math.round(yearsToDays(this._months / 12));
2953
+ days = this._days + Math.round(monthsToDays(this._months));
2865
2954
  switch (units) {
2866
- case 'week' : return days / 7 + milliseconds / 6048e5;
2867
- case 'day' : return days + milliseconds / 864e5;
2868
- case 'hour' : return days * 24 + milliseconds / 36e5;
2869
- case 'minute' : return days * 24 * 60 + milliseconds / 6e4;
2870
- case 'second' : return days * 24 * 60 * 60 + milliseconds / 1000;
2955
+ case 'week' : return days / 7 + milliseconds / 6048e5;
2956
+ case 'day' : return days + milliseconds / 864e5;
2957
+ case 'hour' : return days * 24 + milliseconds / 36e5;
2958
+ case 'minute' : return days * 1440 + milliseconds / 6e4;
2959
+ case 'second' : return days * 86400 + milliseconds / 1000;
2871
2960
  // Math.floor prevents floating point math errors here
2872
- case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + milliseconds;
2961
+ case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
2873
2962
  default: throw new Error('Unknown unit ' + units);
2874
2963
  }
2875
2964
  }
@@ -2911,7 +3000,7 @@
2911
3000
  };
2912
3001
  }
2913
3002
 
2914
- var duration_get__milliseconds = makeGetter('milliseconds');
3003
+ var milliseconds = makeGetter('milliseconds');
2915
3004
  var seconds = makeGetter('seconds');
2916
3005
  var minutes = makeGetter('minutes');
2917
3006
  var hours = makeGetter('hours');
@@ -2989,13 +3078,36 @@
2989
3078
  var iso_string__abs = Math.abs;
2990
3079
 
2991
3080
  function iso_string__toISOString() {
3081
+ // for ISO strings we do not use the normal bubbling rules:
3082
+ // * milliseconds bubble up until they become hours
3083
+ // * days do not bubble at all
3084
+ // * months bubble up until they become years
3085
+ // This is because there is no context-free conversion between hours and days
3086
+ // (think of clock changes)
3087
+ // and also not between days and months (28-31 days per month)
3088
+ var seconds = iso_string__abs(this._milliseconds) / 1000;
3089
+ var days = iso_string__abs(this._days);
3090
+ var months = iso_string__abs(this._months);
3091
+ var minutes, hours, years;
3092
+
3093
+ // 3600 seconds -> 60 minutes -> 1 hour
3094
+ minutes = absFloor(seconds / 60);
3095
+ hours = absFloor(minutes / 60);
3096
+ seconds %= 60;
3097
+ minutes %= 60;
3098
+
3099
+ // 12 months -> 1 year
3100
+ years = absFloor(months / 12);
3101
+ months %= 12;
3102
+
3103
+
2992
3104
  // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
2993
- var Y = iso_string__abs(this.years());
2994
- var M = iso_string__abs(this.months());
2995
- var D = iso_string__abs(this.days());
2996
- var h = iso_string__abs(this.hours());
2997
- var m = iso_string__abs(this.minutes());
2998
- var s = iso_string__abs(this.seconds() + this.milliseconds() / 1000);
3105
+ var Y = years;
3106
+ var M = months;
3107
+ var D = days;
3108
+ var h = hours;
3109
+ var m = minutes;
3110
+ var s = seconds;
2999
3111
  var total = this.asSeconds();
3000
3112
 
3001
3113
  if (!total) {
@@ -3032,7 +3144,7 @@
3032
3144
  duration_prototype__proto.valueOf = duration_as__valueOf;
3033
3145
  duration_prototype__proto._bubble = bubble;
3034
3146
  duration_prototype__proto.get = duration_get__get;
3035
- duration_prototype__proto.milliseconds = duration_get__milliseconds;
3147
+ duration_prototype__proto.milliseconds = milliseconds;
3036
3148
  duration_prototype__proto.seconds = seconds;
3037
3149
  duration_prototype__proto.minutes = minutes;
3038
3150
  duration_prototype__proto.hours = hours;
@@ -3070,7 +3182,7 @@
3070
3182
  // Side effect imports
3071
3183
 
3072
3184
 
3073
- utils_hooks__hooks.version = '2.10.2';
3185
+ utils_hooks__hooks.version = '2.10.6';
3074
3186
 
3075
3187
  setHookCallback(local__createLocal);
3076
3188