@orderly.network/hooks 1.1.5-rc.0 → 1.1.6

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 (101) hide show
  1. package/esm/dataProvider.d.ts +4 -3
  2. package/esm/dataProvider.d.ts.map +1 -1
  3. package/esm/dataProvider.js +5 -0
  4. package/esm/index.d.ts +4 -1
  5. package/esm/index.d.ts.map +1 -1
  6. package/esm/index.js +2 -0
  7. package/esm/orderly/useMarketsStream.d.ts.map +1 -1
  8. package/esm/orderly/useMarketsStream.js +1 -0
  9. package/esm/orderly/useMaxQty.d.ts.map +1 -1
  10. package/esm/orderly/useMaxQty.js +14 -27
  11. package/esm/orderly/useOrderEntry.js +19 -6
  12. package/esm/orderly/useOrderStream.d.ts +10 -1
  13. package/esm/orderly/useOrderStream.d.ts.map +1 -1
  14. package/esm/orderly/useOrderStream.js +29 -26
  15. package/esm/orderly/useOrderbookStream.d.ts.map +1 -1
  16. package/esm/orderly/useOrderbookStream.js +20 -13
  17. package/esm/orderly/usePositionStream.js +1 -1
  18. package/esm/orderly/usePrivateDataObserver.d.ts.map +1 -1
  19. package/esm/orderly/usePrivateDataObserver.js +62 -42
  20. package/esm/services/painter/backgroundPaint.d.ts +4 -4
  21. package/esm/services/painter/basePaint.d.ts +17 -8
  22. package/esm/services/painter/basePaint.d.ts.map +1 -1
  23. package/esm/services/painter/dataPaint.d.ts +4 -3
  24. package/esm/services/painter/dataPaint.d.ts.map +1 -1
  25. package/esm/services/painter/dataPaint.js +72 -35
  26. package/esm/services/painter/layout.config.d.ts +2 -2
  27. package/esm/services/painter/layout.config.d.ts.map +1 -1
  28. package/esm/services/painter/layout.config.js +13 -8
  29. package/esm/services/painter/painter.d.ts +6 -4
  30. package/esm/services/painter/painter.d.ts.map +1 -1
  31. package/esm/services/painter/painter.js +4 -4
  32. package/esm/unuse/apiPrefixMiddleware.d.ts.map +1 -1
  33. package/esm/unuse/apiPrefixMiddleware.js +0 -2
  34. package/esm/useLocalStorage.d.ts.map +1 -1
  35. package/esm/useLocalStorage.js +2 -4
  36. package/esm/useMutation.d.ts +4 -1
  37. package/esm/useMutation.d.ts.map +1 -1
  38. package/esm/useMutation.js +29 -2
  39. package/esm/usePoster.d.ts +30 -4
  40. package/esm/usePoster.d.ts.map +1 -1
  41. package/esm/usePoster.js +95 -24
  42. package/esm/utils/dev.d.ts +2 -0
  43. package/esm/utils/dev.d.ts.map +1 -0
  44. package/esm/utils/dev.js +18 -0
  45. package/esm/utils/swr.d.ts +10 -0
  46. package/esm/utils/swr.d.ts.map +1 -0
  47. package/esm/utils/swr.js +195 -0
  48. package/esm/version.d.ts +1 -1
  49. package/esm/version.d.ts.map +1 -1
  50. package/esm/version.js +2 -2
  51. package/lib/dataProvider.d.ts +4 -3
  52. package/lib/dataProvider.d.ts.map +1 -1
  53. package/lib/dataProvider.js +5 -0
  54. package/lib/index.d.ts +4 -1
  55. package/lib/index.d.ts.map +1 -1
  56. package/lib/index.js +4 -1
  57. package/lib/orderly/useMarketsStream.d.ts.map +1 -1
  58. package/lib/orderly/useMarketsStream.js +1 -0
  59. package/lib/orderly/useMaxQty.d.ts.map +1 -1
  60. package/lib/orderly/useMaxQty.js +14 -27
  61. package/lib/orderly/useOrderEntry.js +16 -3
  62. package/lib/orderly/useOrderStream.d.ts +10 -1
  63. package/lib/orderly/useOrderStream.d.ts.map +1 -1
  64. package/lib/orderly/useOrderStream.js +29 -26
  65. package/lib/orderly/useOrderbookStream.d.ts.map +1 -1
  66. package/lib/orderly/useOrderbookStream.js +20 -13
  67. package/lib/orderly/usePositionStream.js +1 -1
  68. package/lib/orderly/usePrivateDataObserver.d.ts.map +1 -1
  69. package/lib/orderly/usePrivateDataObserver.js +61 -41
  70. package/lib/services/painter/backgroundPaint.d.ts +4 -4
  71. package/lib/services/painter/basePaint.d.ts +17 -8
  72. package/lib/services/painter/basePaint.d.ts.map +1 -1
  73. package/lib/services/painter/dataPaint.d.ts +4 -3
  74. package/lib/services/painter/dataPaint.d.ts.map +1 -1
  75. package/lib/services/painter/dataPaint.js +72 -35
  76. package/lib/services/painter/layout.config.d.ts +2 -2
  77. package/lib/services/painter/layout.config.d.ts.map +1 -1
  78. package/lib/services/painter/layout.config.js +14 -9
  79. package/lib/services/painter/painter.d.ts +6 -4
  80. package/lib/services/painter/painter.d.ts.map +1 -1
  81. package/lib/services/painter/painter.js +4 -4
  82. package/lib/unuse/apiPrefixMiddleware.d.ts.map +1 -1
  83. package/lib/unuse/apiPrefixMiddleware.js +0 -2
  84. package/lib/useLocalStorage.d.ts.map +1 -1
  85. package/lib/useLocalStorage.js +2 -4
  86. package/lib/useMutation.d.ts +4 -1
  87. package/lib/useMutation.d.ts.map +1 -1
  88. package/lib/useMutation.js +29 -2
  89. package/lib/usePoster.d.ts +30 -4
  90. package/lib/usePoster.d.ts.map +1 -1
  91. package/lib/usePoster.js +93 -22
  92. package/lib/utils/dev.d.ts +2 -0
  93. package/lib/utils/dev.d.ts.map +1 -0
  94. package/lib/utils/dev.js +20 -0
  95. package/lib/utils/swr.d.ts +10 -0
  96. package/lib/utils/swr.d.ts.map +1 -0
  97. package/lib/utils/swr.js +200 -0
  98. package/lib/version.d.ts +1 -1
  99. package/lib/version.d.ts.map +1 -1
  100. package/lib/version.js +2 -2
  101. package/package.json +8 -8
