@1001-digital/components 1.2.2 → 1.3.0
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/package.json +2 -22
- package/src/base/components/AppShell.vue +60 -0
- package/src/base/components/BottomNav.vue +44 -0
- package/src/base/components/Sidebar.vue +282 -0
- package/src/index.ts +3 -3
- package/src/evm/assets/wallets/coinbase.svg +0 -4
- package/src/evm/assets/wallets/in-app.svg +0 -5
- package/src/evm/assets/wallets/metamask.svg +0 -1
- package/src/evm/assets/wallets/phantom.svg +0 -4
- package/src/evm/assets/wallets/rabby.svg +0 -24
- package/src/evm/assets/wallets/rainbow.svg +0 -59
- package/src/evm/assets/wallets/safe.png +0 -0
- package/src/evm/assets/wallets/walletconnect.svg +0 -1
- package/src/evm/components/EvmAccount.vue +0 -28
- package/src/evm/components/EvmAvatar.vue +0 -62
- package/src/evm/components/EvmConnect.vue +0 -303
- package/src/evm/components/EvmConnectDialog.vue +0 -75
- package/src/evm/components/EvmConnectionStatus.vue +0 -13
- package/src/evm/components/EvmConnectorQR.vue +0 -86
- package/src/evm/components/EvmInAppWalletSetup.vue +0 -251
- package/src/evm/components/EvmMetaMaskQR.vue +0 -34
- package/src/evm/components/EvmProfile.vue +0 -186
- package/src/evm/components/EvmSeedPhraseInput.vue +0 -193
- package/src/evm/components/EvmSiwe.vue +0 -190
- package/src/evm/components/EvmSiweDialog.vue +0 -93
- package/src/evm/components/EvmSwitchNetwork.vue +0 -132
- package/src/evm/components/EvmTransactionFlow.vue +0 -353
- package/src/evm/components/EvmWalletConnectQR.vue +0 -13
- package/src/evm/components/EvmWalletConnectWallets.vue +0 -200
- package/src/evm/composables/base.ts +0 -7
- package/src/evm/composables/chainId.ts +0 -42
- package/src/evm/composables/ens.ts +0 -113
- package/src/evm/composables/gasPrice.ts +0 -37
- package/src/evm/composables/priceFeed.ts +0 -116
- package/src/evm/composables/siwe.ts +0 -89
- package/src/evm/composables/uri.ts +0 -12
- package/src/evm/composables/walletExplorer.ts +0 -130
- package/src/evm/config.ts +0 -35
- package/src/evm/connectors/inAppWallet.ts +0 -5
- package/src/evm/index.ts +0 -60
- package/src/evm/utils/addresses.ts +0 -6
- package/src/evm/utils/cache.ts +0 -59
- package/src/evm/utils/chains.ts +0 -32
- package/src/evm/utils/ens.ts +0 -116
- package/src/evm/utils/format-eth.ts +0 -15
- package/src/evm/utils/price.ts +0 -17
- package/src/evm/utils/siwe.ts +0 -70
- package/src/evm/utils/uri.ts +0 -24
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<EvmInAppWalletSetup
|
|
3
|
-
v-if="showInAppSetup"
|
|
4
|
-
@connected="onInAppConnected"
|
|
5
|
-
@back="showInAppSetup = false"
|
|
6
|
-
/>
|
|
7
|
-
<template v-else-if="errorMessage">
|
|
8
|
-
<Alert type="error">
|
|
9
|
-
{{ errorMessage }}
|
|
10
|
-
</Alert>
|
|
11
|
-
<Button
|
|
12
|
-
class="link muted small"
|
|
13
|
-
@click="resetConnection"
|
|
14
|
-
>
|
|
15
|
-
<Icon type="chevron-left" />
|
|
16
|
-
<span>Back</span>
|
|
17
|
-
</Button>
|
|
18
|
-
</template>
|
|
19
|
-
<EvmMetaMaskQR
|
|
20
|
-
v-else-if="metaMaskUri"
|
|
21
|
-
:uri="metaMaskUri"
|
|
22
|
-
@back="resetConnection"
|
|
23
|
-
/>
|
|
24
|
-
<EvmWalletConnectWallets
|
|
25
|
-
v-else-if="walletConnectUri"
|
|
26
|
-
:uri="walletConnectUri"
|
|
27
|
-
@back="resetConnection"
|
|
28
|
-
/>
|
|
29
|
-
<template v-else-if="isConnecting">
|
|
30
|
-
<Loading
|
|
31
|
-
:txt="`Waiting for ${connectingWallet} confirmation...`"
|
|
32
|
-
spinner
|
|
33
|
-
stacked
|
|
34
|
-
/>
|
|
35
|
-
</template>
|
|
36
|
-
<div
|
|
37
|
-
v-else
|
|
38
|
-
class="wallet-options"
|
|
39
|
-
>
|
|
40
|
-
<Button
|
|
41
|
-
v-for="connector in shownConnectors"
|
|
42
|
-
:key="connector.uid"
|
|
43
|
-
@click="() => login(connector)"
|
|
44
|
-
class="block choose-connector"
|
|
45
|
-
>
|
|
46
|
-
<img
|
|
47
|
-
v-if="ICONS[connector.name] || connector.icon"
|
|
48
|
-
:src="ICONS[connector.name] || connector.icon"
|
|
49
|
-
:alt="connector.name"
|
|
50
|
-
/>
|
|
51
|
-
<div
|
|
52
|
-
v-else
|
|
53
|
-
class="default-wallet-icon"
|
|
54
|
-
>
|
|
55
|
-
<Icon type="wallet" />
|
|
56
|
-
</div>
|
|
57
|
-
<span>{{ connector.name }}</span>
|
|
58
|
-
</Button>
|
|
59
|
-
<Button
|
|
60
|
-
v-if="wcConnector"
|
|
61
|
-
@click="loginWithSafe"
|
|
62
|
-
class="block choose-connector"
|
|
63
|
-
>
|
|
64
|
-
<img
|
|
65
|
-
:src="safeIcon"
|
|
66
|
-
alt="Safe"
|
|
67
|
-
/>
|
|
68
|
-
<span>Safe</span>
|
|
69
|
-
</Button>
|
|
70
|
-
<Button
|
|
71
|
-
v-if="inAppConnector"
|
|
72
|
-
@click="() => { emit('connecting'); showInAppSetup = true }"
|
|
73
|
-
class="block choose-connector"
|
|
74
|
-
>
|
|
75
|
-
<img
|
|
76
|
-
:src="inAppIcon"
|
|
77
|
-
alt="Seed Phrase"
|
|
78
|
-
/>
|
|
79
|
-
<span>In App</span>
|
|
80
|
-
</Button>
|
|
81
|
-
<Button
|
|
82
|
-
to="https://ethereum.org/wallets/"
|
|
83
|
-
target="_blank"
|
|
84
|
-
class="link muted small"
|
|
85
|
-
>
|
|
86
|
-
<Icon type="help" />
|
|
87
|
-
<span>New to wallets?</span>
|
|
88
|
-
</Button>
|
|
89
|
-
</div>
|
|
90
|
-
</template>
|
|
91
|
-
|
|
92
|
-
<script setup lang="ts">
|
|
93
|
-
import { ref, computed } from 'vue'
|
|
94
|
-
import type { Connector } from '@wagmi/vue'
|
|
95
|
-
import { useConnect, useConnectors, useChainId } from '@wagmi/vue'
|
|
96
|
-
import Button from '../../base/components/Button.vue'
|
|
97
|
-
import Icon from '../../base/components/Icon.vue'
|
|
98
|
-
import Alert from '../../base/components/Alert.vue'
|
|
99
|
-
import Loading from '../../base/components/Loading.vue'
|
|
100
|
-
import EvmMetaMaskQR from './EvmMetaMaskQR.vue'
|
|
101
|
-
import EvmWalletConnectWallets from './EvmWalletConnectWallets.vue'
|
|
102
|
-
import EvmInAppWalletSetup from './EvmInAppWalletSetup.vue'
|
|
103
|
-
|
|
104
|
-
import coinbaseIcon from '../assets/wallets/coinbase.svg'
|
|
105
|
-
import metamaskIcon from '../assets/wallets/metamask.svg'
|
|
106
|
-
import phantomIcon from '../assets/wallets/phantom.svg'
|
|
107
|
-
import rabbyIcon from '../assets/wallets/rabby.svg'
|
|
108
|
-
import rainbowIcon from '../assets/wallets/rainbow.svg'
|
|
109
|
-
import safeIcon from '../assets/wallets/safe.png'
|
|
110
|
-
import inAppIcon from '../assets/wallets/in-app.svg'
|
|
111
|
-
import walletconnectIcon from '../assets/wallets/walletconnect.svg'
|
|
112
|
-
|
|
113
|
-
const ICONS: Record<string, string> = {
|
|
114
|
-
'Base Account': coinbaseIcon,
|
|
115
|
-
MetaMask: metamaskIcon,
|
|
116
|
-
Phantom: phantomIcon,
|
|
117
|
-
'Rabby Wallet': rabbyIcon,
|
|
118
|
-
Rainbow: rainbowIcon,
|
|
119
|
-
Safe: safeIcon,
|
|
120
|
-
'In App': inAppIcon,
|
|
121
|
-
WalletConnect: walletconnectIcon,
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const PRIORITY: Record<string, number> = {
|
|
125
|
-
WalletConnect: 20,
|
|
126
|
-
'Base Account': 10,
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const emit = defineEmits<{
|
|
130
|
-
connecting: []
|
|
131
|
-
connected: []
|
|
132
|
-
}>()
|
|
133
|
-
|
|
134
|
-
const chainId = useChainId()
|
|
135
|
-
const connectors = useConnectors()
|
|
136
|
-
const { mutateAsync: connectAsync } = useConnect()
|
|
137
|
-
|
|
138
|
-
const inAppConnector = computed(() =>
|
|
139
|
-
connectors.value.find((c) => c.type === 'inAppWallet'),
|
|
140
|
-
)
|
|
141
|
-
const showInAppSetup = ref(false)
|
|
142
|
-
|
|
143
|
-
const shownConnectors = computed(() => {
|
|
144
|
-
const unique = Array.from(
|
|
145
|
-
new Map(
|
|
146
|
-
connectors.value?.map((connector) => [connector.name, connector]),
|
|
147
|
-
).values(),
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
const filtered =
|
|
151
|
-
unique.length > 1
|
|
152
|
-
? unique.filter(
|
|
153
|
-
(c) =>
|
|
154
|
-
c.id !== 'injected' && c.id !== 'safe' && c.type !== 'inAppWallet',
|
|
155
|
-
)
|
|
156
|
-
: unique.filter((c) => c.type !== 'inAppWallet')
|
|
157
|
-
|
|
158
|
-
return filtered.sort((a, b) => {
|
|
159
|
-
const priorityA = PRIORITY[a.name] ?? 5
|
|
160
|
-
const priorityB = PRIORITY[b.name] ?? 5
|
|
161
|
-
return priorityA - priorityB
|
|
162
|
-
})
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
const wcConnector = computed(() =>
|
|
166
|
-
connectors.value.find((c) => c.id === 'walletConnect'),
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
const errorMessage = ref('')
|
|
170
|
-
const isConnecting = ref(false)
|
|
171
|
-
const connectingWallet = ref('')
|
|
172
|
-
const metaMaskUri = ref('')
|
|
173
|
-
const walletConnectUri = ref('')
|
|
174
|
-
const safeDeepLink = ref(false)
|
|
175
|
-
|
|
176
|
-
const loginWithSafe = () => {
|
|
177
|
-
if (!wcConnector.value) return
|
|
178
|
-
safeDeepLink.value = true
|
|
179
|
-
login(wcConnector.value)
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const login = async (connector: Connector) => {
|
|
183
|
-
emit('connecting')
|
|
184
|
-
errorMessage.value = ''
|
|
185
|
-
isConnecting.value = true
|
|
186
|
-
connectingWallet.value = safeDeepLink.value ? 'Safe' : connector.name
|
|
187
|
-
metaMaskUri.value = ''
|
|
188
|
-
walletConnectUri.value = ''
|
|
189
|
-
|
|
190
|
-
const handleMetaMaskMessage = (event: { type: string; data?: unknown }) => {
|
|
191
|
-
if (event.type === 'display_uri' && typeof event.data === 'string') {
|
|
192
|
-
metaMaskUri.value = event.data
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const handleWcMessage = (event: { type: string; data?: unknown }) => {
|
|
197
|
-
if (event.type === 'display_uri' && typeof event.data === 'string') {
|
|
198
|
-
if (safeDeepLink.value) {
|
|
199
|
-
window.open(
|
|
200
|
-
`https://app.safe.global/wc?uri=${encodeURIComponent(event.data)}`,
|
|
201
|
-
'_blank',
|
|
202
|
-
'noreferrer',
|
|
203
|
-
)
|
|
204
|
-
} else {
|
|
205
|
-
walletConnectUri.value = event.data
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (connector.id === 'metaMaskSDK') {
|
|
211
|
-
connector.emitter.on('message', handleMetaMaskMessage)
|
|
212
|
-
} else if (connector.id === 'walletConnect') {
|
|
213
|
-
connector.emitter.on('message', handleWcMessage)
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
try {
|
|
217
|
-
await connectAsync({ connector, chainId: chainId.value })
|
|
218
|
-
|
|
219
|
-
emit('connected')
|
|
220
|
-
|
|
221
|
-
resetConnection()
|
|
222
|
-
} catch (error: unknown) {
|
|
223
|
-
isConnecting.value = false
|
|
224
|
-
metaMaskUri.value = ''
|
|
225
|
-
walletConnectUri.value = ''
|
|
226
|
-
safeDeepLink.value = false
|
|
227
|
-
|
|
228
|
-
const errorMsg = error instanceof Error ? error.message : ''
|
|
229
|
-
if (
|
|
230
|
-
errorMsg.includes('User rejected') ||
|
|
231
|
-
errorMsg.includes('rejected') ||
|
|
232
|
-
errorMsg.includes('denied')
|
|
233
|
-
) {
|
|
234
|
-
errorMessage.value = 'Connection cancelled. Please try again.'
|
|
235
|
-
} else {
|
|
236
|
-
errorMessage.value = 'Failed to connect. Please try again.'
|
|
237
|
-
}
|
|
238
|
-
console.error('Wallet connection error:', error)
|
|
239
|
-
} finally {
|
|
240
|
-
if (connector.id === 'metaMaskSDK') {
|
|
241
|
-
connector.emitter.off('message', handleMetaMaskMessage)
|
|
242
|
-
} else if (connector.id === 'walletConnect') {
|
|
243
|
-
connector.emitter.off('message', handleWcMessage)
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const resetConnection = () => {
|
|
249
|
-
errorMessage.value = ''
|
|
250
|
-
isConnecting.value = false
|
|
251
|
-
connectingWallet.value = ''
|
|
252
|
-
metaMaskUri.value = ''
|
|
253
|
-
walletConnectUri.value = ''
|
|
254
|
-
safeDeepLink.value = false
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const onInAppConnected = () => {
|
|
258
|
-
showInAppSetup.value = false
|
|
259
|
-
emit('connected')
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
const reset = () => {
|
|
263
|
-
resetConnection()
|
|
264
|
-
showInAppSetup.value = false
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
defineExpose({ reset })
|
|
268
|
-
</script>
|
|
269
|
-
|
|
270
|
-
<style scoped>
|
|
271
|
-
.wallet-options {
|
|
272
|
-
display: grid;
|
|
273
|
-
gap: var(--spacer);
|
|
274
|
-
|
|
275
|
-
button.choose-connector {
|
|
276
|
-
justify-content: flex-start;
|
|
277
|
-
padding-inline-start: var(--ui-padding-inline);
|
|
278
|
-
|
|
279
|
-
img,
|
|
280
|
-
.default-wallet-icon {
|
|
281
|
-
margin: -1rem 0 -1rem -0.6rem;
|
|
282
|
-
width: var(--size-5);
|
|
283
|
-
height: var(--size-5);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
.default-wallet-icon {
|
|
287
|
-
display: flex;
|
|
288
|
-
align-items: center;
|
|
289
|
-
justify-content: center;
|
|
290
|
-
background: var(--gray-z-2);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
span:last-child {
|
|
294
|
-
border-left: var(--border);
|
|
295
|
-
padding-left: var(--spacer-sm);
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
.link.muted {
|
|
301
|
-
justify-self: center;
|
|
302
|
-
}
|
|
303
|
-
</style>
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<Button
|
|
3
|
-
v-if="showConnect"
|
|
4
|
-
@click="open = true"
|
|
5
|
-
:class="className"
|
|
6
|
-
>
|
|
7
|
-
<slot>Connect Wallet</slot>
|
|
8
|
-
</Button>
|
|
9
|
-
<slot
|
|
10
|
-
v-else-if="isConnected"
|
|
11
|
-
name="connected"
|
|
12
|
-
:address="address"
|
|
13
|
-
>
|
|
14
|
-
<EvmAccount :address="address" />
|
|
15
|
-
</slot>
|
|
16
|
-
|
|
17
|
-
<Dialog
|
|
18
|
-
v-if="showConnect"
|
|
19
|
-
title="Connect Wallet"
|
|
20
|
-
v-model:open="open"
|
|
21
|
-
@closed="onClosed"
|
|
22
|
-
>
|
|
23
|
-
<EvmConnect
|
|
24
|
-
ref="connectRef"
|
|
25
|
-
@connected="onConnected"
|
|
26
|
-
/>
|
|
27
|
-
</Dialog>
|
|
28
|
-
</template>
|
|
29
|
-
|
|
30
|
-
<script setup lang="ts">
|
|
31
|
-
import { ref, computed, watch, onMounted } from 'vue'
|
|
32
|
-
import { useConnection } from '@wagmi/vue'
|
|
33
|
-
import Button from '../../base/components/Button.vue'
|
|
34
|
-
import Dialog from '../../base/components/Dialog.vue'
|
|
35
|
-
import EvmAccount from './EvmAccount.vue'
|
|
36
|
-
import EvmConnect from './EvmConnect.vue'
|
|
37
|
-
|
|
38
|
-
defineProps<{
|
|
39
|
-
className?: string
|
|
40
|
-
}>()
|
|
41
|
-
|
|
42
|
-
const emit = defineEmits<{
|
|
43
|
-
connected: [{ address: `0x${string}` | undefined }]
|
|
44
|
-
disconnected: []
|
|
45
|
-
}>()
|
|
46
|
-
|
|
47
|
-
const { address, isConnected } = useConnection()
|
|
48
|
-
|
|
49
|
-
const showConnect = computed(() => !isConnected.value)
|
|
50
|
-
const open = ref(false)
|
|
51
|
-
const connectRef = ref<InstanceType<typeof EvmConnect> | null>(null)
|
|
52
|
-
|
|
53
|
-
const onConnected = () => {
|
|
54
|
-
open.value = false
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const onClosed = () => {
|
|
58
|
-
connectRef.value?.reset()
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const check = () =>
|
|
62
|
-
isConnected.value
|
|
63
|
-
? emit('connected', { address: address.value })
|
|
64
|
-
: emit('disconnected')
|
|
65
|
-
|
|
66
|
-
watch(isConnected, () => {
|
|
67
|
-
check()
|
|
68
|
-
if (!isConnected.value) {
|
|
69
|
-
open.value = false
|
|
70
|
-
connectRef.value?.reset()
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
onMounted(() => check())
|
|
75
|
-
</script>
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<p>
|
|
3
|
-
<slot name="instruction">Scan the code in your wallet application</slot>
|
|
4
|
-
</p>
|
|
5
|
-
<div class="qr-frame">
|
|
6
|
-
<canvas ref="qrCanvas"></canvas>
|
|
7
|
-
</div>
|
|
8
|
-
<Button
|
|
9
|
-
@click="copyUri"
|
|
10
|
-
class="copy-uri tertiary small"
|
|
11
|
-
>
|
|
12
|
-
<Icon :type="isCopied ? 'check' : 'copy'" />
|
|
13
|
-
<span>
|
|
14
|
-
{{ isCopied ? 'Copied' : 'Copy Link' }}
|
|
15
|
-
</span>
|
|
16
|
-
</Button>
|
|
17
|
-
</template>
|
|
18
|
-
|
|
19
|
-
<script setup lang="ts">
|
|
20
|
-
import { ref, watch, onMounted } from 'vue'
|
|
21
|
-
import QRCode from 'qrcode'
|
|
22
|
-
import { useClipboard } from '@vueuse/core'
|
|
23
|
-
import Button from '../../base/components/Button.vue'
|
|
24
|
-
import Icon from '../../base/components/Icon.vue'
|
|
25
|
-
|
|
26
|
-
const props = defineProps<{
|
|
27
|
-
uri: string
|
|
28
|
-
}>()
|
|
29
|
-
|
|
30
|
-
const qrCanvas = ref<HTMLCanvasElement | null>(null)
|
|
31
|
-
const { copy, copied: isCopied } = useClipboard()
|
|
32
|
-
|
|
33
|
-
const generateQR = async () => {
|
|
34
|
-
if (!qrCanvas.value || !props.uri) return
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
await QRCode.toCanvas(qrCanvas.value, props.uri, {
|
|
38
|
-
width: 300,
|
|
39
|
-
margin: 2,
|
|
40
|
-
color: {
|
|
41
|
-
dark: '#000000',
|
|
42
|
-
light: '#FFFFFF',
|
|
43
|
-
},
|
|
44
|
-
})
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.error('Failed to generate QR code:', error)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const copyUri = () => copy(props.uri)
|
|
51
|
-
|
|
52
|
-
watch(() => props.uri, generateQR, { immediate: true })
|
|
53
|
-
|
|
54
|
-
onMounted(() => {
|
|
55
|
-
generateQR()
|
|
56
|
-
})
|
|
57
|
-
</script>
|
|
58
|
-
|
|
59
|
-
<style scoped>
|
|
60
|
-
p {
|
|
61
|
-
text-align: center;
|
|
62
|
-
@mixin ui-font;
|
|
63
|
-
color: var(--muted);
|
|
64
|
-
font-size: var(--font-sm);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.qr-frame {
|
|
68
|
-
background: white;
|
|
69
|
-
padding: var(--spacer-sm);
|
|
70
|
-
max-width: 15rem;
|
|
71
|
-
max-height: 15rem;
|
|
72
|
-
border: var(--border);
|
|
73
|
-
border-radius: var(--border-radius);
|
|
74
|
-
margin: 0 auto;
|
|
75
|
-
|
|
76
|
-
canvas {
|
|
77
|
-
width: 100% !important;
|
|
78
|
-
height: 100% !important;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.copy-uri {
|
|
83
|
-
width: fit-content;
|
|
84
|
-
margin: 0 auto;
|
|
85
|
-
}
|
|
86
|
-
</style>
|