@azuro-org/images-generator 2.0.2 → 2.0.4

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.
@@ -4,12 +4,27 @@ interface GeneratorOptions {
4
4
  timeout?: number;
5
5
  args?: string[];
6
6
  }
7
+ /**
8
+ * Options for a single image generation.
9
+ */
7
10
  interface GenerateOptions {
11
+ /** JPEG quality 1–100 (ignored for PNG). Default 85. */
8
12
  quality?: number;
13
+ /** Screenshot the full scrollable page instead of just the viewport. Default false. */
9
14
  fullPage?: boolean;
15
+ /** Wait for document.fonts.ready before taking the screenshot so webfonts are applied. Default true. */
10
16
  waitForFonts?: boolean;
17
+ /** Max ms to wait for content/font loading. Default 2000. */
11
18
  waitTimeout?: number;
19
+ /**
20
+ * When to consider the page content "loaded" before screenshot.
21
+ * - `domcontentloaded` – DOM ready, resources (images, fonts) may still load. Fastest. Default.
22
+ * - `load` – load event fired (images, stylesheets, etc. loaded).
23
+ * - `networkidle0` – no network requests for 500ms.
24
+ * - `networkidle2` – at most 2 network requests for 500ms.
25
+ */
12
26
  waitUntil?: 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2';
27
+ /** If true, do not add an extra delay for CSS animations. Default true. */
13
28
  skipAnimations?: boolean;
14
29
  }
