yz-yuki-plugin 1.0.2-rc.7 → 1.0.3

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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # 1.0.3
2
+ * 修复群组与好友动态推送混淆问题
3
+ * 更新获取B站up信息api
4
+ * 优化动态字体样式
5
+ * 优化文字动态内容排版
6
+ * 修复转发动态内容缺失
7
+
1
8
  # 1.0.2
2
9
  * 新增支持获取完整文章动态内容
3
10
  * 修复宫格样式
@@ -8,11 +8,13 @@ import { BiliQuery } from './bilibili.query.js';
8
8
 
9
9
  class BiliTask {
10
10
  taskName;
11
- key;
11
+ groupKey;
12
+ privateKey;
12
13
  e;
13
14
  constructor(e) {
14
15
  this.taskName = "biliTask";
15
- this.key = "Yz:yuki:bili:upPush:";
16
+ this.groupKey = "Yz:yuki:bili:upPush:group:";
17
+ this.privateKey = "Yz:yuki:bili:upPush:private:";
16
18
  }
17
19
  async hendleEventDynamicData(uid, count = 0) {
18
20
  const resp = await new BiliGetWebData().getBiliDynamicListDataByUid(uid);
@@ -50,6 +52,10 @@ class BiliTask {
50
52
  }
51
53
  async processBiliData(biliPushData, uidMap, dynamicList, lastLiveStatus) {
52
54
  for (let chatType in biliPushData) {
55
+ if (!uidMap.has(chatType)) {
56
+ uidMap.set(chatType, new Map());
57
+ }
58
+ const chatTypeMap = uidMap.get(chatType);
53
59
  for (let chatId in biliPushData[chatType]) {
54
60
  const subUpsOfChat = biliPushData[chatType][chatId] || [];
55
61
  for (let subInfoOfup of subUpsOfChat) {
@@ -75,46 +81,48 @@ class BiliTask {
75
81
  logger.error(`获取 ${subInfoOfup.uid} 动态失败,resp 为空`);
76
82
  return;
77
83
  }
78
- const chatIds = Array.from(new Set([...Object((uidMap.get(subInfoOfup.uid) && uidMap.get(subInfoOfup.uid).chatIds) || []), chatId]));
84
+ const chatIds = Array.from(new Set([...Object((chatTypeMap.get(subInfoOfup.uid) && chatTypeMap.get(subInfoOfup.uid).chatIds) || []), chatId]));
79
85
  const bot_id = subInfoOfup.bot_id || [];
80
86
  const { name, type } = subInfoOfup;
81
- uidMap.set(subInfoOfup.uid, { chatIds, bot_id, upName: name, type, chatType });
87
+ chatTypeMap.set(subInfoOfup.uid, { chatIds, bot_id, upName: name, type });
82
88
  await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (8000 - 2000 + 1) + 2000)));
83
89
  }
84
90
  }
85
91
  }
86
92
  }