@@ -1,5 +1,8 @@
1
1
  import { PosterPainter } from "./painter";
2
2
  export type posterDataSource = {
3
+ /**
4
+ * slogan of the poster
5
+ */
3
6
  message?: string;
4
7
  position: {
5
8
  symbol: string;
@@ -17,7 +20,7 @@ export type posterDataSource = {
17
20
  */
18
21
  ROI: number;
19
22
  /**
20
- * The informations of the position, such as open price, opened at, mark price, quantity
23
+ * The informations of the position, such as open price, opened at, mark price, quantity and custom message.
21
24
  */
22
25
  informations: {
23
26
  title: string;
@@ -51,23 +54,29 @@ export type layoutInfo = {
51
54
  bottom: number;
52
55
  }>;
53
56
  };
54
- export type posterLayoutConfig = {
57
+ export type PosterLayoutConfig = {
55
58
  message?: layoutInfo;
56
59
  domain?: layoutInfo;
57
60
  position?: layoutInfo;
58
- unrealizedPnl?: layoutInfo;
59
- informations?: layoutInfo;
61
+ unrealizedPnl?: layoutInfo & {
62
+ secondaryColor: string;
63
+ secondaryFontSize: number;
64
+ };
65
+ informations?: layoutInfo & {
66
+ labelColor?: string;
67
+ };
60
68
  updateTime?: layoutInfo;
61
69
  };
62
- export type drawOptions = {
70
+ export type DrawOptions = {
63
71
  /**
64
72
  * Color of common text
65
73
  */
66
74
  color?: string;
75
+ fontFamily?: string;
67
76
  /**
68
77
  * Lose color
69
78
  */
70
- loseColor?: string;
79
+ lossColor?: string;
71
80
  /**
72
81
  * Profit color
73
82
  */
@@ -79,12 +88,12 @@ export type drawOptions = {
79
88
  backgroundColor?: string;
80
89
  backgroundImg?: string;
81
90
  data?: posterDataSource;
82
- layout?: posterLayoutConfig;
91
+ layout?: PosterLayoutConfig;
83
92
  };
84
93
  export declare abstract class BasePaint {
85
94
  protected ctx: CanvasRenderingContext2D;
86
95
  protected painter: PosterPainter;
87
96
  constructor(ctx: CanvasRenderingContext2D, painter: PosterPainter);
88
- abstract draw(options: drawOptions): Promise<void>;
97
+ abstract draw(options: DrawOptions): Promise<void>;
89
98
  }
90
99
  //# sourceMappingURL=basePaint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"basePaint.d.ts","sourceRoot":"","sources":["../../../src/services/painter/basePaint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QAEf,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QACvB;;WAEG;QACH,QAAQ,EAAE,MAAM,CAAC;QACjB;;WAEG;QACH,GAAG,EAAE,MAAM,CAAC;QACZ;;WAEG;QACH,GAAG,EAAE,MAAM,CAAC;QACZ;;WAEG;QACH,YAAY,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACjD;;WAEG;QACH,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,QAAQ,EAAE,OAAO,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,CAAC,EAAE,UAAU,CAAC;IAErB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,aAAa,CAAC,EAAE,UAAU,CAAC;IAE3B,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B,CAAC;AAEF,8BAAsB,SAAS;IAE3B,SAAS,CAAC,GAAG,EAAE,wBAAwB;IACvC,SAAS,CAAC,OAAO,EAAE,aAAa;gBADtB,GAAG,EAAE,wBAAwB,EAC7B,OAAO,EAAE,aAAa;IAElC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CACnD"}
1
+ {"version":3,"file":"basePaint.d.ts","sourceRoot":"","sources":["../../../src/services/painter/basePaint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QAEf,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QACvB;;WAEG;QACH,QAAQ,EAAE,MAAM,CAAC;QACjB;;WAEG;QACH,GAAG,EAAE,MAAM,CAAC;QACZ;;WAEG;QACH,GAAG,EAAE,MAAM,CAAC;QACZ;;WAEG;QACH,YAAY,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACjD;;WAEG;QACH,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,QAAQ,EAAE,OAAO,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,CAAC,EAAE,UAAU,CAAC;IAErB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,aAAa,CAAC,EAAE,UAAU,GAAG;QAC3B,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IAEF,YAAY,CAAC,EAAE,UAAU,GAAG;QAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B,CAAC;AAEF,8BAAsB,SAAS;IAE3B,SAAS,CAAC,GAAG,EAAE,wBAAwB;IACvC,SAAS,CAAC,OAAO,EAAE,aAAa;gBADtB,GAAG,EAAE,wBAAwB,EAC7B,OAAO,EAAE,aAAa;IAElC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CACnD"}
@@ -1,9 +1,10 @@
1
- import { BasePaint, drawOptions } from "./basePaint";
1
+ import { BasePaint, DrawOptions } from "./basePaint";
2
2
  export declare class DataPaint extends BasePaint {
3
3
  private positionInfoCellWidth;
4
4
  private DEFAULT_PROFIT_COLOR;
5
- private DEFAULT_LOSE_COLOR;
6
- draw(options: drawOptions): Promise<void>;
5
+ private DEFAULT_LOSS_COLOR;
6
+ private transformTop;
7
+ draw(options: DrawOptions): Promise<void>;
7
8
  private drawMessage;
8
9
  private drawPosition;
9
10
  private drawUnrealizedPnL;
@@ -1 +1 @@
1
- {"version":3,"file":"dataPaint.d.ts","sourceRoot":"","sources":["../../../src/services/painter/dataPaint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAGjE,qBAAa,SAAU,SAAQ,SAAS;IACtC,OAAO,CAAC,qBAAqB,CAAO;IAEpC,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,kBAAkB,CAAsB;IAE1C,IAAI,CAAC,OAAO,EAAE,WAAW;IA0B/B,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,YAAY;IAoEpB,OAAO,CAAC,iBAAiB;IAoDzB,OAAO,CAAC,gBAAgB;IA6BxB,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,SAAS;IAoCjB,OAAO,CAAC,MAAM;CAGf"}
1
+ {"version":3,"file":"dataPaint.d.ts","sourceRoot":"","sources":["../../../src/services/painter/dataPaint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAGjE,qBAAa,SAAU,SAAQ,SAAS;IACtC,OAAO,CAAC,qBAAqB,CAAO;IAEpC,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,kBAAkB,CAAsB;IAEhD,OAAO,CAAC,YAAY,CAAK;IAEnB,IAAI,CAAC,OAAO,EAAE,WAAW;IAoC/B,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,YAAY;IA2EpB,OAAO,CAAC,iBAAiB;IAyEzB,OAAO,CAAC,gBAAgB;IAoCxB,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,SAAS;IAuCjB,OAAO,CAAC,MAAM;CAGf"}
@@ -4,22 +4,29 @@ import { path } from "ramda";
4
4
  export class DataPaint extends BasePaint {
5
5
  constructor() {
6
6
  super(...arguments);
7
- this.positionInfoCellWidth = 100;
7
+ this.positionInfoCellWidth = 110;
8
8
  this.DEFAULT_PROFIT_COLOR = "rgb(0,181,159)";
9
- this.DEFAULT_LOSE_COLOR = "rgb(255,103,194)";
9
+ this.DEFAULT_LOSS_COLOR = "rgb(255,103,194)";
10
+ this.transformTop = 0;
10
11
  }
11
12
  async draw(options) {
12
- console.log("DataPaint draw: ", options.data);
13
+ const needDrawDetails = Array.isArray(options.data?.position?.informations) &&
14
+ (options.data?.position?.informations?.length ?? 0) > 0;
15
+ const hasMessage = !!options.data?.message;
16
+ this.transformTop = hasMessage ? 0 : needDrawDetails ? -40 : -150;
17
+ // If position details are not displayed, the position PNL information will be margin
18
+ const offsetTop = hasMessage ? 50 : 100;
19
+ // const offsetMessage = hasMessage ? 0 : -50;
13
20
  if (!!options.data?.message) {
14
21
  this.drawMessage(options);
15
22
  }
16
23
  if (!!options.data?.position) {
17
- this.drawPosition(options);
24
+ this.drawPosition(options, needDrawDetails ? 0 : offsetTop);
18
25
  }
19
- if (Array.isArray(options.data?.position?.informations)) {
26
+ if (needDrawDetails) {
20
27
  this.drawInformations(options);
21
28
  }
22
- this.drawUnrealizedPnL(options);
29
+ this.drawUnrealizedPnL(options, needDrawDetails ? 0 : offsetTop);
23
30
  if (!!options.data?.domain) {
24
31
  this.drawDomainUrl(options);
25
32
  }
@@ -37,22 +44,25 @@ export class DataPaint extends BasePaint {
37
44
  top: this._ratio(position.top),
38
45
  left: this._ratio(position.left),
39
46
  textBaseline: "top",
47
+ fontFamily: options.fontFamily,
40
48
  });
41
49
  }
42
- drawPosition(options) {
50
+ drawPosition(options, offsetTop = 0) {
43
51
  const layout = path(["layout", "position"], options);
44
- const { position } = layout;
52
+ const { position, fontSize = 14 } = layout;
45
53
  let left = this._ratio(position.left);
54
+ let top = layout.position.top + offsetTop + this.transformTop;
46
55
  let prevElementBoundingBox = {};
47
56
  // draw position side;
48
57
  if (typeof options.data?.position.side !== "undefined") {
49
58
  prevElementBoundingBox = this._drawText(options.data.position.side, {
50
- color: options.data?.position.side === "LONG"
59
+ color: options.data?.position.side.toUpperCase() === "LONG"
51
60
  ? this.DEFAULT_PROFIT_COLOR
52
- : this.DEFAULT_LOSE_COLOR,
61
+ : this.DEFAULT_LOSS_COLOR,
53
62
  left,
54
- top: this._ratio(70),
55
- fontSize: this._ratio(14),
63
+ top: this._ratio(top),
64
+ fontSize: this._ratio(fontSize),
65
+ fontFamily: options.fontFamily,
56
66
  });
57
67
  }
58
68
  if (typeof options.data?.position.symbol !== "undefined") {
@@ -61,16 +71,18 @@ export class DataPaint extends BasePaint {
61
71
  prevElementBoundingBox = this._drawText("|", {
62
72
  color: "rgba(255,255,255,0.2)",
63
73
  left,
64
- top: this._ratio(70),
65
- fontSize: this._ratio(12),
74
+ top: this._ratio(top),
75
+ fontSize: this._ratio(fontSize),
76
+ fontFamily: options.fontFamily,
66
77
  });
67
78
  }
68
79
  left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
69
80
  prevElementBoundingBox = this._drawText(options.data?.position.symbol, {
70
- color: "rgba(255,255,255,0.98)",
81
+ color: layout.color,
71
82
  left: left,
72
- top: this._ratio(70),
73
- fontSize: this._ratio(12),
83
+ top: this._ratio(top),
84
+ fontSize: this._ratio(fontSize),
85
+ fontFamily: options.fontFamily,
74
86
  });
75
87
  }
76
88
  if (typeof options.data?.position.leverage !== "undefined") {
@@ -79,76 +91,95 @@ export class DataPaint extends BasePaint {
79
91
  prevElementBoundingBox = this._drawText("|", {
80
92
  color: "rgba(255,255,255,0.2)",
81
93
  left,
82
- top: this._ratio(70),
83
- fontSize: this._ratio(12),
94
+ top: this._ratio(top),
95
+ fontSize: this._ratio(fontSize),
96
+ fontFamily: options.fontFamily,
84
97
  });
85
98
  }
86
99
  left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
87
100
  prevElementBoundingBox = this._drawText(`${options.data?.position.leverage}X`, {
88
- color: "rgba(255,255,255,0.98)",
101
+ color: layout.color,
89
102
  left,
90
- top: this._ratio(70),
91
- fontSize: this._ratio(12),
103
+ top: this._ratio(top),
104
+ fontSize: this._ratio(fontSize),
105
+ fontFamily: options.fontFamily,
92
106
  });
93
107
  }
94
108
  }
95
- drawUnrealizedPnL(options) {
109
+ drawUnrealizedPnL(options, offsetTop = 0) {
96
110
  // reset left value;
97
111
  const layout = path(["layout", "unrealizedPnl"], options);
98
112
  const { position } = layout;
99
113
  let left = this._ratio(position.left);
100
114
  let prevElementBoundingBox = {};
115
+ const top = (position.top ?? 0) + offsetTop + this.transformTop;
101
116
  // ROI
102
117
  if (typeof options.data?.position.ROI !== "undefined") {
103
118
  const prefix = options.data?.position.ROI > 0 ? "+" : "";
104
119
  prevElementBoundingBox = this._drawText(`${prefix}${commify(options.data?.position.ROI)}%`, {
105
120
  color: prefix === "+"
106
121
  ? options.profitColor || this.DEFAULT_PROFIT_COLOR
107
- : options.loseColor || this.DEFAULT_LOSE_COLOR,
122
+ : options.lossColor || this.DEFAULT_LOSS_COLOR,
108
123
  left,
109
- top: this._ratio(position.top),
124
+ top: this._ratio(top),
110
125
  fontSize: this._ratio(layout.fontSize),
111
126
  fontWeight: 700,
127
+ fontFamily: options.fontFamily,
112
128
  });
113
129
  }
114
130
  // unrelPnL
115
131
  if (typeof options.data?.position.pnl !== "undefined") {
116
132
  const prefix = options.data?.position.pnl > 0 ? "+" : "";
117
133
  let text = `${prefix}${commify(options.data?.position.pnl)} ${options.data?.position.currency}`;
134
+ let fontWeight = 600;
118
135
  if (prevElementBoundingBox.width) {
119
136
  left += (prevElementBoundingBox.width ?? 0) + this._ratio(8);
120
137
  text = `(${text})`;
121
138
  }
122
139
  else {
123
140
  left = this._ratio(position.left);
141
+ fontWeight = 700;
124
142
  }
143
+ const color = typeof options.data.position.ROI === "undefined"
144
+ ? prefix === "+"
145
+ ? options.profitColor || this.DEFAULT_PROFIT_COLOR
146
+ : options.lossColor || this.DEFAULT_LOSS_COLOR
147
+ : layout.secondaryColor;
148
+ const fontSize = typeof options.data.position.ROI === "undefined"
149
+ ? this._ratio(layout.fontSize)
150
+ : this._ratio(layout.secondaryFontSize);
125
151
  prevElementBoundingBox = this._drawText(text, {
126
- color: "rgba(255,255,255,0.5)",
152
+ color,
127
153
  left,
128
- top: this._ratio(position.top),
129
- fontSize: this._ratio(layout.fontSize * 0.6),
130
- fontWeight: 600,
154
+ top: this._ratio(top),
155
+ fontSize,
156
+ fontWeight,
157
+ fontFamily: options.fontFamily,
131
158
  });
132
159
  }
133
160
  }
134
161
  drawInformations(options) {
135
162
  const layout = path(["layout", "informations"], options);
136
163
  const { position } = layout;
164
+ const isVertical = (options.data?.position.informations.length ?? 0) === 2;
137
165
  options.data?.position.informations.forEach((info, index) => {
138
- const left = position.left + this.positionInfoCellWidth * (index % 2);
139
- const top = position.top + Math.floor(index / 2) * 40;
166
+ // let cellWidth = this.positionInfoCellWidth;
167
+ let left = position.left + this.positionInfoCellWidth * Math.floor(index / 2);
168
+ let top = position.top + (index % 2) * 38 + this.transformTop;
140
169
  this._drawText(info.title, {
141
170
  left: this._ratio(left),
142
171
  top: this._ratio(top),
143
172
  fontSize: this._ratio(10),
144
- color: "rgba(255,255,255,0.2)",
173
+ color: layout.labelColor,
174
+ fontFamily: options.fontFamily,
145
175
  });
146
176
  this._drawText(info.value, {
147
- left: this._ratio(position.left + this.positionInfoCellWidth * (index % 2)),
177
+ left: this._ratio(left),
148
178
  top: this._ratio(top + 17),
149
179
  fontSize: this._ratio(layout.fontSize),
150
180
  fontWeight: 500,
151
181
  color: layout.color,
182
+ fontFamily: options.fontFamily,
152
183
  });
153
184
  });
154
185
  }
@@ -161,6 +192,9 @@ export class DataPaint extends BasePaint {
161
192
  top: this._ratio(top),
162
193
  fontSize: this._ratio(layout.fontSize),
163
194
  color: options.brandColor ?? this.DEFAULT_PROFIT_COLOR,
195
+ fontFamily: options.fontFamily,
196
+ textBaseline: layout.textBaseline,
197
+ fontWeight: 600,
164
198
  });
165
199
  }
166
200
  drawPositionTime(options) {
@@ -173,14 +207,17 @@ export class DataPaint extends BasePaint {
173
207
  top: this._ratio(top),
174
208
  fontSize: this._ratio(layout.fontSize),
175
209
  color: layout.color,
176
- textAlign: "end",
210
+ textAlign: layout.textAlign,
211
+ fontFamily: options.fontFamily,
212
+ textBaseline: layout.textBaseline,
177
213
  });
178
214
  }
179
215
  _drawText(str, options) {
180
216
  let boundingBox;
181
217
  const { left = 30, top = 30, fontSize = 13, fontWeight = 500, color = "black", textBaseline = "middle", textAlign = "start", } = options ?? {};
182
218
  this.ctx.save();
183
- this.ctx.font = `${fontWeight} ${fontSize}px Manrope`;
219
+ // "Nunito Sans",-apple-system,"San Francisco",BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Helvetica,Arial,sans-serif
220
+ this.ctx.font = `${fontWeight} ${fontSize}px ${options?.fontFamily}`;
184
221
  this.ctx.fillStyle = color;
185
222
  this.ctx.textBaseline = textBaseline;
186
223
  this.ctx.textAlign = textAlign;
@@ -1,3 +1,3 @@
1
- import { posterLayoutConfig } from "./basePaint";
2
- export declare const defaultLayoutConfig: posterLayoutConfig;
1
+ import { type PosterLayoutConfig } from "./basePaint";
2
+ export declare const DefaultLayoutConfig: PosterLayoutConfig;
3
3
  //# sourceMappingURL=layout.config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout.config.d.ts","sourceRoot":"","sources":["../../../src/services/painter/layout.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAE7D,eAAO,MAAM,mBAAmB,EAAE,kBAoDjC,CAAC"}
1
+ {"version":3,"file":"layout.config.d.ts","sourceRoot":"","sources":["../../../src/services/painter/layout.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,eAAO,MAAM,mBAAmB,EAAE,kBAyDjC,CAAC"}
@@ -1,15 +1,16 @@
1
- export const defaultLayoutConfig = {
1
+ export const DefaultLayoutConfig = {
2
2
  domain: {
3
3
  fontSize: 13,
4
4
  // color: undefined,
5
+ textBaseline: "bottom",
5
6
  position: {
6
7
  left: 20,
7
- bottom: 37,
8
+ bottom: 17,
8
9
  },
9
10
  },
10
11
  message: {
11
12
  fontSize: 20,
12
- color: "white",
13
+ color: "rgba(255, 255, 255, 0.98)",
13
14
  textBaseline: "top",
14
15
  position: {
15
16
  left: 20,
@@ -17,8 +18,8 @@ export const defaultLayoutConfig = {
17
18
  },
18
19
  },
19
20
  position: {
20
- fontSize: 20,
21
- color: "white",
21
+ fontSize: 14,
22
+ color: "rgba(255,255,255,0.98)",
22
23
  position: {
23
24
  left: 20,
24
25
  top: 70,
@@ -27,6 +28,8 @@ export const defaultLayoutConfig = {
27
28
  unrealizedPnl: {
28
29
  fontSize: 36,
29
30
  color: "rgba(255,255,255,0.5)",
31
+ secondaryColor: "rgba(255,255,255,0.54)",
32
+ secondaryFontSize: 20,
30
33
  position: {
31
34
  left: 20,
32
35
  top: 110,
@@ -34,7 +37,8 @@ export const defaultLayoutConfig = {
34
37
  },
35
38
  informations: {
36
39
  fontSize: 12,
37
- color: "rgba(255,255,255,0.54)",
40
+ color: "rgba(255, 255, 255, 0.8)",
41
+ labelColor: "rgba(255,255,255,0.36)",
38
42
  position: {
39
43
  left: 20,
40
44
  top: 150,
@@ -44,9 +48,10 @@ export const defaultLayoutConfig = {
44
48
  fontSize: 10,
45
49
  color: "rgba(255,255,255,0.5)",
46
50
  textAlign: "end",
51
+ textBaseline: "bottom",
47
52
  position: {
48
- right: 15,
49
- bottom: 15,
53
+ right: 20,
54
+ bottom: 17,
50
55
  },
51
56
  },
52
57
  };
@@ -1,12 +1,14 @@
1
- import { drawOptions } from "./basePaint";
1
+ import { DrawOptions } from "./basePaint";
2
2
  export declare class PosterPainter {
3
3
  private canvas;
4
4
  private ctx;
5
5
  width: number;
6
6
  height: number;
7
7
  ratio: number;
8
- constructor(canvas: HTMLCanvasElement);
9
- draw(options: drawOptions): void;
10
- _draw(options: drawOptions): Promise<void>;
8
+ constructor(canvas: HTMLCanvasElement, options?: {
9
+ ratio: number;
10
+ });
11
+ draw(options: DrawOptions): void;
12
+ _draw(options: DrawOptions): Promise<void>;
11
13
  }
12
14
  //# sourceMappingURL=painter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"painter.d.ts","sourceRoot":"","sources":["../../../src/services/painter/painter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,qBAAa,aAAa;IAMZ,OAAO,CAAC,MAAM;IAL1B,OAAO,CAAC,GAAG,CAA2B;IACtC,KAAK,EAAE,MAAM,CAAK;IAClB,MAAM,EAAE,MAAM,CAAK;IACnB,KAAK,EAAE,MAAM,CAAK;gBAEE,MAAM,EAAE,iBAAiB;IAqB7C,IAAI,CAAC,OAAO,EAAE,WAAW;IAInB,KAAK,CAAC,OAAO,EAAE,WAAW;CAUjC"}
1
+ {"version":3,"file":"painter.d.ts","sourceRoot":"","sources":["../../../src/services/painter/painter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,qBAAa,aAAa;IAOtB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,GAAG,CAA2B;IACtC,KAAK,EAAE,MAAM,CAAK;IAClB,MAAM,EAAE,MAAM,CAAK;IACnB,KAAK,EAAE,MAAM,CAAC;gBAGJ,MAAM,EAAE,iBAAiB,EACjC,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;KACf;IAsBH,IAAI,CAAC,OAAO,EAAE,WAAW;IAInB,KAAK,CAAC,OAAO,EAAE,WAAW;CAWjC"}
@@ -2,16 +2,15 @@ import { BackgroundPaint } from "./backgroundPaint";
2
2
  import { DataPaint } from "./dataPaint";
3
3
  export class PosterPainter {
4
4
  // resourceManager: Resource;
5
- constructor(canvas) {
5
+ constructor(canvas, options) {
6
6
  // console.log("PosterPainter constructor");
7
7
  this.canvas = canvas;
8
8
  this.width = 0;
9
9
  this.height = 0;
10
- this.ratio = 1;
11
10
  this.ctx = this.canvas.getContext("2d");
12
11
  this.width = this.canvas.width;
13
12
  this.height = this.canvas.height;
14
- this.ratio = Math.floor(window.devicePixelRatio) || 1;
13
+ this.ratio = options?.ratio || Math.floor(window.devicePixelRatio) || 1;
15
14
  console.log("this ratio", this.ratio);
16
15
  // render to high resolution
17
16
  this.canvas.width = this.width * this.ratio;
@@ -26,7 +25,8 @@ export class PosterPainter {
26
25
  async _draw(options) {
27
26
  if (this.ctx === null)
28
27
  return;
29
- console.log("============ DRAW ============");
28
+ // console.log("============ DRAW ============");
29
+ // this.ctx.font = options.fontFamily!;
30
30
  // this.ctx.clearRect(0, 0, this.width * this.ratio, this.height * this.ratio);
31
31
  // start draw
32
32
  // background
@@ -1 +1 @@
1
- {"version":3,"file":"apiPrefixMiddleware.d.ts","sourceRoot":"","sources":["../../src/unuse/apiPrefixMiddleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,KAAK,CAAC;AAG/C,eAAO,MAAM,mBAAmB,EAAE,UA4BjC,CAAC"}
1
+ {"version":3,"file":"apiPrefixMiddleware.d.ts","sourceRoot":"","sources":["../../src/unuse/apiPrefixMiddleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,KAAK,CAAC;AAG/C,eAAO,MAAM,mBAAmB,EAAE,UA0BjC,CAAC"}
@@ -4,13 +4,11 @@ export const apiPrefixMiddleware = (useSWRNext) => {
4
4
  // @ts-ignore
5
5
  const { apiBaseUrl } = useContext(OrderlyContext);
6
6
  return (key, fetcher, config) => {
7
- // 将日志记录器添加到原始 fetcher。
8
7
  const extendedFetcher = (...args) => {
9
8
  // @ts-ignore
10
9
  return fetcher(...args);
11
10
  };
12
11
  // key = `${apiBaseUrl}${key}`;
13
- // 使用新的 fetcher 执行 hook。
14
12
  return useSWRNext(key, extendedFetcher, config);
15
13
  };
16
14
  // return (key, fetcher, config) => {
@@ -1 +1 @@
1
- {"version":3,"file":"useLocalStorage.d.ts","sourceRoot":"","sources":["../src/useLocalStorage.ts"],"names":[],"mappings":"AAIA,wBAAgB,eAAe,CAAC,CAAC,EAC/B,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,CAAC,GACd,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,CAuF3B"}
1
+ {"version":3,"file":"useLocalStorage.d.ts","sourceRoot":"","sources":["../src/useLocalStorage.ts"],"names":[],"mappings":"AAIA,wBAAgB,eAAe,CAAC,CAAC,EAC/B,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,CAAC,GACd,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,CAoF3B"}
@@ -63,11 +63,9 @@ export function useLocalStorage(key, initialValue) {
63
63
  }
64
64
  setStoredValue(readValue());
65
65
  };
66
- // 添加 storage 事件监听器
67
- window.addEventListener('storage', handleStorageChange);
66
+ window.addEventListener("storage", handleStorageChange);
68
67
  return () => {
69
- // 清除 storage 事件监听器
70
- window.removeEventListener('storage', handleStorageChange);
68
+ window.removeEventListener("storage", handleStorageChange);
71
69
  };
72
70
  }, [key]);
73
71
  return [storedValue, setValue];
@@ -1,6 +1,9 @@
1
1
  import { type SWRMutationConfiguration } from "swr/mutation";
2
2
  type HTTP_METHOD = "POST" | "PUT" | "DELETE";
3
- export declare const useMutation: <T, E>(url: string, method?: HTTP_METHOD, options?: SWRMutationConfiguration<T, E> | undefined) => readonly [(data: any, params?: any, options?: any) => Promise<any>, {
3
+ /**
4
+ * This hook is used to execute API requests for data mutation, such as POST, DELETE, PUT, etc.
5
+ */
6
+ export declare const useMutation: <T, E>(url: string, method?: HTTP_METHOD, options?: SWRMutationConfiguration<T, E> | undefined) => readonly [(data: Record<string, any> | null, params?: Record<string, any>, options?: SWRMutationConfiguration<T, E> | undefined) => Promise<any>, {
4
7
  readonly data: any;
5
8
  readonly error: E | undefined;
6
9
  readonly reset: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"useMutation.d.ts","sourceRoot":"","sources":["../src/useMutation.ts"],"names":[],"mappings":"AAAA,OAAuB,EAErB,KAAK,wBAAwB,EAE9B,MAAM,cAAc,CAAC;AAStB,KAAK,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;AAmC7C,eAAO,MAAM,WAAW,cACjB,MAAM,WACH,WAAW,4EAoBX,GAAG,WACA,GAAG,YACF,GAAG,KACZ,QAAQ,GAAG,CAAC;;;;;EAsChB,CAAC"}
1
+ {"version":3,"file":"useMutation.d.ts","sourceRoot":"","sources":["../src/useMutation.ts"],"names":[],"mappings":"AAAA,OAAuB,EAErB,KAAK,wBAAwB,EAE9B,MAAM,cAAc,CAAC;AAStB,KAAK,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;AAmC7C;;GAEG;AACH,eAAO,MAAM,WAAW,cAKjB,MAAM,WAIH,WAAW,4EA6BX,OAAO,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,WAIvB,OAAO,MAAM,EAAE,GAAG,CAAC,2DAE3B,QAAQ,GAAG,CAAC;;;;;EAsChB,CAAC"}
@@ -19,7 +19,26 @@ const fetcher = (url, options) => {
19
19
  }
20
20
  return mutate(url, init);
21
21
  };
22
- export const useMutation = (url, method = "POST", options) => {
22
+ /**
23
+ * This hook is used to execute API requests for data mutation, such as POST, DELETE, PUT, etc.
24
+ */
25
+ export const useMutation = (
26
+ /**
27
+ * The URL to send the request to. If the URL does not start with "http",
28
+ * it will be prefixed with the API base URL.
29
+ */
30
+ url,
31
+ /**
32
+ * The HTTP method to use for the request. Defaults to "POST".
33
+ */
34
+ method = "POST",
35
+ /**
36
+ * The configuration object for the mutation.
37
+ * @see [useSWRMutation](https://swr.vercel.app/docs/mutation#api)
38
+ *
39
+ * @link https://swr.vercel.app/docs/mutation#api
40
+ */
41
+ options) => {
23
42
  const apiBaseUrl = useConfig("apiBaseUrl");
24
43
  let fullUrl = url;
25
44
  if (!url.startsWith("http")) {
@@ -30,7 +49,15 @@ export const useMutation = (url, method = "POST", options) => {
30
49
  const { trigger, data, error, reset, isMutating } = useSWRMutation(fullUrl,
31
50
  // method === "POST" ? fetcher : deleteFetcher,
32
51
  fetcher, options);
33
- const mutation = async (data, params, options) => {
52
+ const mutation = async (
53
+ /**
54
+ * The data to send with the request.
55
+ */
56
+ data,
57
+ /**
58
+ * The query parameters to send with the request.
59
+ */
60
+ params, options) => {
34
61
  let newUrl = url;
35
62
  if (typeof params === "object" && Object.keys(params).length) {
36
63
  let search = new URLSearchParams(params);
@@ -1,14 +1,40 @@
1
- import { type drawOptions } from "./services/painter/basePaint";
2
- export { type drawOptions } from "./services/painter/basePaint";
1
+ import { type DrawOptions } from "./services/painter/basePaint";
3
2
  /**
4
3
  * Generates a poster image based on position information. You can set the size, background color, font color, font size, and content position of the poster.
5
- * @returns
4
+ * @example
5
+ * ```tsx
6
+ * const { ref, toDataURL, toBlob, download, copy } = usePoster({
7
+ * backgroundColor: "#0b8c70",
8
+ * backgroundImg: "/images/poster_bg.png",
9
+ * color: "rgba(255, 255, 255, 0.98)",
10
+ * profitColor: "rgb(0,181,159)",
11
+ * ...
12
+ * });
6
13
  */
7
- export declare const usePoster: (trage: HTMLCanvasElement, options: drawOptions) => {
14
+ export declare const usePoster: (data: DrawOptions, options?: {
15
+ /**
16
+ * The ratio of the poster
17
+ */
18
+ ratio?: number;
19
+ }) => {
8
20
  readonly error: Error | null;
21
+ readonly ref: (ref: HTMLCanvasElement | null) => void;
9
22
  /**
10
23
  * Converts the poster to a data URL
11
24
  */
12
25
  readonly toDataURL: (type?: string, encoderOptions?: number) => string;
26
+ /**
27
+ * Converts the poster to a blob
28
+ */
29
+ readonly toBlob: (type?: string, encoderOptions?: number) => Promise<Blob | null>;
30
+ /**
31
+ * Downloads the poster as an image
32
+ */
33
+ readonly download: (filename: string, type?: string, encoderOptions?: number) => void;
34
+ /**
35
+ * Browser if supports copy image to clipboard
36
+ */
37
+ readonly canCopy: boolean;
38
+ readonly copy: () => Promise<void>;
13
39
  };
14
40
  //# sourceMappingURL=usePoster.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"usePoster.d.ts","sourceRoot":"","sources":["../src/usePoster.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAGhE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE;;;GAGG;AACH,eAAO,MAAM,SAAS,UAIb,iBAAiB,WAIf,WAAW;;IAyClB;;OAEG;;CAGN,CAAC"}
1
+ {"version":3,"file":"usePoster.d.ts","sourceRoot":"","sources":["../src/usePoster.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAIhE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS,SAId,WAAW,YACP;IACR;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;wBA6DiB,iBAAiB,GAAG,IAAI;IAkDxC;;OAEG;gCA3EqB,MAAM,mBAAmB,MAAM;IA6EvD;;OAEG;6BApEK,MAAM,mBAAmB,MAAM,KAAG,QAAQ,IAAI,GAAG,IAAI,CAAC;IAsE9D;;OAEG;kCAjDQ,MAAM,SAAQ,MAAM,mBAAiC,MAAM;IAmDtE;;OAEG;;;CAIN,CAAC"}