15
30
  type GenerateProps<P> = {
package/dist/index.es.js CHANGED
@@ -180,7 +180,7 @@ function __generator(thisArg, body) {
180
180
  throw new Error('Invalid template: missing required properties');
181
181
  }
182
182
  width = template.width, height = template.height, type = template.type, getHtml = template.html;
183
- _d = options.quality, quality = _d === void 0 ? type === 'jpeg' ? 85 : undefined : _d, _e = options.fullPage, fullPage = _e === void 0 ? false : _e, _f = options.waitForFonts, waitForFonts = _f === void 0 ? true : _f, _g = options.waitTimeout, waitTimeout = _g === void 0 ? 2000 : _g, _h = options.waitUntil, waitUntil = _h === void 0 ? 'domcontentloaded' : _h, _j = options.skipAnimations, skipAnimations = _j === void 0 ? true : _j;
183
+ _d = options.quality, quality = _d === void 0 ? type === 'jpeg' ? 85 : undefined : _d, _e = options.fullPage, fullPage = _e === void 0 ? false : _e, _f = options.waitForFonts, waitForFonts = _f === void 0 ? true : _f, _g = options.waitTimeout, waitTimeout = _g === void 0 ? 2000 : _g, _h = options.waitUntil, waitUntil = _h === void 0 ? 'load' : _h, _j = options.skipAnimations, skipAnimations = _j === void 0 ? true : _j;
184
184
  _l.label = 7;
185
185
  case 7:
186
186
  _l.trys.push([7, 20, , 21]);
@@ -1,5 +1,6 @@
1
1
  import { type Template } from '../../utils';
2
2
  export type Props = {
3
+ accountAddress: string;
3
4
  trend: {
4
5
  image: string | undefined;
5
6
  title: string;
@@ -7,8 +8,8 @@ export type Props = {
7
8
  position: {
8
9
  leverage: number;
9
10
  isLong: boolean;
10
- openLevel: number;
11
- exitLevel: number | undefined;
11
+ openLevel: string;
12
+ exitLevel: string | undefined;
12
13
  };
13
14
  pnl: number;
14
15
  };
@@ -7,7 +7,7 @@
7
7
  <link rel="preconnect" href="https://fonts.googleapis.com">
8
8
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
9
  <link
10
- href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@100..900&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Mona+Sans:ital,wdth,wght@0,125,200..900;1,125,200..900&display=swap"
10
+ href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;700&family=Inter:wght@500;600&family=Mona+Sans:wdth,wght@125,700&display=swap"
11
11
  rel="stylesheet">
12
12
  <style>
13
13
  html {
@@ -157,6 +157,7 @@
157
157
  height: 675px;
158
158
  padding: 40px 36px 30px;
159
159
  position: relative;
160
+ color: white;
160
161
  }
161
162
 
162
163
  .logo {
@@ -166,42 +167,12 @@
166
167
  margin-right: 45px;
167
168
  }
168
169
 
169
- .trend {
170
- /* margin-top: 108px; */
171
- }
172
-
173
- .trend__img {
174
- margin-right: 20px;
175
- width: 80px;
176
- height: 80px;
177
- border-radius: 100%;
178
- overflow: hidden;
179
- }
180
-
181
- .trend__img>img {
182
- width: 100%;
183
- }
184
-
185
- .trend__title {
186
- font-size: 32px;
187
- line-height: 100%;
188
- }
189
-
190
- .trend__badge {
191
- background-color: rgba(0, 0, 0, 0.2);
192
- padding: 6px 12px 8px 8px;
193
- border-radius: 5px;
194
- font-size: 24px;
195
- line-height: 100%;
196
- margin-top: 10px;
197
- width: fit-content;
198
- }
199
-
200
170
  .pnl {
201
- margin-top: 22px;
202
- font-size: 120px;
203
- line-height: 100%;
171
+ font-size: 72px;
172
+ line-height: 90%;
204
173
  font-weight: 700;
174
+ font-stretch: 125%;
175
+ color: --card-bg-color;
205
176
  }
206
177
 
207
178
  .right-img {
@@ -214,8 +185,10 @@
214
185
  .arrow {
215
186
  width: 24px;
216
187
  height: 24px;
217
- margin-top: 3px;
218
- margin-bottom: -3px;
188
+ margin-top: -4px;
189
+ margin-bottom: -4px;
190
+ margin-right: -4px;
191
+ margin-left: -6px;
219
192
  }
220
193
 
221
194
  .person-img {
@@ -226,44 +199,74 @@
226
199
  mix-blend-mode: multiply;
227
200
  }
228
201
 
229
- .bg-img {
230
- position: absolute;
231
- top: 0px;
232
- left: 0px;
233
- width: 100%;
202
+ .box {
203
+ background: #0F0F0F;
204
+ border-radius: 33px;
205
+ height: 100%;
206
+ width: fit-content;
207
+ padding: 30px 30px 55px;
208
+ min-width: 550px;
209
+ position: relative;
234
210
  }
235
211
 
236
- .level-wrapper {
212
+ .box-bottom {
237
213
  margin-top: 30px;
238
214
  }
239
215
 
240
- .level-title {
241
- opacity: 50%;
242
- color: #000000CC;
216
+ .wrapper {
217
+ width: 100%;
218
+ padding-top: 24px;
219
+ border-top: 1px solid #494949;
220
+ }
221
+
222
+ .wrapper+.wrapper {
223
+ margin-left: 24px;
224
+ }
225
+
226
+ .text {
243
227
  font-size: 24px;
244
228
  line-height: 100%;
245
229
  }
246
230
 
247
- .level-content {
248
- margin-top: 6px;
249
- font-size: 28px;
250
- line-height: 37.86px;
231
+ .text-gray {
232
+ color: #707070;
251
233
  }
252
234
 
253
- .level-box {
254
- margin-left: 125px;
235
+ .mt-45 {
236
+ margin-top: 45px;
255
237
  }
256
238
 
257
- .box {
258
- background: #0F0F0F;
259
- border-radius: 33px;
260
- height: 100%;
261
- width: fit-content;
262
- padding: 30px 30px 55px;
239
+ .mt-12 {
240
+ margin-top: 12px;
263
241
  }
264
242
 
265
- .box-bottom {
266
- margin-top: 30px;
243
+ .text-black {
244
+ color: #0F0F0F;
245
+ }
246
+
247
+ .account {
248
+ font-size: 30px;
249
+ line-height: 80%;
250
+ }
251
+
252
+ .avatar {
253
+ border: 1px solid #2A2A2A;
254
+ border-radius: 100%;
255
+ width: 64px;
256
+ height: 64px;
257
+ margin-right: 16px;
258
+ }
259
+
260
+ .avatar img {
261
+ width: 50%;
262
+ }
263
+
264
+ .text-semibold {
265
+ font-weight: 600;
266
+ }
267
+
268
+ .text-nowrap {
269
+ white-space: nowrap;
267
270
  }
268
271
  </style>
269
272
  </head>
@@ -271,10 +274,43 @@
271
274
  <body>
272
275
  <div class="card flex flex-col justify-between">
273
276
  <img class="person-img" src={trendImage} alt="">
274
- <div class="box"></div>
277
+ <div class="box flex flex-col justify-between">
278
+ <div class="flex items-center">
279
+ <div class="avatar flex items-center justify-center">
280
+ <img src="{avatar}" alt="">
281
+ </div>
282
+ <div class="account">{account}</div>
283
+ </div>
284
+ <div>
285
+ <div class="wrapper flex justify-between">
286
+ <div class="pnl mona-sans">{pnl}%</div>
287
+ <div class="text text-gray">PnL</div>
288
+ </div>
289
+ <div class="flex mt-45 text">
290
+ <div class="wrapper">
291
+ <div class="text-semibold text-nowrap">{trendTitle}</div>
292
+ <div class="mt-12">
293
+ <img class="arrow" src="{arrowImage}" alt="">
294
+ <span class="text-gray">{positionInfo}</span>
295
+ </div>
296
+ </div>
297
+ <div class="wrapper">
298
+ <div class="flex justify-between">
299
+ <div class="text-gray">Entry:</div>
300
+ <div class="text-semibold">{openLevel}</div>
301
+ </div>
302
+ <div class="flex justify-between mt-12 {exitLevelClass}">
303
+ <div class="text-gray">Exit:</div>
304
+ <div class="text-semibold">{exitLevel}</div>
305
+ </div>
306
+ </div>
307
+ </div>
308
+ </div>
309
+ </div>
275
310
  <div class="box-bottom flex items-end">
276
311
  <img src="{logo}" class="logo" alt="">
277
- <div class="text-upper geist-mono">trade attention on <span class="text-underline text-bold">Trendle.fi</span>
312
+ <div class="text-upper geist-mono text-black">trade attention on <span
313
+ class="text-underline text-bold">Trendle.fi</span>
278
314
  </div>
279
315
  </div>
280
316
  </div>
@@ -1,4 +1,27 @@
1
- import {_ as __awaiter,a as __generator,b as getBase64Image,g as getFile,d as downloadImage}from'../../index-6ec143bc.js';import path from'path';import'fs';import'util';import'stream';import'http';import'https';import'url';import'crypto';import'http2';import'assert';import'tty';import'zlib';import'events';var cardTypes = {
1
+ import {_ as __awaiter,a as __generator,b as getBase64Image,g as getFile,d as downloadImage}from'../../index-6ec143bc.js';import path from'path';import'fs';import'util';import'stream';import'http';import'https';import'url';import'crypto';import'http2';import'assert';import'tty';import'zlib';import'events';var hashCode = function (str) {
2
+ return Array.from(str).reduce(function (hash, c) { return (hash << 5) - hash + c.charCodeAt(0); }, 0);
3
+ };
4
+ var generateShapeAvatar = function (address, size, scale) {
5
+ if (size === void 0) { size = 6; }
6
+ if (scale === void 0) { scale = 10; }
7
+ var hash = Math.abs(hashCode(address.toLowerCase()));
8
+ var color = "hsl(".concat(hash % 360, ", 60%, 55%)");
9
+ var svg = "<svg xmlns='http://www.w3.org/2000/svg' width='".concat(size * scale, "' height='").concat(size * scale, "'>");
10
+ for (var y = 0; y < size; y++) {
11
+ for (var x = 0; x < Math.ceil(size / 2); x++) {
12
+ if (((hash >> (x + y * size)) & 1) === 1) {
13
+ var rx = x * scale;
14
+ var ry = y * scale;
15
+ var symX = (size - x - 1) * scale;
16
+ svg += "<rect x='".concat(rx, "' y='").concat(ry, "' width='").concat(scale, "' height='").concat(scale, "' fill='").concat(color, "'/>");
17
+ svg += "<rect x='".concat(symX, "' y='").concat(ry, "' width='").concat(scale, "' height='").concat(scale, "' fill='").concat(color, "'/>");
18
+ }
19
+ }
20
+ }
21
+ svg += '</svg>';
22
+ var avatar = "data:image/svg+xml;utf8,".concat(encodeURIComponent(svg));
23
+ return avatar;
24
+ };var cardTypes = {
2
25
  'profit': {
3
26
  bgColor: '#72FF4B',
4
27
  },
@@ -11,11 +34,11 @@ var template = {
11
34
  height: 630,
12
35
  type: 'jpeg',
13
36
  html: function (props) { return __awaiter(void 0, void 0, void 0, function () {
14
- var trend, pnl, position, isProfit, bgColor, leverage, isLong, openLevel, exitLevel, html, logo, arrowImage, trendImage, _a, positionInfo;
37
+ var accountAddress, trend, pnl, position, isProfit, bgColor, leverage, isLong, openLevel, exitLevel, html, logo, arrowImage, trendImage, _a, positionInfo, avatar;
15
38
  return __generator(this, function (_b) {
16
39
  switch (_b.label) {
17
40
  case 0:
18
- trend = props.trend, pnl = props.pnl, position = props.position;
41
+ accountAddress = props.accountAddress, trend = props.trend, pnl = props.pnl, position = props.position;
19
42
  isProfit = pnl > 0;
20
43
  bgColor = (isProfit ? cardTypes.profit : cardTypes.loss).bgColor;
21
44
  leverage = position.leverage, isLong = position.isLong, openLevel = position.openLevel, exitLevel = position.exitLevel;
@@ -32,10 +55,13 @@ var template = {
32
55
  _b.label = 3;
33
56
  case 3:
34
57
  trendImage = _a;
35
- positionInfo = "".concat(isLong ? ' Up' : ' Down', ", Boost x").concat(leverage);
58
+ positionInfo = "".concat(isLong ? 'Up' : 'Down', ", X").concat(leverage, " Boost");
59
+ avatar = generateShapeAvatar(accountAddress);
36
60
  return [2 /*return*/, html
37
61
  .replace('{logo}', logo)
38
- .replace('--card-bg-color', bgColor)
62
+ .replace('{account}', "".concat(accountAddress.substr(0, 6), "...").concat(accountAddress.substr(-1 * 6)))
63
+ .replace('{avatar}', avatar)
64
+ .replaceAll('--card-bg-color', bgColor)
39
65
  .replace('{personImg}', trendImage)
40
66
  .replace('{trendImage}', trendImage)
41
67
  .replace('{trendTitle}', trend.title)
@@ -0,0 +1,2 @@
1
+ declare const generateShapeAvatar: (address: string, size?: number, scale?: number) => string;
2
+ export default generateShapeAvatar;
@@ -4,12 +4,27 @@ interface GeneratorOptions {
4
4
  timeout?: number;
5
5
  args?: string[];
6
6
  }
7
+ /**
8
+ * Options for a single image generation.
9
+ */
7
10
  interface GenerateOptions {
11
+ /** JPEG quality 1–100 (ignored for PNG). Default 85. */
8
12
  quality?: number;
13
+ /** Screenshot the full scrollable page instead of just the viewport. Default false. */
9
14
  fullPage?: boolean;
15
+ /** Wait for document.fonts.ready before taking the screenshot so webfonts are applied. Default true. */
10
16
  waitForFonts?: boolean;
17
+ /** Max ms to wait for content/font loading. Default 2000. */
11
18
  waitTimeout?: number;
19
+ /**
20
+ * When to consider the page content "loaded" before screenshot.
21
+ * - `domcontentloaded` – DOM ready, resources (images, fonts) may still load. Fastest. Default.
22
+ * - `load` – load event fired (images, stylesheets, etc. loaded).
23
+ * - `networkidle0` – no network requests for 500ms.
24
+ * - `networkidle2` – at most 2 network requests for 500ms.
25
+ */
12
26
  waitUntil?: 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2';
27
+ /** If true, do not add an extra delay for CSS animations. Default true. */
13
28
  skipAnimations?: boolean;
14
29
  }
15
30
  type GenerateProps<P> = {
package/lib/index.js CHANGED
@@ -180,7 +180,7 @@ function __generator(thisArg, body) {
180
180
  throw new Error('Invalid template: missing required properties');
181
181
  }
182
182
  width = template.width, height = template.height, type = template.type, getHtml = template.html;
183
- _d = options.quality, quality = _d === void 0 ? type === 'jpeg' ? 85 : undefined : _d, _e = options.fullPage, fullPage = _e === void 0 ? false : _e, _f = options.waitForFonts, waitForFonts = _f === void 0 ? true : _f, _g = options.waitTimeout, waitTimeout = _g === void 0 ? 2000 : _g, _h = options.waitUntil, waitUntil = _h === void 0 ? 'domcontentloaded' : _h, _j = options.skipAnimations, skipAnimations = _j === void 0 ? true : _j;
183
+ _d = options.quality, quality = _d === void 0 ? type === 'jpeg' ? 85 : undefined : _d, _e = options.fullPage, fullPage = _e === void 0 ? false : _e, _f = options.waitForFonts, waitForFonts = _f === void 0 ? true : _f, _g = options.waitTimeout, waitTimeout = _g === void 0 ? 2000 : _g, _h = options.waitUntil, waitUntil = _h === void 0 ? 'load' : _h, _j = options.skipAnimations, skipAnimations = _j === void 0 ? true : _j;
184
184
  _l.label = 7;
185
185
  case 7:
186
186
  _l.trys.push([7, 20, , 21]);
@@ -1,5 +1,6 @@
1
1
  import { type Template } from '../../utils';
2
2
  export type Props = {
3
+ accountAddress: string;
3
4
  trend: {
4
5
  image: string | undefined;
5
6
  title: string;
@@ -7,8 +8,8 @@ export type Props = {
7
8
  position: {
8
9
  leverage: number;
9
10
  isLong: boolean;
10
- openLevel: number;
11
- exitLevel: number | undefined;
11
+ openLevel: string;
12
+ exitLevel: string | undefined;
12
13
  };
13
14
  pnl: number;
14
15
  };
@@ -7,7 +7,7 @@
7
7
  <link rel="preconnect" href="https://fonts.googleapis.com">
8
8
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
9
  <link
10
- href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@100..900&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Mona+Sans:ital,wdth,wght@0,125,200..900;1,125,200..900&display=swap"
10
+ href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;700&family=Inter:wght@500;600&family=Mona+Sans:wdth,wght@125,700&display=swap"
11
11
  rel="stylesheet">
12
12
  <style>
13
13
  html {
@@ -157,6 +157,7 @@
157
157
  height: 675px;
158
158
  padding: 40px 36px 30px;
159
159
  position: relative;
160
+ color: white;
160
161
  }
161
162
 
162
163
  .logo {
@@ -166,42 +167,12 @@
166
167
  margin-right: 45px;
167
168
  }
168
169
 
169
- .trend {
170
- /* margin-top: 108px; */
171
- }
172
-
173
- .trend__img {
174
- margin-right: 20px;
175
- width: 80px;
176
- height: 80px;
177
- border-radius: 100%;
178
- overflow: hidden;
179
- }
180
-
181
- .trend__img>img {
182
- width: 100%;
183
- }
184
-
185
- .trend__title {
186
- font-size: 32px;
187
- line-height: 100%;
188
- }
189
-
190
- .trend__badge {
191
- background-color: rgba(0, 0, 0, 0.2);
192
- padding: 6px 12px 8px 8px;
193
- border-radius: 5px;
194
- font-size: 24px;
195
- line-height: 100%;
196
- margin-top: 10px;
197
- width: fit-content;
198
- }
199
-
200
170
  .pnl {
201
- margin-top: 22px;
202
- font-size: 120px;
203
- line-height: 100%;
171
+ font-size: 72px;
172
+ line-height: 90%;
204
173
  font-weight: 700;
174
+ font-stretch: 125%;
175
+ color: --card-bg-color;
205
176
  }
206
177
 
207
178
  .right-img {
@@ -214,8 +185,10 @@
214
185
  .arrow {
215
186
  width: 24px;
216
187
  height: 24px;
217
- margin-top: 3px;
218
- margin-bottom: -3px;
188
+ margin-top: -4px;
189
+ margin-bottom: -4px;
190
+ margin-right: -4px;
191
+ margin-left: -6px;
219
192
  }
220
193
 
221
194
  .person-img {
@@ -226,44 +199,74 @@
226
199
  mix-blend-mode: multiply;
227
200
  }
228
201
 
229
- .bg-img {
230
- position: absolute;
231
- top: 0px;
232
- left: 0px;
233
- width: 100%;
202
+ .box {
203
+ background: #0F0F0F;
204
+ border-radius: 33px;
205
+ height: 100%;
206
+ width: fit-content;
207
+ padding: 30px 30px 55px;
208
+ min-width: 550px;
209
+ position: relative;
234
210
  }
235
211
 
236
- .level-wrapper {
212
+ .box-bottom {
237
213
  margin-top: 30px;
238
214
  }
239
215
 
240
- .level-title {
241
- opacity: 50%;
242
- color: #000000CC;
216
+ .wrapper {
217
+ width: 100%;
218
+ padding-top: 24px;
219
+ border-top: 1px solid #494949;
220
+ }
221
+
222
+ .wrapper+.wrapper {
223
+ margin-left: 24px;
224
+ }
225
+
226
+ .text {
243
227
  font-size: 24px;
244
228
  line-height: 100%;
245
229
  }
246
230
 
247
- .level-content {
248
- margin-top: 6px;
249
- font-size: 28px;
250
- line-height: 37.86px;
231
+ .text-gray {
232
+ color: #707070;
251
233
  }
252
234
 
253
- .level-box {
254
- margin-left: 125px;
235
+ .mt-45 {
236
+ margin-top: 45px;
255
237
  }
256
238
 
257
- .box {
258
- background: #0F0F0F;
259
- border-radius: 33px;
260
- height: 100%;
261
- width: fit-content;
262
- padding: 30px 30px 55px;
239
+ .mt-12 {
240
+ margin-top: 12px;
263
241
  }
264
242
 
265
- .box-bottom {
266
- margin-top: 30px;
243
+ .text-black {
244
+ color: #0F0F0F;
245
+ }
246
+
247
+ .account {
248
+ font-size: 30px;
249
+ line-height: 80%;
250
+ }
251
+
252
+ .avatar {
253
+ border: 1px solid #2A2A2A;
254
+ border-radius: 100%;
255
+ width: 64px;
256
+ height: 64px;
257
+ margin-right: 16px;
258
+ }
259
+
260
+ .avatar img {
261
+ width: 50%;
262
+ }
263
+
264
+ .text-semibold {
265
+ font-weight: 600;
266
+ }
267
+
268
+ .text-nowrap {
269
+ white-space: nowrap;
267
270
  }
268
271
  </style>
269
272
  </head>
@@ -271,10 +274,43 @@
271
274
  <body>
272
275
  <div class="card flex flex-col justify-between">
273
276
  <img class="person-img" src={trendImage} alt="">
274
- <div class="box"></div>
277
+ <div class="box flex flex-col justify-between">
278
+ <div class="flex items-center">
279
+ <div class="avatar flex items-center justify-center">
280
+ <img src="{avatar}" alt="">
281
+ </div>
282
+ <div class="account">{account}</div>
283
+ </div>
284
+ <div>
285
+ <div class="wrapper flex justify-between">
286
+ <div class="pnl mona-sans">{pnl}%</div>
287
+ <div class="text text-gray">PnL</div>
288
+ </div>
289
+ <div class="flex mt-45 text">
290
+ <div class="wrapper">
291
+ <div class="text-semibold text-nowrap">{trendTitle}</div>
292
+ <div class="mt-12">
293
+ <img class="arrow" src="{arrowImage}" alt="">
294
+ <span class="text-gray">{positionInfo}</span>
295
+ </div>
296
+ </div>
297
+ <div class="wrapper">
298
+ <div class="flex justify-between">
299
+ <div class="text-gray">Entry:</div>
300
+ <div class="text-semibold">{openLevel}</div>
301
+ </div>
302
+ <div class="flex justify-between mt-12 {exitLevelClass}">
303
+ <div class="text-gray">Exit:</div>
304
+ <div class="text-semibold">{exitLevel}</div>
305
+ </div>
306
+ </div>
307
+ </div>
308
+ </div>
309
+ </div>
275
310
  <div class="box-bottom flex items-end">
276
311
  <img src="{logo}" class="logo" alt="">
277
- <div class="text-upper geist-mono">trade attention on <span class="text-underline text-bold">Trendle.fi</span>
312
+ <div class="text-upper geist-mono text-black">trade attention on <span
313
+ class="text-underline text-bold">Trendle.fi</span>
278
314
  </div>
279
315
  </div>
280
316
  </div>
@@ -1,4 +1,27 @@
1
- 'use strict';var index=require('../../index-efa024cc.js'),path=require('path');require('fs'),require('util'),require('stream'),require('http'),require('https'),require('url'),require('crypto'),require('http2'),require('assert'),require('tty'),require('zlib'),require('events');function _interopDefaultLegacy(e){return e&&typeof e==='object'&&'default'in e?e:{'default':e}}var path__default=/*#__PURE__*/_interopDefaultLegacy(path);var cardTypes = {
1
+ 'use strict';var index=require('../../index-efa024cc.js'),path=require('path');require('fs'),require('util'),require('stream'),require('http'),require('https'),require('url'),require('crypto'),require('http2'),require('assert'),require('tty'),require('zlib'),require('events');function _interopDefaultLegacy(e){return e&&typeof e==='object'&&'default'in e?e:{'default':e}}var path__default=/*#__PURE__*/_interopDefaultLegacy(path);var hashCode = function (str) {
2
+ return Array.from(str).reduce(function (hash, c) { return (hash << 5) - hash + c.charCodeAt(0); }, 0);
3
+ };
4
+ var generateShapeAvatar = function (address, size, scale) {
5
+ if (size === void 0) { size = 6; }
6
+ if (scale === void 0) { scale = 10; }
7
+ var hash = Math.abs(hashCode(address.toLowerCase()));
8
+ var color = "hsl(".concat(hash % 360, ", 60%, 55%)");
9
+ var svg = "<svg xmlns='http://www.w3.org/2000/svg' width='".concat(size * scale, "' height='").concat(size * scale, "'>");
10
+ for (var y = 0; y < size; y++) {
11
+ for (var x = 0; x < Math.ceil(size / 2); x++) {
12
+ if (((hash >> (x + y * size)) & 1) === 1) {
13
+ var rx = x * scale;
14
+ var ry = y * scale;
15
+ var symX = (size - x - 1) * scale;
16
+ svg += "<rect x='".concat(rx, "' y='").concat(ry, "' width='").concat(scale, "' height='").concat(scale, "' fill='").concat(color, "'/>");
17
+ svg += "<rect x='".concat(symX, "' y='").concat(ry, "' width='").concat(scale, "' height='").concat(scale, "' fill='").concat(color, "'/>");
18
+ }
19
+ }
20
+ }
21
+ svg += '</svg>';
22
+ var avatar = "data:image/svg+xml;utf8,".concat(encodeURIComponent(svg));
23
+ return avatar;
24
+ };var cardTypes = {
2
25
  'profit': {
3
26
  bgColor: '#72FF4B',
4
27
  },
@@ -11,11 +34,11 @@ var template = {
11
34
  height: 630,
12
35
  type: 'jpeg',
13
36
  html: function (props) { return index._(void 0, void 0, void 0, function () {
14
- var trend, pnl, position, isProfit, bgColor, leverage, isLong, openLevel, exitLevel, html, logo, arrowImage, trendImage, _a, positionInfo;
37
+ var accountAddress, trend, pnl, position, isProfit, bgColor, leverage, isLong, openLevel, exitLevel, html, logo, arrowImage, trendImage, _a, positionInfo, avatar;
15
38
  return index.a(this, function (_b) {
16
39
  switch (_b.label) {
17
40
  case 0:
18
- trend = props.trend, pnl = props.pnl, position = props.position;
41
+ accountAddress = props.accountAddress, trend = props.trend, pnl = props.pnl, position = props.position;
19
42
  isProfit = pnl > 0;
20
43
  bgColor = (isProfit ? cardTypes.profit : cardTypes.loss).bgColor;
21
44
  leverage = position.leverage, isLong = position.isLong, openLevel = position.openLevel, exitLevel = position.exitLevel;
@@ -32,10 +55,13 @@ var template = {
32
55
  _b.label = 3;
33
56
  case 3:
34
57
  trendImage = _a;
35
- positionInfo = "".concat(isLong ? ' Up' : ' Down', ", Boost x").concat(leverage);
58
+ positionInfo = "".concat(isLong ? 'Up' : 'Down', ", X").concat(leverage, " Boost");
59
+ avatar = generateShapeAvatar(accountAddress);
36
60
  return [2 /*return*/, html
37
61
  .replace('{logo}', logo)
38
- .replace('--card-bg-color', bgColor)
62
+ .replace('{account}', "".concat(accountAddress.substr(0, 6), "...").concat(accountAddress.substr(-1 * 6)))
63
+ .replace('{avatar}', avatar)
64
+ .replaceAll('--card-bg-color', bgColor)
39
65
  .replace('{personImg}', trendImage)
40
66
  .replace('{trendImage}', trendImage)
41
67
  .replace('{trendTitle}', trend.title)
@@ -0,0 +1,2 @@
1
+ declare const generateShapeAvatar: (address: string, size?: number, scale?: number) => string;
2
+ export default generateShapeAvatar;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azuro-org/images-generator",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "license": "ISC",
5
5
  "engines": {
6
6
  "node": ">=16.15.1",
package/tsconfig.json CHANGED
@@ -4,7 +4,12 @@
4
4
  "target": "es5",
5
5
  "module": "esnext",
6
6
  "moduleResolution": "node",
7
- "lib": [ "es2017", "es7", "es6", "dom" ],
7
+ "lib": [
8
+ "es2021",
9
+ "es7",
10
+ "es6",
11
+ "dom"
12
+ ],
8
13
  "strict": true,
9
14
  "declaration": true,
10
15
  "esModuleInterop": true