@everymatrix/player-bonus-card 1.0.15 → 1.0.69
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/es2015/player-bonus-card.cjs +1 -0
- package/es2015/player-bonus-card.js +16 -0
- package/package.json +14 -34
- package/README.md +0 -30
- package/dist/player-bonus-card.js +0 -2
- package/dist/player-bonus-card.js.map +0 -1
- package/index.html +0 -21
- package/index.js +0 -1
- package/public/favicon.png +0 -0
- package/public/reset.css +0 -48
- package/rollup.config.js +0 -67
- package/src/PlayerBonusCard.svelte +0 -181
- package/src/i18n.js +0 -27
- package/src/index.ts +0 -4
- package/src/translations.js +0 -68
- package/stories/PlayerBonusCard.stories.js +0 -13
- package/tsconfig.json +0 -6
package/index.html
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset='utf-8'>
|
|
5
|
-
<meta name='viewport' content='width=device-width,initial-scale=1'>
|
|
6
|
-
|
|
7
|
-
<title>
|
|
8
|
-
player-bonus-card
|
|
9
|
-
</title>
|
|
10
|
-
<link rel="stylesheet" href="public/reset.css">
|
|
11
|
-
<script src='dist/player-bonus-card.js'></script>
|
|
12
|
-
</head>
|
|
13
|
-
|
|
14
|
-
<body>
|
|
15
|
-
|
|
16
|
-
<div class="webcomponent">
|
|
17
|
-
<player-bonus-card></player-bonus-card>
|
|
18
|
-
</div>
|
|
19
|
-
|
|
20
|
-
</body>
|
|
21
|
-
</html>
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import './dist/player-bonus-card.js';
|
package/public/favicon.png
DELETED
|
Binary file
|
package/public/reset.css
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/* http://meyerweb.com/eric/tools/css/reset/
|
|
2
|
-
v2.0 | 20110126
|
|
3
|
-
License: none (public domain)
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
html, body, div, span, applet, object, iframe,
|
|
7
|
-
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
|
8
|
-
a, abbr, acronym, address, big, cite, code,
|
|
9
|
-
del, dfn, em, img, ins, kbd, q, s, samp,
|
|
10
|
-
small, strike, strong, sub, sup, tt, var,
|
|
11
|
-
b, u, i, center,
|
|
12
|
-
dl, dt, dd, ol, ul, li,
|
|
13
|
-
fieldset, form, label, legend,
|
|
14
|
-
table, caption, tbody, tfoot, thead, tr, th, td,
|
|
15
|
-
article, aside, canvas, details, embed,
|
|
16
|
-
figure, figcaption, footer, header, hgroup,
|
|
17
|
-
menu, nav, output, ruby, section, summary,
|
|
18
|
-
time, mark, audio, video {
|
|
19
|
-
margin: 0;
|
|
20
|
-
padding: 0;
|
|
21
|
-
border: 0;
|
|
22
|
-
font-size: 100%;
|
|
23
|
-
font: inherit;
|
|
24
|
-
vertical-align: baseline;
|
|
25
|
-
}
|
|
26
|
-
/* HTML5 display-role reset for older browsers */
|
|
27
|
-
article, aside, details, figcaption, figure,
|
|
28
|
-
footer, header, hgroup, menu, nav, section {
|
|
29
|
-
display: block;
|
|
30
|
-
}
|
|
31
|
-
body {
|
|
32
|
-
line-height: 1;
|
|
33
|
-
}
|
|
34
|
-
ol, ul {
|
|
35
|
-
list-style: none;
|
|
36
|
-
}
|
|
37
|
-
blockquote, q {
|
|
38
|
-
quotes: none;
|
|
39
|
-
}
|
|
40
|
-
blockquote:before, blockquote:after,
|
|
41
|
-
q:before, q:after {
|
|
42
|
-
content: '';
|
|
43
|
-
content: none;
|
|
44
|
-
}
|
|
45
|
-
table {
|
|
46
|
-
border-collapse: collapse;
|
|
47
|
-
border-spacing: 0;
|
|
48
|
-
}
|
package/rollup.config.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import svelte from 'rollup-plugin-svelte';
|
|
2
|
-
import commonjs from '@rollup/plugin-commonjs';
|
|
3
|
-
import resolve from '@rollup/plugin-node-resolve';
|
|
4
|
-
import serve from 'rollup-plugin-dev-server';
|
|
5
|
-
import livereload from 'rollup-plugin-livereload';
|
|
6
|
-
import { terser } from 'rollup-plugin-terser';
|
|
7
|
-
import sveltePreprocess from 'svelte-preprocess';
|
|
8
|
-
import typescript from '@rollup/plugin-typescript';
|
|
9
|
-
import uglify from 'rollup-plugin-uglify';
|
|
10
|
-
import image from '@rollup/plugin-image';
|
|
11
|
-
|
|
12
|
-
const production = process.env.NODE_ENV == 'production';
|
|
13
|
-
const dev = process.env.NODE_ENV == 'development';
|
|
14
|
-
|
|
15
|
-
export default {
|
|
16
|
-
input: 'src/index.ts',
|
|
17
|
-
output: {
|
|
18
|
-
sourcemap: true,
|
|
19
|
-
format: 'umd',
|
|
20
|
-
name: 'app',
|
|
21
|
-
file: 'dist/player-bonus-card.js',
|
|
22
|
-
},
|
|
23
|
-
plugins: [
|
|
24
|
-
svelte({
|
|
25
|
-
preprocess: sveltePreprocess(),
|
|
26
|
-
compilerOptions: {
|
|
27
|
-
// @TODO check generate and hydratable
|
|
28
|
-
// generate: 'ssr',
|
|
29
|
-
// hydratable: true,
|
|
30
|
-
// enable run-time checks when not in production
|
|
31
|
-
customElement: true,
|
|
32
|
-
dev: !production
|
|
33
|
-
}
|
|
34
|
-
}),
|
|
35
|
-
image(),
|
|
36
|
-
commonjs(),
|
|
37
|
-
resolve({
|
|
38
|
-
browser: true,
|
|
39
|
-
dedupe: ['svelte']
|
|
40
|
-
}),
|
|
41
|
-
dev && serve({
|
|
42
|
-
open: true,
|
|
43
|
-
verbose: true,
|
|
44
|
-
allowCrossOrigin: true,
|
|
45
|
-
historyApiFallback: false,
|
|
46
|
-
host: 'localhost',
|
|
47
|
-
port: 5050,
|
|
48
|
-
}),
|
|
49
|
-
dev && livereload({ watch: ['', 'dist'] }),
|
|
50
|
-
typescript({
|
|
51
|
-
sourceMap: !production,
|
|
52
|
-
inlineSources: !production,
|
|
53
|
-
}),
|
|
54
|
-
// If we're building for production (npm run build
|
|
55
|
-
// instead of npm run dev), minify
|
|
56
|
-
production &&
|
|
57
|
-
terser({
|
|
58
|
-
output: {
|
|
59
|
-
comments: "all"
|
|
60
|
-
},
|
|
61
|
-
}),
|
|
62
|
-
production && uglify.uglify()
|
|
63
|
-
],
|
|
64
|
-
watch: {
|
|
65
|
-
clearScreen: false
|
|
66
|
-
}
|
|
67
|
-
};
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
<svelte:options tag={null} />
|
|
2
|
-
<script lang="ts">
|
|
3
|
-
import { getDevice } from 'rvhelper';
|
|
4
|
-
import { _, addNewMessages, setLocale } from './i18n';
|
|
5
|
-
import { PlayerBonusCardTranslations } from './translations';
|
|
6
|
-
|
|
7
|
-
import moment from 'moment';
|
|
8
|
-
|
|
9
|
-
export let bonuswalletid:string = '';
|
|
10
|
-
export let bonusdate:string = '';
|
|
11
|
-
export let bonusstatus:string = '';
|
|
12
|
-
export let bonusname:string = '';
|
|
13
|
-
export let bonustype:string = '';
|
|
14
|
-
export let bonusamount:string = '';
|
|
15
|
-
export let bonuswageringamount:string = '';
|
|
16
|
-
export let bonusremainingamount:string = '';
|
|
17
|
-
export let bonuscurrency:string = '';
|
|
18
|
-
export let lang:string = 'en';
|
|
19
|
-
export let translationUrl:string = '';
|
|
20
|
-
|
|
21
|
-
let userAgent:string = window.navigator.userAgent;
|
|
22
|
-
let isMobile:boolean = (getDevice(userAgent) === 'PC') ? false : true;
|
|
23
|
-
|
|
24
|
-
let bonusTypeText:string = '';
|
|
25
|
-
|
|
26
|
-
const setTranslationUrl = ():void => {
|
|
27
|
-
let url:string = translationUrl;
|
|
28
|
-
|
|
29
|
-
fetch(url).then((res:any) => res.json())
|
|
30
|
-
.then((res) => {
|
|
31
|
-
Object.keys(res).forEach((item:any):void => {
|
|
32
|
-
addNewMessages(item, res[item]);
|
|
33
|
-
});
|
|
34
|
-
}).catch((err:any) => {
|
|
35
|
-
console.log(err);
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Object.keys(PlayerBonusCardTranslations).forEach((item:any) => {
|
|
41
|
-
addNewMessages(item, PlayerBonusCardTranslations[item]);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
const bonusTypeRewrite = () => {
|
|
45
|
-
bonusTypeText = bonustype;
|
|
46
|
-
|
|
47
|
-
if (bonusTypeText === 'freeRound') {
|
|
48
|
-
bonusTypeText = 'Free Spins';
|
|
49
|
-
} else if (bonusTypeText === 'freeBet') {
|
|
50
|
-
bonusTypeText = 'Free Bet';
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const deleteBonus = () => {
|
|
55
|
-
window.postMessage({ type: 'DisableScroll'}, window.location.href);
|
|
56
|
-
window.postMessage({ type: 'DeleteActiveBonus', bonuswalletid }, window.location.href);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const initialLoad = () => {
|
|
60
|
-
setLocale(lang);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
$: lang && initialLoad();
|
|
64
|
-
$: bonustype && bonusTypeRewrite();
|
|
65
|
-
$: translationUrl && setTranslationUrl();
|
|
66
|
-
</script>
|
|
67
|
-
|
|
68
|
-
<div class="BonusCard" part="BonusCard">
|
|
69
|
-
<div class="BonusCardInfo" part="BonusCardInfo">
|
|
70
|
-
<div class="BonusCardRow" part="BonusCardRow">
|
|
71
|
-
<p class="BonusCardRowTitle" part="BonusCardRowTitle">{$_('bonusCard.date')} <span>{moment(bonusdate).format('DD/MM/YYYY h:mm A')}</span></p>
|
|
72
|
-
<p class="BonusCardRowText BonusCardStatus TextCapitalize {bonusstatus === 'active' || bonusstatus === 'released' ? 'StatusActive' : ''} {bonusstatus === 'expired' ? 'StatusExpired' : ''} {bonusstatus === 'forfeited' ? 'StatusForfeited' : ''}"
|
|
73
|
-
part="BonusCardRowText BonusCardStatus TextCapitalize {bonusstatus === 'active' || bonusstatus === 'released' ? 'StatusActive' : ''} {bonusstatus === 'expired' ? 'StatusExpired' : ''} {bonusstatus === 'forfeited' ? 'StatusForfeited' : ''}">{bonusstatus}</p>
|
|
74
|
-
</div>
|
|
75
|
-
<div class="BonusCardRow" part="BonusCardRow">
|
|
76
|
-
<p class="BonusCardRowTitle" part="BonusCardRowTitle">{$_('bonusCard.bonusName')}</p>
|
|
77
|
-
<p class="BonusCardRowText" part="BonusCardRowText">{bonusname}</p>
|
|
78
|
-
</div>
|
|
79
|
-
<div class="BonusCardRow" part="BonusCardRow">
|
|
80
|
-
<p class="BonusCardRowTitle" part="BonusCardRowTitle">{$_('bonusCard.bonusType')}</p>
|
|
81
|
-
<p class="BonusCardRowText TextCapitalize" part="BonusCardRowText TextCapitalize">{bonusTypeText}</p>
|
|
82
|
-
</div>
|
|
83
|
-
{#if bonusamount}
|
|
84
|
-
<div class="BonusCardRow" part="BonusCardRow">
|
|
85
|
-
<p class="BonusCardRowTitle" part="BonusCardRowTitle">{$_('bonusCard.bonusAmount')}</p>
|
|
86
|
-
<p class="BonusCardRowText" part="BonusCardRowText">{bonusamount} {bonuscurrency}</p>
|
|
87
|
-
</div>
|
|
88
|
-
{/if}
|
|
89
|
-
{#if bonuswageringamount}
|
|
90
|
-
<div class="BonusCardRow" part="BonusCardRow">
|
|
91
|
-
<p class="BonusCardRowTitle" part="BonusCardRowTitle">{$_('bonusCard.wageringAmount')}</p>
|
|
92
|
-
<p class="BonusCardRowText" part="BonusCardRowText">{bonuswageringamount} {bonuscurrency}</p>
|
|
93
|
-
</div>
|
|
94
|
-
{/if}
|
|
95
|
-
{#if bonusremainingamount}
|
|
96
|
-
<div class="BonusCardRow" part="BonusCardRow">
|
|
97
|
-
<p class="BonusCardRowTitle" part="BonusCardRowTitle">{$_('bonusCard.remainingBonus')}</p>
|
|
98
|
-
<p class="BonusCardRowText" part="BonusCardRowText">{bonusremainingamount} {bonuscurrency}</p>
|
|
99
|
-
</div>
|
|
100
|
-
{/if}
|
|
101
|
-
</div>
|
|
102
|
-
{#if bonusstatus === 'active'}
|
|
103
|
-
<button class="DeleteBonus {isMobile ? 'DeleteBonusMobile' : ''}" part="DeleteBonus {isMobile ? 'DeleteBonusMobile' : ''}" on:click={deleteBonus}>{$_('bonusCard.forfeitBonus')}</button>
|
|
104
|
-
{/if}
|
|
105
|
-
</div>
|
|
106
|
-
|
|
107
|
-
<style lang="scss">
|
|
108
|
-
|
|
109
|
-
:host {
|
|
110
|
-
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.BonusCard {
|
|
114
|
-
background-color: var(--emfe-w-color-white, #FFFFFF);
|
|
115
|
-
padding: 10px 20px 20px;
|
|
116
|
-
border-radius: 5px;
|
|
117
|
-
box-shadow: 0px 3px 12px var(--emfe-w-color-gray-100, #E6E6E6);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
.BonusCardRow {
|
|
121
|
-
display: flex;
|
|
122
|
-
justify-content: space-between;
|
|
123
|
-
align-items: center;
|
|
124
|
-
padding: 2px 10px;
|
|
125
|
-
font-size: 14px;
|
|
126
|
-
.BonusCardRowTitle {
|
|
127
|
-
color: var(--emfe-w-color-black, #000000);
|
|
128
|
-
font-weight: 700;
|
|
129
|
-
span {
|
|
130
|
-
font-weight: 400;
|
|
131
|
-
color: var(--emfe-w-color-gray-300, #58586B);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
.BonusCardRowText {
|
|
135
|
-
color: var(--emfe-w-color-gray-300, #58586B);
|
|
136
|
-
&.BonusCardStatus {
|
|
137
|
-
font-weight: 700;
|
|
138
|
-
color: var(--emfe-w-color-black, #000000);
|
|
139
|
-
}
|
|
140
|
-
&.StatusActive {
|
|
141
|
-
color: #0AA543;
|
|
142
|
-
}
|
|
143
|
-
&.StatusExpired {
|
|
144
|
-
color: #FD2839;
|
|
145
|
-
}
|
|
146
|
-
&.StatusForfeited {
|
|
147
|
-
color: #fd8c2d;
|
|
148
|
-
}
|
|
149
|
-
&.TextCapitalize {
|
|
150
|
-
text-transform: capitalize;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
&:nth-child(even) {
|
|
154
|
-
background-color: var(--emfe-w-color-gray-50, #F9F8F8);
|
|
155
|
-
border-radius: 5px;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
.DeleteBonus {
|
|
160
|
-
background: var(--emfe-w-color-primary, #D0046C);
|
|
161
|
-
border: 1px solid var(--emfe-w-color-primary, #D0046C);
|
|
162
|
-
color: var(--emfe-w-color-white, #FFFFFF);
|
|
163
|
-
cursor: pointer;
|
|
164
|
-
border-radius: 5px;
|
|
165
|
-
width: 50%;
|
|
166
|
-
height: 44px;
|
|
167
|
-
font-size: 15px;
|
|
168
|
-
text-transform: uppercase;
|
|
169
|
-
text-align: center;
|
|
170
|
-
transition-duration: 0.3s;
|
|
171
|
-
box-sizing: border-box;
|
|
172
|
-
padding: 10px;
|
|
173
|
-
margin-top: 10px;
|
|
174
|
-
&.DeleteBonusMobile {
|
|
175
|
-
width: 100%;
|
|
176
|
-
}
|
|
177
|
-
&:active {
|
|
178
|
-
background: var(--emfe-w-color-primary-600, #99034F);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
</style>
|
package/src/i18n.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
dictionary,
|
|
3
|
-
locale,
|
|
4
|
-
addMessages,
|
|
5
|
-
_
|
|
6
|
-
} from 'svelte-i18n';
|
|
7
|
-
|
|
8
|
-
function setupI18n({ withLocale: _locale, translations }) {
|
|
9
|
-
locale.subscribe((data) => {
|
|
10
|
-
if (data == null) {
|
|
11
|
-
dictionary.set(translations);
|
|
12
|
-
locale.set(_locale);
|
|
13
|
-
}
|
|
14
|
-
}); // maybe we will need this to make sure that the i18n is set up only once
|
|
15
|
-
/*dictionary.set(translations);
|
|
16
|
-
locale.set(_locale);*/
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function addNewMessages(lang, dict) {
|
|
20
|
-
addMessages(lang, dict);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function setLocale(_locale) {
|
|
24
|
-
locale.set(_locale);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export { _, setupI18n, addNewMessages, setLocale };
|
package/src/index.ts
DELETED
package/src/translations.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
export const PlayerBonusCardTranslations = {
|
|
2
|
-
en: {
|
|
3
|
-
bonusCard: {
|
|
4
|
-
date: `Granted date:`,
|
|
5
|
-
bonusName: `Bonus Name`,
|
|
6
|
-
bonusType: `Bonus Type`,
|
|
7
|
-
bonusAmount: `Bonus Amount`,
|
|
8
|
-
wageringAmount: `Wagering Amount`,
|
|
9
|
-
remainingBonus: `Remaining Bonus Amount`,
|
|
10
|
-
forfeitBonus: `Forfeit Bonus`
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
zh: {
|
|
14
|
-
bonusCard: {
|
|
15
|
-
date: `授予日期:`,
|
|
16
|
-
bonusName: `獎金名稱`,
|
|
17
|
-
bonusType: `獎金類型`,
|
|
18
|
-
bonusAmount: `獎金金額`,
|
|
19
|
-
wageringAmount: `投注金額`,
|
|
20
|
-
remainingBonus: `剩餘紅利金額`,
|
|
21
|
-
forfeitBonus: `沒收獎金`
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
fr: {
|
|
25
|
-
bonusCard: {
|
|
26
|
-
date: `Date d'attribution:`,
|
|
27
|
-
bonusName: `Nom du bonus`,
|
|
28
|
-
bonusType: `Type de bonus`,
|
|
29
|
-
bonusAmount: `Montant du bonus`,
|
|
30
|
-
wageringAmount: `Montant de la mise`,
|
|
31
|
-
remainingBonus: `Montant du bonus restant`,
|
|
32
|
-
forfeitBonus: `Supprimer le bonus`
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
ro: {
|
|
36
|
-
bonusCard: {
|
|
37
|
-
date: `Dată Alocare:`,
|
|
38
|
-
bonusName: `Nume bonus`,
|
|
39
|
-
bonusType: `Tip de bonus`,
|
|
40
|
-
bonusAmount: `Sumă`,
|
|
41
|
-
wageringAmount: `Sumă de pariat`,
|
|
42
|
-
remainingBonus: `Bonus rămas`,
|
|
43
|
-
forfeitBonus: `Anulează bonusul`
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
es: {
|
|
47
|
-
bonusCard: {
|
|
48
|
-
date: `Fecha de entrega del bono:`,
|
|
49
|
-
bonusName: `Nombre del bono`,
|
|
50
|
-
bonusType: `Tipo de bono`,
|
|
51
|
-
bonusAmount: `Cantidad del bono`,
|
|
52
|
-
wageringAmount: `Cantidad de apuesta`,
|
|
53
|
-
remainingBonus: `Cantidad de bonificación restante`,
|
|
54
|
-
forfeitBonus: `Bono de pérdida`
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
pt: {
|
|
58
|
-
bonusCard: {
|
|
59
|
-
date: `Data de atribuição do bônus:`,
|
|
60
|
-
bonusName: `Nome do bônus`,
|
|
61
|
-
bonusType: `Tipo de bônus`,
|
|
62
|
-
bonusAmount: `Valor do bônus`,
|
|
63
|
-
wageringAmount: `Valor da aposta`,
|
|
64
|
-
remainingBonus: `Valor do bônus restante`,
|
|
65
|
-
forfeitBonus: `Bônus de Perda`
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { html } from 'lit-element';
|
|
2
|
-
|
|
3
|
-
import PlayerBonusCard from '../src/PlayerBonusCard';
|
|
4
|
-
|
|
5
|
-
// This default export determines where your story goes in the story list
|
|
6
|
-
export default {
|
|
7
|
-
title: 'PlayerBonusCard',
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
// 👇 We create a “template” of how args map to rendering
|
|
11
|
-
const PlayerBonusCard = ({ aProperty }) => html`<player-bonus-card></player-bonus-card>`;
|
|
12
|
-
|
|
13
|
-
export const FirstStory = PlayerBonusCard.bind({});
|