utiller 1.0.395 → 1.0.397
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.
- package/lib/utiller/index.js +270 -20
- package/package.json +1 -1
- package/template/sample.package.json +1 -1
package/lib/utiller/index.js
CHANGED
|
@@ -699,6 +699,156 @@ var Utiller = /*#__PURE__*/function () {
|
|
|
699
699
|
var factor = Math.pow(10, precision);
|
|
700
700
|
return Math.ceil(a * b * factor) / factor;
|
|
701
701
|
});
|
|
702
|
+
/**
|
|
703
|
+
* 根據課程資訊生成 Google Calendar 的行事曆新增連結。
|
|
704
|
+
* @param {object} event - 行程物件。
|
|
705
|
+
* @param {string} event.title - 行程主題 (e.g., '吉他課')。
|
|
706
|
+
* @param {string} event.startDate - 開始日期 (e.g., '2025/11/10')。
|
|
707
|
+
* @param {string} event.startTime - 開始時間 (e.g., '14:00')。
|
|
708
|
+
* @param {string} event.endDate - 結束日期 (e.g., '2025/11/10')。
|
|
709
|
+
* @param {string} event.endTime - 結束時間 (e.g., '16:00')。
|
|
710
|
+
* @param {string} event.location - 地點/地址 (e.g., '台北市大安區信義路三段 162 號')。
|
|
711
|
+
* @param {string} event.details - 描述/備註 (e.g., '請攜帶吉他,並預習第5頁。')。
|
|
712
|
+
* @returns {string} Google Calendar 的新增連結。
|
|
713
|
+
*/
|
|
714
|
+
(0, _defineProperty2["default"])(this, "generateGoogleCalendarLink", function (_ref4) {
|
|
715
|
+
var title = _ref4.title,
|
|
716
|
+
startDate = _ref4.startDate,
|
|
717
|
+
startTime = _ref4.startTime,
|
|
718
|
+
endDate = _ref4.endDate,
|
|
719
|
+
endTime = _ref4.endTime,
|
|
720
|
+
location = _ref4.location,
|
|
721
|
+
details = _ref4.details;
|
|
722
|
+
// 使用 moment 結合日期和時間,並格式化為 YYYYMMDDTHHMMSS
|
|
723
|
+
// 注意: 日期格式已從 YYYY-MM-DD 變更為 YYYY/MM/DD
|
|
724
|
+
var startDateTime = (0, _momentTimezone["default"])("".concat(startDate, " ").concat(startTime), "YYYY/MM/DD HH:mm").format("YYYYMMDDTHHMMSS");
|
|
725
|
+
var endDateTime = (0, _momentTimezone["default"])("".concat(endDate, " ").concat(endTime), "YYYY/MM/DD HH:mm").format("YYYYMMDDTHHMMSS");
|
|
726
|
+
|
|
727
|
+
// 進行 URL 編碼
|
|
728
|
+
var encodedTitle = encodeURIComponent(title);
|
|
729
|
+
var encodedLocation = encodeURIComponent(location);
|
|
730
|
+
var encodedDetails = encodeURIComponent(details);
|
|
731
|
+
|
|
732
|
+
// --- Google Calendar 連結 (使用 https://calendar.google.com/calendar/r/eventedit) ---
|
|
733
|
+
var googleCalendarLink = "https://calendar.google.com/calendar/r/eventedit?" + "text=".concat(encodedTitle) + "&dates=".concat(startDateTime, "/").concat(endDateTime) + "&details=".concat(encodedDetails) + "&location=".concat(encodedLocation) + "&ctz=Asia/Taipei" + // 台灣時區
|
|
734
|
+
"&trp=true"; // 設為忙碌 (Busy)
|
|
735
|
+
|
|
736
|
+
return googleCalendarLink;
|
|
737
|
+
});
|
|
738
|
+
/**
|
|
739
|
+
* 根據課程資訊生成 TimeTree 的行事曆新增連結。
|
|
740
|
+
* (此函式不需要 moment.js,但維持其結構)
|
|
741
|
+
* @param {object} event - 行程物件。
|
|
742
|
+
* @param {string} event.title - 行程主題 (e.g., '吉他課')。
|
|
743
|
+
* @param {string} event.startDate - 開始日期 (YYYY/MM/DD, e.g., '2025/11/10')。
|
|
744
|
+
* @param {string} event.startTime - 開始時間 (HH:MM, e.g., '14:00')。
|
|
745
|
+
* @param {string} event.endDate - 結束日期 (YYYY/MM/DD, e.g., '2025/11/10')。
|
|
746
|
+
* @param {string} event.endTime - 結束時間 (HH:MM, e.g., '16:00')。
|
|
747
|
+
* @param {string} [event.location=''] - 地點/地址 (選填)。
|
|
748
|
+
* @param {string} [event.memo=''] - 描述/備註 (選填,TimeTree 使用 'memo')。
|
|
749
|
+
* @returns {string} TimeTree 行事曆新增連結。
|
|
750
|
+
*/
|
|
751
|
+
(0, _defineProperty2["default"])(this, "generateTimeTreeLink", function (_ref5) {
|
|
752
|
+
var title = _ref5.title,
|
|
753
|
+
startDate = _ref5.startDate,
|
|
754
|
+
startTime = _ref5.startTime,
|
|
755
|
+
endDate = _ref5.endDate,
|
|
756
|
+
endTime = _ref5.endTime,
|
|
757
|
+
_ref5$location = _ref5.location,
|
|
758
|
+
location = _ref5$location === void 0 ? "" : _ref5$location,
|
|
759
|
+
_ref5$memo = _ref5.memo,
|
|
760
|
+
memo = _ref5$memo === void 0 ? "" : _ref5$memo;
|
|
761
|
+
// 進行 URL 編碼
|
|
762
|
+
var encodedTitle = encodeURIComponent(title);
|
|
763
|
+
var encodedLocation = encodeURIComponent(location);
|
|
764
|
+
var encodedMemo = encodeURIComponent(memo);
|
|
765
|
+
|
|
766
|
+
// TimeTree 網址結構相對簡單,直接使用模板字串
|
|
767
|
+
// 注意: TimeTree 連結直接使用 YYYY-MM-DD 格式,故此函式仍傳遞原始 YYYY/MM/DD 字串
|
|
768
|
+
// 在實際應用中,如果 TimeTree 不接受 YYYY/MM/DD,則需要在傳入前轉換 (但 TimeTree 連結通常較為寬鬆)
|
|
769
|
+
var timeTreeLink = "https://timetreeapp.com/plans/new?" + "title=".concat(encodedTitle) + "&start_date=".concat(startDate.replace(/\//g, "-")) + // 將 YYYY/MM/DD 轉換回 YYYY-MM-DD
|
|
770
|
+
"&start_time=".concat(startTime) + "&end_date=".concat(endDate.replace(/\//g, "-")) + // 將 YYYY/MM/DD 轉換回 YYYY-MM-DD
|
|
771
|
+
"&end_time=".concat(endTime) + "".concat(location ? "&location=".concat(encodedLocation) : "") + "".concat(memo ? "&memo=".concat(encodedMemo) : "");
|
|
772
|
+
return timeTreeLink;
|
|
773
|
+
});
|
|
774
|
+
/**
|
|
775
|
+
* 根據課程資訊生成 iCalendar (.ics) 檔案內容。
|
|
776
|
+
* @param {object} event - 行程物件。
|
|
777
|
+
* @param {string} event.title - 行程主題。
|
|
778
|
+
* @param {string} event.startDate - 開始日期 (YYYY/MM/DD)。
|
|
779
|
+
* @param {string} event.startTime - 開始時間 (HH:MM)。
|
|
780
|
+
* @param {string} event.endDate - 結束日期 (YYYY/MM/DD)。
|
|
781
|
+
* @param {string} event.endTime - 結束時間 (HH:MM)。
|
|
782
|
+
* @param {string} event.location - 地點/地址。
|
|
783
|
+
* @param {string} event.details - 描述/備註。
|
|
784
|
+
* @returns {string} 遵循 iCalendar 規範的字串內容。
|
|
785
|
+
*/
|
|
786
|
+
(0, _defineProperty2["default"])(this, "generateIcsContent", function (_ref6) {
|
|
787
|
+
var title = _ref6.title,
|
|
788
|
+
startDate = _ref6.startDate,
|
|
789
|
+
startTime = _ref6.startTime,
|
|
790
|
+
endDate = _ref6.endDate,
|
|
791
|
+
endTime = _ref6.endTime,
|
|
792
|
+
location = _ref6.location,
|
|
793
|
+
details = _ref6.details;
|
|
794
|
+
// 使用 moment-timezone 結合日期和時間,並格式化為 YYYYMMDDTHHMMSS
|
|
795
|
+
// 注意: 日期格式已從 YYYY-MM-DD 變更為 YYYY/MM/DD
|
|
796
|
+
var startDateTime = _momentTimezone["default"].tz("".concat(startDate, " ").concat(startTime), "YYYY/MM/DD HH:mm", "Asia/Taipei").format("YYYYMMDDTHHMMSS");
|
|
797
|
+
var endDateTime = _momentTimezone["default"].tz("".concat(endDate, " ").concat(endTime), "YYYY/MM/DD HH:mm", "Asia/Taipei").format("YYYYMMDDTHHMMSS");
|
|
798
|
+
|
|
799
|
+
// DTSTAMP 必須是 UTC 格式 (以 Z 結尾)
|
|
800
|
+
var stamp = (0, _momentTimezone["default"])().utc().format("YYYYMMDDTHHMMSS") + "Z";
|
|
801
|
+
|
|
802
|
+
// 唯一識別碼 (UID)
|
|
803
|
+
var uid = Date.now().toString(36) + Math.random().toString(36).substring(2, 5) + "@gemini-app.com";
|
|
804
|
+
|
|
805
|
+
// 確保內容中的特殊字元(如換行、逗號、分號)被正確逸出
|
|
806
|
+
var escapeIcs = function escapeIcs(text) {
|
|
807
|
+
return text.replace(/\\/g, "\\\\").replace(/,/g, "\\,").replace(/;/g, "\\;").replace(/\n/g, "\\n");
|
|
808
|
+
};
|
|
809
|
+
var escapedTitle = escapeIcs(title);
|
|
810
|
+
var escapedLocation = escapeIcs(location);
|
|
811
|
+
var escapedDetails = escapeIcs(details);
|
|
812
|
+
|
|
813
|
+
// 產生 ICS 內容
|
|
814
|
+
var icsContent = "BEGIN:VCALENDAR\n" + "VERSION:2.0\n" + "PRODID:-//Gemini AI//NONSGML v1.0//EN\n" + "BEGIN:VEVENT\n" + "UID:".concat(uid, "\n") + "DTSTAMP:".concat(stamp, "\n") + // 採用 Asia/Taipei 時區
|
|
815
|
+
"DTSTART;TZID=Asia/Taipei:".concat(startDateTime, "\n") + "DTEND;TZID=Asia/Taipei:".concat(endDateTime, "\n") + "SUMMARY:".concat(escapedTitle, "\n") + "LOCATION:".concat(escapedLocation, "\n") + "DESCRIPTION:".concat(escapedDetails, "\n") + "END:VEVENT\n" + "END:VCALENDAR";
|
|
816
|
+
|
|
817
|
+
// 確保使用 CRLF (\r\n) 換行符號,這是 ICS 規範的要求
|
|
818
|
+
return icsContent.replace(/\n/g, "\r\n");
|
|
819
|
+
});
|
|
820
|
+
/**
|
|
821
|
+
* 根據行程物件,生成所有主要的行事曆新增連結 (Google, TimeTree, iCalendar/ICS)。
|
|
822
|
+
* @param {object} event - 行程物件。
|
|
823
|
+
* @param {string} event.title - 行程主題。
|
|
824
|
+
* @param {string} event.startDate - 開始日期 (YYYY/MM/DD)。
|
|
825
|
+
* @param {string} event.startTime - 開始時間 (HH:MM)。
|
|
826
|
+
* @param {string} event.endDate - 結束日期 (YYYY/MM/DD)。
|
|
827
|
+
* @param {string} event.endTime - 結束時間 (HH:MM)。
|
|
828
|
+
* @param {string} event.location - 地點/地址。
|
|
829
|
+
* @param {string} event.details - 描述/備註。
|
|
830
|
+
* @returns {{google: string, timeTree: string, ics: string}} 包含所有連結的物件。
|
|
831
|
+
*/
|
|
832
|
+
(0, _defineProperty2["default"])(this, "generateAllCalendarLinks", function (event) {
|
|
833
|
+
// 1. Google Calendar Link
|
|
834
|
+
var googleLink = _this.generateGoogleCalendarLink(event);
|
|
835
|
+
|
|
836
|
+
// 2. TimeTree Link
|
|
837
|
+
// TimeTree 使用 'memo' 參數,因此將 event.details 映射到 memo
|
|
838
|
+
var timeTreeEvent = _objectSpread(_objectSpread({}, event), {}, {
|
|
839
|
+
memo: event.details
|
|
840
|
+
});
|
|
841
|
+
var timeTreeLink = _this.generateTimeTreeLink(timeTreeEvent);
|
|
842
|
+
|
|
843
|
+
// 3. iCalendar (ICS) Link (Data URI 格式,用於 iOS/Outlook/下載)
|
|
844
|
+
var icsContent = _this.generateIcsContent(event);
|
|
845
|
+
var icsLink = "data:text/calendar;charset=utf8,".concat(encodeURIComponent(icsContent));
|
|
846
|
+
return {
|
|
847
|
+
google: googleLink,
|
|
848
|
+
timeTree: timeTreeLink,
|
|
849
|
+
ics: icsLink // iCalendar 連結
|
|
850
|
+
};
|
|
851
|
+
});
|
|
702
852
|
/**
|
|
703
853
|
* @param {Array<Object>} current - 要更新的目標陣列
|
|
704
854
|
* @param {Array<Object>} reference - 用來替換屬性的參照陣列
|
|
@@ -3987,9 +4137,9 @@ var Utiller = /*#__PURE__*/function () {
|
|
|
3987
4137
|
key: "mutateRemoveKeys",
|
|
3988
4138
|
value: function mutateRemoveKeys(array, keysToRemove) {
|
|
3989
4139
|
_lodash["default"].forEach(array, function (obj, index) {
|
|
3990
|
-
var filtered = Object.fromEntries(Object.entries(obj).filter(function (
|
|
3991
|
-
var
|
|
3992
|
-
key =
|
|
4140
|
+
var filtered = Object.fromEntries(Object.entries(obj).filter(function (_ref8) {
|
|
4141
|
+
var _ref9 = (0, _slicedToArray2["default"])(_ref8, 1),
|
|
4142
|
+
key = _ref9[0];
|
|
3993
4143
|
return !keysToRemove.includes(key);
|
|
3994
4144
|
}));
|
|
3995
4145
|
// 原地替換每個 object 的 key
|
|
@@ -4016,9 +4166,9 @@ var Utiller = /*#__PURE__*/function () {
|
|
|
4016
4166
|
key: "removeKeysFromArrayObjects",
|
|
4017
4167
|
value: function removeKeysFromArrayObjects(array, keysToRemove) {
|
|
4018
4168
|
return _lodash["default"].map(array, function (obj) {
|
|
4019
|
-
return Object.fromEntries(Object.entries(obj).filter(function (
|
|
4020
|
-
var
|
|
4021
|
-
key =
|
|
4169
|
+
return Object.fromEntries(Object.entries(obj).filter(function (_ref10) {
|
|
4170
|
+
var _ref11 = (0, _slicedToArray2["default"])(_ref10, 1),
|
|
4171
|
+
key = _ref11[0];
|
|
4022
4172
|
return !keysToRemove.includes(key);
|
|
4023
4173
|
}));
|
|
4024
4174
|
});
|
|
@@ -4077,10 +4227,10 @@ var Utiller = /*#__PURE__*/function () {
|
|
|
4077
4227
|
var predict = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (attr) {
|
|
4078
4228
|
return attr.checked !== true;
|
|
4079
4229
|
};
|
|
4080
|
-
return _lodash["default"].fromPairs(_lodash["default"].toPairs(obj).filter(function (
|
|
4081
|
-
var
|
|
4082
|
-
_ =
|
|
4083
|
-
value =
|
|
4230
|
+
return _lodash["default"].fromPairs(_lodash["default"].toPairs(obj).filter(function (_ref12) {
|
|
4231
|
+
var _ref13 = (0, _slicedToArray2["default"])(_ref12, 2),
|
|
4232
|
+
_ = _ref13[0],
|
|
4233
|
+
value = _ref13[1];
|
|
4084
4234
|
return predict(value);
|
|
4085
4235
|
}));
|
|
4086
4236
|
}
|
|
@@ -4276,9 +4426,9 @@ var Utiller = /*#__PURE__*/function () {
|
|
|
4276
4426
|
}, {
|
|
4277
4427
|
key: "getTSOfSpecificDate",
|
|
4278
4428
|
value: function getTSOfSpecificDate(dateStr) {
|
|
4279
|
-
var
|
|
4280
|
-
|
|
4281
|
-
end =
|
|
4429
|
+
var _ref14 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
4430
|
+
_ref14$end = _ref14.end,
|
|
4431
|
+
end = _ref14$end === void 0 ? false : _ref14$end;
|
|
4282
4432
|
return Number((0, _lodash["default"])(dateStr).thru(function (str) {
|
|
4283
4433
|
return (0, _momentTimezone["default"])(str.split("(")[0], "YYYY/MM/DD");
|
|
4284
4434
|
}).thru(function (m) {
|
|
@@ -4439,15 +4589,117 @@ var Utiller = /*#__PURE__*/function () {
|
|
|
4439
4589
|
array.length = 0;
|
|
4440
4590
|
|
|
4441
4591
|
// 重建結構
|
|
4442
|
-
Object.entries(resultMap).forEach(function (
|
|
4443
|
-
var
|
|
4444
|
-
key =
|
|
4445
|
-
value =
|
|
4592
|
+
Object.entries(resultMap).forEach(function (_ref15) {
|
|
4593
|
+
var _ref16 = (0, _slicedToArray2["default"])(_ref15, 2),
|
|
4594
|
+
key = _ref16[0],
|
|
4595
|
+
value = _ref16[1];
|
|
4446
4596
|
array.push((0, _defineProperty2["default"])({}, key, value));
|
|
4447
4597
|
});
|
|
4448
4598
|
return array;
|
|
4449
4599
|
}
|
|
4450
4600
|
|
|
4601
|
+
/**
|
|
4602
|
+
* 將時間字串解析為物件,回傳 {startDate, startTime, endDate, endTime}
|
|
4603
|
+
*
|
|
4604
|
+
* 支援格式:
|
|
4605
|
+
* 1. '2025/11/10 (一)|13:00-15:00'
|
|
4606
|
+
* => { startDate:'2025/11/10', startTime:'13:00', endDate:'2025/11/10', endTime:'15:00' }
|
|
4607
|
+
*
|
|
4608
|
+
* 2. '2025/11/10 (一) 13:00 - 2025/11/12 (三) 15:00'
|
|
4609
|
+
* => { startDate:'2025/11/10', startTime:'13:00', endDate:'2025/11/12', endTime:'15:00' }
|
|
4610
|
+
*
|
|
4611
|
+
* @param {string} input - 欲解析的時間字串
|
|
4612
|
+
* @returns {{startDate: string, startTime: string, endDate: string, endTime: string}} 解析後的時間物件
|
|
4613
|
+
*
|
|
4614
|
+
* @example
|
|
4615
|
+
* getObjectOfStartEndDateTime('2025/11/10 (一)|13:00-15:00');
|
|
4616
|
+
* // => { startDate:'2025/11/10', startTime:'13:00', endDate:'2025/11/10', endTime:'15:00' }
|
|
4617
|
+
*
|
|
4618
|
+
* @example
|
|
4619
|
+
* getObjectOfStartEndDateTime('2025/11/10 (一) 13:00 - 2025/11/12 (三) 15:00');
|
|
4620
|
+
* // => { startDate:'2025/11/10', startTime:'13:00', endDate:'2025/11/12', endTime:'15:00' }
|
|
4621
|
+
*/
|
|
4622
|
+
}, {
|
|
4623
|
+
key: "getObjectOfStartEndDateTime",
|
|
4624
|
+
value: function getObjectOfStartEndDateTime(input) {
|
|
4625
|
+
if (!input || typeof input !== "string") {
|
|
4626
|
+
return {
|
|
4627
|
+
startDate: "",
|
|
4628
|
+
startTime: "",
|
|
4629
|
+
endDate: "",
|
|
4630
|
+
endTime: ""
|
|
4631
|
+
};
|
|
4632
|
+
}
|
|
4633
|
+
|
|
4634
|
+
// 將全形符號與多餘空白轉換為標準形式
|
|
4635
|
+
var cleaned = input.replace(/|/g, " ").replace(/-/g, "-") // 全形破折號轉半形
|
|
4636
|
+
.replace(/\s+/g, " ").trim();
|
|
4637
|
+
|
|
4638
|
+
// 跨日期格式 (例:2025/11/10 13:00 - 2025/11/12 15:00)
|
|
4639
|
+
var crossDatePattern = /(\d{4}\/\d{1,2}\/\d{1,2})(?:\s*\([^)]*\))?\s*(\d{2}:\d{2})\s*-\s*(\d{4}\/\d{1,2}\/\d{1,2})(?:\s*\([^)]*\))?\s*(\d{2}:\d{2})/;
|
|
4640
|
+
|
|
4641
|
+
// 同日期格式 (例:2025/11/10 13:00 - 15:00)
|
|
4642
|
+
var sameDatePattern = /(\d{4}\/\d{1,2}\/\d{1,2})(?:\s*\([^)]*\))?\s*(\d{2}:\d{2})\s*-\s*(\d{2}:\d{2})/;
|
|
4643
|
+
var startDate, startTime, endDate, endTime;
|
|
4644
|
+
if (crossDatePattern.test(cleaned)) {
|
|
4645
|
+
var _cleaned$match = cleaned.match(crossDatePattern);
|
|
4646
|
+
var _cleaned$match2 = (0, _slicedToArray2["default"])(_cleaned$match, 5);
|
|
4647
|
+
startDate = _cleaned$match2[1];
|
|
4648
|
+
startTime = _cleaned$match2[2];
|
|
4649
|
+
endDate = _cleaned$match2[3];
|
|
4650
|
+
endTime = _cleaned$match2[4];
|
|
4651
|
+
} else if (sameDatePattern.test(cleaned)) {
|
|
4652
|
+
var _cleaned$match3 = cleaned.match(sameDatePattern);
|
|
4653
|
+
var _cleaned$match4 = (0, _slicedToArray2["default"])(_cleaned$match3, 4);
|
|
4654
|
+
startDate = _cleaned$match4[1];
|
|
4655
|
+
startTime = _cleaned$match4[2];
|
|
4656
|
+
endTime = _cleaned$match4[3];
|
|
4657
|
+
endDate = startDate;
|
|
4658
|
+
} else {
|
|
4659
|
+
return {
|
|
4660
|
+
startDate: "",
|
|
4661
|
+
startTime: "",
|
|
4662
|
+
endDate: "",
|
|
4663
|
+
endTime: ""
|
|
4664
|
+
};
|
|
4665
|
+
}
|
|
4666
|
+
|
|
4667
|
+
// 將日期時間轉為可比較的 Date 物件
|
|
4668
|
+
var start = new Date("".concat(startDate, " ").concat(startTime));
|
|
4669
|
+
var end = new Date("".concat(endDate, " ").concat(endTime));
|
|
4670
|
+
if (end < start) {
|
|
4671
|
+
throw new Error("End time cannot be earlier than start time: ".concat(input));
|
|
4672
|
+
}
|
|
4673
|
+
return {
|
|
4674
|
+
startDate: startDate,
|
|
4675
|
+
startTime: startTime,
|
|
4676
|
+
endDate: endDate,
|
|
4677
|
+
endTime: endTime
|
|
4678
|
+
};
|
|
4679
|
+
}
|
|
4680
|
+
}, {
|
|
4681
|
+
key: "getFilteredHeraPeriods",
|
|
4682
|
+
value:
|
|
4683
|
+
// 範例用法 (請確保 moment.js 已載入)
|
|
4684
|
+
/*
|
|
4685
|
+
const myEvent = {
|
|
4686
|
+
title: '吉他課 (Moment.js)',
|
|
4687
|
+
startDate: '2026/01/15', // 使用新的 YYYY/MM/DD 格式
|
|
4688
|
+
startTime: '10:30',
|
|
4689
|
+
endDate: '2026/01/15',
|
|
4690
|
+
endTime: '12:00',
|
|
4691
|
+
location: '新北市板橋區縣民大道一段 1 號',
|
|
4692
|
+
details: 'Moment.js 測試:請記得帶譜架。'
|
|
4693
|
+
};
|
|
4694
|
+
if (typeof moment !== 'undefined') {
|
|
4695
|
+
const links = generateAllCalendarLinks(myEvent);
|
|
4696
|
+
console.log('--- 使用 Moment.js 生成的連結 ---');
|
|
4697
|
+
console.log(links);
|
|
4698
|
+
} else {
|
|
4699
|
+
console.warn('moment.js 函式庫未載入,無法執行。');
|
|
4700
|
+
}
|
|
4701
|
+
*/
|
|
4702
|
+
|
|
4451
4703
|
/** ============== 排課系統公式 開始 ============== */
|
|
4452
4704
|
|
|
4453
4705
|
/**
|
|
@@ -4465,9 +4717,7 @@ var Utiller = /*#__PURE__*/function () {
|
|
|
4465
4717
|
* 2. idOfBooze和idOfVariant為PK, 重複的只保留一組
|
|
4466
4718
|
* 3. 回傳filter array,(反查出哪些課程重複會用到其他資訊)
|
|
4467
4719
|
* */
|
|
4468
|
-
|
|
4469
|
-
key: "getFilteredHeraPeriods",
|
|
4470
|
-
value: function getFilteredHeraPeriods(arr, idOfCurrentBooze) {
|
|
4720
|
+
function getFilteredHeraPeriods(arr, idOfCurrentBooze) {
|
|
4471
4721
|
return _lodash["default"].chain(arr)
|
|
4472
4722
|
// 1️⃣ 刪掉 idOfBooze 等於目標值的項目
|
|
4473
4723
|
.filter(function (item) {
|
package/package.json
CHANGED