87
93
  async pushDynamicMessages(uidMap, dynamicList, now, interval, biliConfigData) {
88
- for (let [key, value] of uidMap) {
89
- const tempDynamicList = dynamicList[key] || [];
90
- const willPushDynamicList = [];
91
- const printedList = new Set();
92
- for (let dynamicItem of tempDynamicList) {
93
- let author = dynamicItem?.modules?.module_author || {};
94
- if (!printedList.has(author?.mid)) {
95
- logger.info(`正在检测B站动态 [ ${author?.name} : ${author?.mid} ]`);
96
- printedList.add(author?.mid);
97
- }
98
- if (!author?.pub_ts)
99
- continue;
100
- if (Number(now - author.pub_ts) > interval) {
101
- logger.debug(`超过间隔,跳过 [ ${author?.name} : ${author?.mid} ] ${author?.pub_time} 的动态`);
102
- continue;
94
+ for (let [chatType, chatTypeMap] of uidMap) {
95
+ for (let [key, value] of chatTypeMap) {
96
+ const tempDynamicList = dynamicList[key] || [];
97
+ const willPushDynamicList = [];
98
+ const printedList = new Set();
99
+ for (let dynamicItem of tempDynamicList) {
100
+ let author = dynamicItem?.modules?.module_author || {};
101
+ if (!printedList.has(author?.mid)) {
102
+ logger.info(`正在检测B站动态 [ ${author?.name} : ${author?.mid} ]`);
103
+ printedList.add(author?.mid);
104
+ }
105
+ if (!author?.pub_ts)
106
+ continue;
107
+ if (Number(now - author.pub_ts) > interval) {
108
+ logger.debug(`超过间隔,跳过 [ ${author?.name} : ${author?.mid} ] ${author?.pub_time} 的动态`);
109
+ continue;
110
+ }
111
+ if (dynamicItem.type === "DYNAMIC_TYPE_FORWARD" && !biliConfigData.pushTransmit)
112
+ continue;
113
+ willPushDynamicList.push(dynamicItem);
103
114
  }
104
- if (dynamicItem.type === "DYNAMIC_TYPE_FORWARD" && !biliConfigData.pushTransmit)
105
- continue;
106
- willPushDynamicList.push(dynamicItem);
107
- }
108
- printedList.clear();
109
- const pushMapInfo = value || {};
110
- const { chatIds, bot_id, upName, type, chatType } = pushMapInfo;
111
- for (let pushDynamicData of willPushDynamicList) {
112
- if (chatIds && chatIds.length) {
113
- for (let chatId of chatIds) {
114
- if (type && type.length && !type.includes(pushDynamicData.type))
115
- continue;
116
- await this.sendDynamic(chatId, bot_id, upName, pushDynamicData, biliConfigData, chatType);
117
- await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (6500 - 2000 + 1) + 2000)));
115
+ printedList.clear();
116
+ const pushMapInfo = value || {};
117
+ const { chatIds, bot_id, upName, type } = pushMapInfo;
118
+ for (let pushDynamicData of willPushDynamicList) {
119
+ if (chatIds && chatIds.length) {
120
+ for (let chatId of chatIds) {
121
+ if (type && type.length && !type.includes(pushDynamicData.type))
122
+ continue;
123
+ await this.sendDynamic(chatId, bot_id, upName, pushDynamicData, biliConfigData, chatType);
124
+ await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * (6500 - 2000 + 1) + 2000)));
125
+ }
118
126
  }
119
127
  }
120
128
  }
@@ -122,7 +130,15 @@ class BiliTask {
122
130
  }
123
131
  async sendDynamic(chatId, bot_id, upName, pushDynamicData, biliConfigData, chatType) {
124
132
  const id_str = pushDynamicData.id_str;
125
- let sended = await Redis.get(`${this.key}${chatId}:${id_str}`);
133
+ let sended, markKey;
134
+ if (chatType === "group") {
135
+ markKey = this.groupKey;
136
+ sended = await Redis.get(`${markKey}${chatId}:${id_str}`);
137
+ }
138
+ else if (chatType === "private") {
139
+ markKey = this.privateKey;
140
+ sended = await Redis.get(`${markKey}${chatId}:${id_str}`);
141
+ }
126
142
  if (sended)
127
143
  return;
128
144
  if (!!biliConfigData.pushMsgMode) {
@@ -152,7 +168,7 @@ class BiliTask {
152
168
  let imgs = await this.renderDynamicCard(uid, renderData, ScreenshotOptionsData);
153
169
  if (!imgs)
154
170
  return;
155
- Redis.set(`${this.key}${chatId}:${id_str}`, "1", { EX: 3600 * 10 });
171
+ Redis.set(`${markKey}${chatId}:${id_str}`, "1", { EX: 3600 * 10 });
156
172
  (logger ?? Bot.logger)?.mark("优纪插件:B站动态执行推送");
157
173
  for (let i = 0; i < imgs.length; i++) {
158
174
  const image = imgs[i];
@@ -163,7 +179,7 @@ class BiliTask {
163
179
  }
164
180
  else {
165
181
  const dynamicMsg = await BiliQuery.formatTextDynamicData(upName, pushDynamicData, false, biliConfigData);
166
- Redis.set(`${this.key}${chatId}:${id_str}`, "1", { EX: 3600 * 10 });
182
+ Redis.set(`${markKey}${chatId}:${id_str}`, "1", { EX: 3600 * 10 });
167
183
  if (dynamicMsg == "continue") {
168
184
  return "return";
169
185
  }
@@ -247,7 +263,7 @@ class BiliTask {
247
263
  });
248
264
  }
249
265
  else if (chatType === "private") {
250
- await (Bot[bot_id] ?? Bot)?.pickUser(String(chatId)).sendMsg(message)
266
+ await (Bot[bot_id] ?? Bot)?.pickFriend(String(chatId)).sendMsg(message)
251
267
  .catch((error) => {
252
268
  (logger ?? Bot.logger)?.error(`用户[${chatId}]推送失败:${JSON.stringify(error)}`);
253
269
  });
@@ -7,11 +7,13 @@ import { WeiboQuery } from './weibo.query.js';
7
7
 
8
8
  class WeiboTask {
9
9
  taskName;
10
- key;
10
+ groupKey;
11
+ privateKey;
11
12
  e;
12
13
  constructor(e) {
13
14
  this.taskName = "weiboTask";
14
- this.key = "Yz:yuki:weibo:upPush:";
15
+ this.groupKey = "Yz:yuki:weibo:upPush:group:";
16
+ this.privateKey = "Yz:yuki:weibo:upPush:private:";
15
17
  }
16
18
  async runTask() {
17
19
  let weiboConfigData = await Config.getUserConfig("weibo", "config");
@@ -25,6 +27,10 @@ class WeiboTask {
25
27
  }
26
28
  async processWeiboData(weiboPushData, uidMap, dynamicList) {
27
29
  for (let chatType in weiboPushData) {
30
+ if (!uidMap.has(chatType)) {
31
+ uidMap.set(chatType, new Map());
32
+ }
33
+ const chatTypeMap = uidMap.get(chatType);
28
34
  for (let chatId in weiboPushData[chatType]) {
29
35
  const subUpsOfChat = weiboPushData[chatType][chatId] || [];
30
36
  for (let subInfoOfup of subUpsOfChat) {
@@ -33,47 +39,49 @@ class WeiboTask {
33
39
  const dynamicData = resp || [];
34
40
  dynamicList[subInfoOfup.uid] = dynamicData;
35
41
  }
36
- const chatIds = Array.from(new Set([...Object((uidMap.get(subInfoOfup.uid) && uidMap.get(subInfoOfup.uid).chatIds) || []), chatId]));
42
+ const chatIds = Array.from(new Set([...Object((chatTypeMap.get(subInfoOfup.uid) && chatTypeMap.get(subInfoOfup.uid).chatIds) || []), chatId]));
37
43
  const bot_id = subInfoOfup.bot_id || [];
38
44
  const { name, type } = subInfoOfup;
39
- uidMap.set(subInfoOfup.uid, { chatIds, bot_id, upName: name, type, chatType });
45
+ chatTypeMap.set(subInfoOfup.uid, { chatIds, bot_id, upName: name, type });
40
46
  await this.randomDelay(1000, 4000);
41
47
  }
42
48
  }
43
49
  }
44
50
  }
45
51
  async pushDynamicMessages(uidMap, dynamicList, now, interval, weiboConfigData) {
46
- for (let [key, value] of uidMap) {
47
- const tempDynamicList = dynamicList[key] || [];
48
- const willPushDynamicList = [];
49
- const printedList = new Set();
50
- for (let dynamicItem of tempDynamicList) {
51
- let raw_post = dynamicItem || {};
52
- let user = raw_post?.mblog?.user || {};
53
- if (!printedList.has(user?.id)) {
54
- logger.info(`正在检测微博动态 [ ${user?.screen_name} : ${user?.id} ]`);
55
- printedList.add(user?.id);
56
- }
57
- if (!raw_post?.mblog?.created_at)
58
- continue;
59
- if (Number(now - (WeiboQuery.getDynamicCreatetDate(raw_post) / 1000)) > interval) {
60
- logger.debug(`超过间隔,跳过 [ ${user?.screen_name} : ${user?.id} ] ${raw_post?.mblog?.created_at} 的动态`);
61
- continue;
52
+ for (let [chatType, chatTypeMap] of uidMap) {
53
+ for (let [key, value] of chatTypeMap) {
54
+ const tempDynamicList = dynamicList[key] || [];
55
+ const willPushDynamicList = [];
56
+ const printedList = new Set();
57
+ for (let dynamicItem of tempDynamicList) {
58
+ let raw_post = dynamicItem || {};
59
+ let user = raw_post?.mblog?.user || {};
60
+ if (!printedList.has(user?.id)) {
61
+ logger.info(`正在检测微博动态 [ ${user?.screen_name} : ${user?.id} ]`);
62
+ printedList.add(user?.id);
63
+ }
64
+ if (!raw_post?.mblog?.created_at)
65
+ continue;
66
+ if (Number(now - (WeiboQuery.getDynamicCreatetDate(raw_post) / 1000)) > interval) {
67
+ logger.debug(`超过间隔,跳过 [ ${user?.screen_name} : ${user?.id} ] ${raw_post?.mblog?.created_at} 的动态`);
68
+ continue;
69
+ }
70
+ if (dynamicItem.type === "DYNAMIC_TYPE_FORWARD" && !weiboConfigData.pushTransmit)
71
+ continue;
72
+ willPushDynamicList.push(dynamicItem);
62
73
  }
63
- if (dynamicItem.type === "DYNAMIC_TYPE_FORWARD" && !weiboConfigData.pushTransmit)
64
- continue;
65
- willPushDynamicList.push(dynamicItem);
66
- }
67
- printedList.clear();
68
- const pushMapInfo = value || {};
69
- const { chatIds, bot_id, upName, type, chatType } = pushMapInfo;
70
- for (let pushDynamicData of willPushDynamicList) {
71
- if (chatIds && chatIds.length) {
72
- for (let chatId of chatIds) {
73
- if (type && type.length && !type.includes(pushDynamicData.type))
74
- continue;
75
- await this.sendDynamic(chatId, bot_id, upName, pushDynamicData, weiboConfigData, chatType);
76
- await this.randomDelay(2000, 10500);
74
+ printedList.clear();
75
+ const pushMapInfo = value || {};
76
+ const { chatIds, bot_id, upName, type } = pushMapInfo;
77
+ for (let pushDynamicData of willPushDynamicList) {
78
+ if (chatIds && chatIds.length) {
79
+ for (let chatId of chatIds) {
80
+ if (type && type.length && !type.includes(pushDynamicData.type))
81
+ continue;
82
+ await this.sendDynamic(chatId, bot_id, upName, pushDynamicData, weiboConfigData, chatType);
83
+ await this.randomDelay(2000, 10500);
84
+ }
77
85
  }
78
86
  }
79
87
  }
@@ -81,7 +89,15 @@ class WeiboTask {
81
89
  }
82
90
  async sendDynamic(chatId, bot_id, upName, pushDynamicData, weiboConfigData, chatType) {
83
91
  const id_str = WeiboQuery.getDynamicId(pushDynamicData);
84
- let sended = await Redis.get(`${this.key}${chatId}:${id_str}`);
92
+ let sended, markKey;
93
+ if (chatType === "group") {
94
+ markKey = this.groupKey;
95
+ sended = await Redis.get(`${markKey}${chatId}:${id_str}`);
96
+ }
97
+ else if (chatType === "private") {
98
+ markKey = this.privateKey;
99
+ sended = await Redis.get(`${markKey}${chatId}:${id_str}`);
100
+ }
85
101
  if (sended)
86
102
  return;
87
103
  if (!!weiboConfigData.pushMsgMode) {
@@ -111,7 +127,7 @@ class WeiboTask {
111
127
  let imgs = await this.renderDynamicCard(uid, renderData, ScreenshotOptionsData);
112
128
  if (!imgs)
113
129
  return;
114
- Redis.set(`${this.key}${chatId}:${id_str}`, "1", { EX: 3600 * 10 });
130
+ Redis.set(`${markKey}${chatId}:${id_str}`, "1", { EX: 3600 * 10 });
115
131
  (logger ?? Bot.logger)?.mark("优纪插件:B站动态执行推送");
116
132
  for (let i = 0; i < imgs.length; i++) {
117
133
  const image = imgs[i];
@@ -122,7 +138,7 @@ class WeiboTask {
122
138
  }
123
139
  else {
124
140
  const dynamicMsg = await WeiboQuery.formatTextDynamicData(upName, pushDynamicData, false, weiboConfigData);
125
- Redis.set(`${this.key}${chatId}:${id_str}`, "1", { EX: 3600 * 10 });
141
+ Redis.set(`${markKey}${chatId}:${id_str}`, "1", { EX: 3600 * 10 });
126
142
  if (dynamicMsg == "continue" || dynamicMsg == false) {
127
143
  return "return";
128
144
  }
@@ -206,7 +222,7 @@ class WeiboTask {
206
222
  });
207
223
  }
208
224
  else if (chatType === "private") {
209
- await (Bot[bot_id] ?? Bot)?.pickUser(String(chatId)).sendMsg(message)
225
+ await (Bot[bot_id] ?? Bot)?.pickFriend(String(chatId)).sendMsg(message)
210
226
  .catch((error) => {
211
227
  (logger ?? Bot.logger)?.error(`用户[${chatId}]推送失败:${JSON.stringify(error)}`);
212
228
  });
@@ -3,13 +3,14 @@ import { MainProps } from "../../components/dynamic/MainPage";
3
3
  import { ScreenshotOptions } from './../../utils/puppeteer.render';
4
4
  export declare class BiliTask {
5
5
  taskName: string;
6
- key: string;
6
+ groupKey: string;
7
+ privateKey: string;
7
8
  e?: EventType;
8
9
  constructor(e?: EventType);
9
10
  hendleEventDynamicData(uid: string | number, count?: number): Promise<any>;
10
11
  runTask(): Promise<void>;
11
- processBiliData(biliPushData: any, uidMap: Map<any, any>, dynamicList: any, lastLiveStatus: any): Promise<void>;
12
- pushDynamicMessages(uidMap: Map<any, any>, dynamicList: any, now: number, interval: number, biliConfigData: any): Promise<void>;
12
+ processBiliData(biliPushData: any, uidMap: Map<any, Map<string, any>>, dynamicList: any, lastLiveStatus: any): Promise<void>;
13
+ pushDynamicMessages(uidMap: Map<any, Map<string, any>>, dynamicList: any, now: number, interval: number, biliConfigData: any): Promise<void>;
13
14
  sendDynamic(chatId: string | number, bot_id: string | number, upName: string, pushDynamicData: any, biliConfigData: any, chatType: string): Promise<string>;
14
15
  buildRenderData(extentData: any, urlQrcodeData: string, boxGrid: boolean): MainProps;
15
16
  renderDynamicCard(uid: string, renderData: MainProps, ScreenshotOptionsData: ScreenshotOptions): Promise<Buffer[] | null>;
@@ -3,12 +3,13 @@ import { MainProps } from "../../components/dynamic/MainPage";
3
3
  import { ScreenshotOptions } from '../../utils/puppeteer.render';
4
4
  export declare class WeiboTask {
5
5
  taskName: string;
6
- key: string;
6
+ groupKey: string;
7
+ privateKey: string;
7
8
  e?: EventType;
8
9
  constructor(e?: any);
9
10
  runTask(): Promise<void>;
10
- processWeiboData(weiboPushData: any, uidMap: Map<any, any>, dynamicList: any): Promise<void>;
11
- pushDynamicMessages(uidMap: Map<any, any>, dynamicList: any, now: number, interval: number, weiboConfigData: any): Promise<void>;
11
+ processWeiboData(weiboPushData: any, uidMap: Map<any, Map<string, any>>, dynamicList: any): Promise<void>;
12
+ pushDynamicMessages(uidMap: Map<any, Map<string, any>>, dynamicList: any, now: number, interval: number, weiboConfigData: any): Promise<void>;
12
13
  sendDynamic(chatId: string | number, bot_id: string | number, upName: string, pushDynamicData: any, weiboConfigData: any, chatType: string): Promise<string>;
13
14
  buildRenderData(extentData: any, urlQrcodeData: string, boxGrid: boolean): MainProps;
14
15
  renderDynamicCard(uid: string | number, renderData: MainProps, ScreenshotOptionsData: ScreenshotOptions): Promise<Buffer[] | null>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yz-yuki-plugin",
3
- "version": "1.0.2-rc.7",
3
+ "version": "1.0.3",
4
4
  "description": "优纪插件,yunzaijs 关于 微博推送、B站推送 等功能的拓展插件",
5
5
  "author": "snowtafir",
6
6
  "type": "module",
package/public/output.css CHANGED
@@ -1 +1 @@
1
- /*! tailwindcss v3.4.9 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.m-auto{margin:auto}.mb-3{margin-bottom:.75rem}.ml-7{margin-left:1.75rem}.mt-3{margin-top:.75rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-72{height:18rem}.max-h-96{max-height:24rem}.w-32{width:8rem}.w-72{width:18rem}.w-96{width:24rem}.p-1{padding:.25rem}.p-5{padding:1.25rem}.text-center{text-align:center}.text-lg{font-size:1.125rem;line-height:1.75rem}.italic{font-style:italic}.text-blue-500{--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}
1
+ /*! tailwindcss v3.4.10 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.m-auto{margin:auto}.mb-3{margin-bottom:.75rem}.ml-7{margin-left:1.75rem}.mt-3{margin-top:.75rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-72{height:18rem}.max-h-96{max-height:24rem}.w-32{width:8rem}.w-72{width:18rem}.w-96{width:24rem}.p-1{padding:.25rem}.p-5{padding:1.25rem}.text-center{text-align:center}.text-lg{font-size:1.125rem;line-height:1.75rem}.italic{font-style:italic}.text-blue-500{--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}