feat: cash cassettes edit wizard w/ 4 cassettes support

This commit is contained in:
André Sá 2021-11-17 19:13:08 +00:00
parent 8456ef7ac9
commit 6444b20a8c
9 changed files with 513 additions and 6 deletions

View file

@ -5,11 +5,13 @@ import * as R from 'ramda'
import React, { useState } from 'react'
import * as Yup from 'yup'
import { IconButton } from 'src/components/buttons'
import { Table as EditableTable } from 'src/components/editableTable'
import { CashOut, CashIn } from 'src/components/inputs/cashbox/Cashbox'
import { NumberInput, CashCassetteInput } from 'src/components/inputs/formik'
import TitleSection from 'src/components/layout/TitleSection'
import { EmptyTable } from 'src/components/table'
import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'
import { ReactComponent as ReverseHistoryIcon } from 'src/styling/icons/circle buttons/history/white.svg'
import { ReactComponent as HistoryIcon } from 'src/styling/icons/circle buttons/history/zodiac.svg'
import { fromNamespace } from 'src/utils/config'
@ -17,6 +19,7 @@ import { fromNamespace } from 'src/utils/config'
import styles from './CashCassettes.styles.js'
import CashCassettesFooter from './CashCassettesFooter'
import CashboxHistory from './CashboxHistory'
import Wizard from './Wizard/Wizard'
const useStyles = makeStyles(styles)
@ -122,6 +125,8 @@ const CashCassettes = () => {
const [showHistory, setShowHistory] = useState(false)
const { data } = useQuery(GET_MACHINES_AND_CONFIG)
const [wizard, setWizard] = useState(false)
const [machineId, setMachineId] = useState('')
const machines = R.path(['machines'])(data) ?? []
const config = R.path(['config'])(data) ?? {}
@ -145,9 +150,7 @@ const CashCassettes = () => {
machines
)
const onSave = (
...[, { id, cashbox, cassette1, cassette2, cassette3, cassette4 }]
) => {
const onSave = (id, cashbox, cassette1, cassette2, cassette3, cassette4) => {
const oldCashboxCount = cashboxCounts[id]
if (cashbox < oldCashboxCount) {
createBatch({
@ -226,6 +229,23 @@ const CashCassettes = () => {
1
)
elements.push({
name: 'edit',
header: 'Edit',
width: 87,
view: (value, { id }) => {
return (
<IconButton
onClick={() => {
setMachineId(id)
setWizard(true)
}}>
<EditIcon />
</IconButton>
)
}
})
return (
<>
<TitleSection
@ -244,12 +264,9 @@ const CashCassettes = () => {
<EditableTable
error={error?.message}
name="cashboxes"
enableEdit
enableEditText="Update"
stripeWhen={isCashOutDisabled}
elements={elements}
data={machines}
save={onSave}
validationSchema={ValidationSchema}
tbodyWrapperClass={classes.tBody}
/>
@ -270,6 +287,18 @@ const CashCassettes = () => {
bills={bills}
deviceIds={deviceIds}
/>
{wizard && (
<Wizard
machine={R.find(R.propEq('id', machineId), machines)}
cashoutSettings={getCashoutSettings(machineId)}
onClose={() => {
setWizard(false)
}}
error={error?.message}
save={onSave}
locale={locale}
/>
)}
</>
)
}

View file

@ -0,0 +1,103 @@
import * as R from 'ramda'
import React, { useState } from 'react'
import * as Yup from 'yup'
import Modal from 'src/components/Modal'
import WizardSplash from './WizardSplash'
import WizardStep from './WizardStep'
const MODAL_WIDTH = 554
const MODAL_HEIGHT = 520
const CASHBOX_DEFAULT_CAPACITY = 500
const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
const [{ step, config }, setState] = useState({
step: 0,
config: { active: true }
})
const numberOfCassettes = machine.numberOfCassettes
const numberOfCassetteSteps = R.isEmpty(cashoutSettings)
? 0
: numberOfCassettes
const LAST_STEP = numberOfCassetteSteps + 1
const title = `Update counts`
const isLastStep = step === LAST_STEP
const onContinue = it => {
const cashbox = config?.wasCashboxEmptied === 'YES' ? 0 : machine?.cashbox
console.log('Wizard.js:Wizard:it', it)
if (isLastStep) {
save(
machine.id,
parseInt(cashbox),
parseInt(it[1] ?? 0),
parseInt(it[2] ?? 0),
parseInt(it[3] ?? 0),
parseInt(it[4] ?? 0)
)
return onClose()
}
const newConfig = R.merge(config, it)
setState({
step: step + 1,
config: newConfig
})
}
const makeCassetteSteps = R.pipe(
R.range(1),
R.map(i => ({
type: `cassette ${i}`,
schema: Yup.object().shape({
[i]: Yup.number()
.required()
.min(0)
.max(CASHBOX_DEFAULT_CAPACITY)
})
}))
)
const steps = R.prepend(
{
type: 'cashbox',
schema: Yup.object().shape({
wasCashboxEmptied: Yup.string().required()
})
},
makeCassetteSteps(numberOfCassetteSteps + 1)
)
return (
<Modal
title={step === 0 ? null : title}
handleClose={onClose}
width={MODAL_WIDTH}
height={MODAL_HEIGHT}
open={true}>
{step === 0 && (
<WizardSplash name={machine?.name} onContinue={() => onContinue()} />
)}
{step !== 0 && (
<WizardStep
step={step}
name={machine?.name}
machine={machine}
cashoutSettings={cashoutSettings}
cassetteCapacity={CASHBOX_DEFAULT_CAPACITY}
error={error}
lastStep={isLastStep}
steps={steps}
fiatCurrency={locale.fiatCurrency}
onContinue={onContinue}
/>
)}
</Modal>
)
}
export default Wizard

View file

@ -0,0 +1,81 @@
import { makeStyles } from '@material-ui/core'
import React from 'react'
import { Button } from 'src/components/buttons'
import { H1, P, Info2 } from 'src/components/typography'
import filledCassettes from 'src/styling/icons/cassettes/both-filled.svg'
import { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/comet.svg'
import { comet } from 'src/styling/variables'
const styles = {
button: {
margin: [[35, 'auto', 0, 'auto']]
},
modalContent: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
flex: 1,
padding: [[0, 34]]
},
splashTitle: {
marginTop: 15
},
warningInfo: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
marginTop: 15
},
warningIcon: {
width: 25,
height: 25,
marginRight: 8,
display: 'block'
},
warningText: {
flexBasis: '100%',
flexGrow: 1
},
machineName: {
margin: [[5, 0]],
color: comet
}
}
const useStyles = makeStyles(styles)
const WizardSplash = ({ name, onContinue }) => {
const classes = useStyles()
return (
<div className={classes.modalContent}>
<img width="148" height="196" alt="cassette" src={filledCassettes}></img>
<H1 className={classes.splashTitle} noMargin>
Update counts
</H1>
<Info2 className={classes.machineName} noMargin>
{name}
</Info2>
<div className={classes.warningInfo}>
<WarningIcon className={classes.warningIcon} />
<P noMargin className={classes.warningText}>
Before updating counts on Lamassu Admin, make sure you've done it
before on the machines.
</P>
</div>
<div className={classes.warningInfo}>
<WarningIcon className={classes.warningIcon} />
<P noMargin className={classes.warningText}>
For cash-out cassettes, please make sure you've removed the remaining
bills before adding the new ones.
</P>
</div>
<Button className={classes.button} onClick={onContinue}>
Get started
</Button>
</div>
)
}
export default WizardSplash

View file

@ -0,0 +1,289 @@
import { makeStyles } from '@material-ui/core'
import classnames from 'classnames'
import { Formik, Form, Field } from 'formik'
import * as R from 'ramda'
import React from 'react'
import Stepper from 'src/components/Stepper'
import { Tooltip } from 'src/components/Tooltip'
import { Button } from 'src/components/buttons'
import { Cashbox } from 'src/components/inputs/cashbox/Cashbox'
import { NumberInput, RadioGroup } from 'src/components/inputs/formik'
import { Info2, H4, P, Info1 } from 'src/components/typography'
import cashbox from 'src/styling/icons/cassettes/acceptor-left.svg'
import cassetteOne from 'src/styling/icons/cassettes/dispenser-1.svg'
import cassetteTwo from 'src/styling/icons/cassettes/dispenser-2.svg'
import tejo3CassetteOne from 'src/styling/icons/cassettes/tejo/3-cassettes/3-cassettes-open-1-left.svg'
import tejo3CassetteTwo from 'src/styling/icons/cassettes/tejo/3-cassettes/3-cassettes-open-2-left.svg'
import tejo3CassetteThree from 'src/styling/icons/cassettes/tejo/3-cassettes/3-cassettes-open-3-left.svg'
import tejo4CassetteOne from 'src/styling/icons/cassettes/tejo/4-cassettes/4-cassettes-open-1-left.svg'
import tejo4CassetteTwo from 'src/styling/icons/cassettes/tejo/4-cassettes/4-cassettes-open-2-left.svg'
import tejo4CassetteThree from 'src/styling/icons/cassettes/tejo/4-cassettes/4-cassettes-open-3-left.svg'
import tejo4CassetteFour from 'src/styling/icons/cassettes/tejo/4-cassettes/4-cassettes-open-4-left.svg'
import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'
import { comet } from 'src/styling/variables'
const styles = {
content: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
flex: 1,
paddingBottom: 32
},
titleDiv: {
marginBottom: 32
},
title: {
margin: [[0, 0, 12, 0]],
color: comet
},
stepImage: {
width: 148,
height: 196
},
form: {
paddingBottom: 95
},
verticalAlign: {
display: 'flex',
flexDirection: 'column'
},
horizontalAlign: {
display: 'flex',
flexDirection: 'row'
},
centerAlignment: {
alignItems: 'center'
},
lineAlignment: {
alignItems: 'baseline'
},
fullWidth: {
margin: [[0, 'auto']],
flexBasis: 'auto'
},
formWrapper: {
flexBasis: '100%',
display: 'flex',
justifyContent: 'center'
},
submit: {
float: 'right'
},
cashboxBills: {
marginRight: 5
},
cassetteCashbox: {
width: 40,
height: 35
},
cassetteFormTitle: {
marginTop: 18
},
cassetteFormTitleContent: {
marginLeft: 10,
marginRight: 25
},
smBottomMargin: {
marginBottom: 25
},
fiatTotal: {
color: comet
}
}
const useStyles = makeStyles(styles)
const cassetesArtworks = (numberOfCassettes, step) =>
[
[cassetteOne, cassetteTwo],
[tejo3CassetteOne, tejo3CassetteTwo, tejo3CassetteThree],
[tejo4CassetteOne, tejo4CassetteTwo, tejo4CassetteThree, tejo4CassetteFour]
][numberOfCassettes - 2][step - 2]
const WizardStep = ({
step,
name,
machine,
cashoutSettings,
cassetteCapacity,
error,
lastStep,
steps,
fiatCurrency,
onContinue
}) => {
const classes = useStyles()
const label = lastStep ? 'Finish' : 'Confirm'
const stepOneRadioOptions = [
{ display: 'Yes', code: 'YES' },
{ display: 'No', code: 'NO' }
]
const cassetteField = `cassette${step - 1}`
const numberOfCassettes = machine.numberOfCassettes
const originalCassetteCount = machine?.[cassetteField]
const cassetteDenomination = cashoutSettings?.[cassetteField]
const cassetteCount = values => values[`${step - 1}`] || originalCassetteCount
const cassetteTotal = values => cassetteCount(values) * cassetteDenomination
const getPercentage = R.pipe(
cassetteCount,
count => 100 * (count / cassetteCapacity),
R.clamp(0, 100)
)
return (
<div className={classes.content}>
<div className={classes.titleDiv}>
<Info2 className={classes.title}>{name}</Info2>
<Stepper steps={steps.length} currentStep={step} />
</div>
{step === 1 && (
<Formik
validateOnBlur={false}
validateOnChange={false}
onSubmit={onContinue}
initialValues={{ wasCashboxEmptied: '' }}
enableReinitialize
validationSchema={steps[step - 1].schema}>
{({ values }) => (
<Form>
<div
className={classnames(classes.horizontalAlign, classes.form)}>
<img
className={classes.stepImage}
alt="cassette"
src={cashbox}></img>
<div className={classes.formWrapper}>
<div
className={classnames(
classes.verticalAlign,
classes.fullWidth
)}>
<H4 noMargin>Did you empty the cash-in box?</H4>
<Field
component={RadioGroup}
name="wasCashboxEmptied"
options={stepOneRadioOptions}
className={classes.horizontalAlign}
/>
<div
className={classnames(
classes.horizontalAlign,
classes.centerAlignment
)}>
<P>Since previous update</P>
<Tooltip width={215}>
<P>
Number of bills inside the cashbox, since the last
cashbox changes.
</P>
</Tooltip>
</div>
<div
className={classnames(
classes.horizontalAlign,
classes.lineAlignment
)}>
<Info1 noMargin className={classes.cashboxBills}>
{machine?.cashbox}
</Info1>
<P noMargin>accepted bills</P>
</div>
</div>
</div>
</div>
<Button className={classes.submit} type="submit">
{label}
</Button>
</Form>
)}
</Formik>
)}
{step > 1 && (
<Formik
validateOnBlur={false}
validateOnChange={false}
onSubmit={onContinue}
initialValues={{ 1: '', 2: '', 3: '', 4: '' }}
enableReinitialize
validationSchema={steps[step - 1].schema}>
{({ values }) => (
<Form>
<div
className={classnames(classes.horizontalAlign, classes.form)}>
<img
className={classes.stepImage}
alt="cassette"
src={cassetesArtworks(numberOfCassettes, step)}></img>
<div className={classes.formWrapper}>
<div
className={classnames(
classes.verticalAlign,
classes.fullWidth
)}>
<div
className={classnames(
classes.horizontalAlign,
classes.smBottomMargin
)}>
<div
className={classnames(
classes.horizontalAlign,
classes.cassetteFormTitle
)}>
<TxOutIcon />
<H4
className={classes.cassetteFormTitleContent}
noMargin>
Cash-out {step - 1} (dispenser)
</H4>
</div>
<Cashbox
className={classes.cassetteCashbox}
percent={getPercentage(values)}
cashOut
/>
</div>
<H4 noMargin>Refill bill count</H4>
<div
className={classnames(
classes.horizontalAlign,
classes.lineAlignment
)}>
<Field
component={NumberInput}
decimalPlaces={0}
width={50}
placeholder={originalCassetteCount.toString()}
name={step - 1}
className={classes.cashboxBills}
/>
<P>
{cassetteDenomination} {fiatCurrency} bills loaded
</P>
</div>
<P noMargin className={classes.fiatTotal}>
= {cassetteTotal(values)} {fiatCurrency}
</P>
</div>
</div>
</div>
<Button className={classes.submit} type="submit">
{label}
</Button>
</Form>
)}
</Formik>
)}
</div>
)
}
export default WizardStep

View file

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 193.58 258.82"><defs><style>.cls-1{fill:#ebefff;}.cls-2{fill:#4b5fef;}.cls-3{fill:#1b2559;}.cls-4{fill:#48f694;}.cls-5{fill:#41de85;}.cls-6{fill:#00cd5a;}.cls-7{fill:#5a67ff;}.cls-8{fill:#7687ff;}.cls-9{fill:#ccd8ff;opacity:0.74;}.cls-10{fill:#dee5fc;opacity:0.8;}</style></defs><title>acceptor-left-filled</title><path class="cls-1" d="M122.26,105.88V258.82l61.13-35.29V70.59Z"/><g id="Drawer_2" data-name="Drawer 2"><g id="rest_of_drawer" data-name="rest of drawer"><polygon id="Inner_right_side" data-name="Inner right side" class="cls-2" points="71.32 97.69 152.83 144.75 189.58 123.53 71.32 55.25 71.32 97.69"/><polygon class="cls-3" points="171.21 134.14 171.21 112.92 162.13 107.68 162.13 139.43 171.21 134.14"/><polygon id="Back" class="cls-3" points="71.32 55.25 71.32 97.69 52.94 87.08 34.56 76.47 71.32 55.25"/><polygon class="cls-4" points="143.05 149.7 71.32 108.29 71.32 75.78 171.21 133.45 143.05 149.7"/><polygon class="cls-4" points="71.32 75.78 71.32 108.29 43.16 92.03 71.32 75.78"/><polygon class="cls-5" points="171.21 134.05 171.21 133.45 143.05 149.7 143.57 150 171.21 134.05"/><polygon class="cls-4" points="143.05 148.1 71.32 106.69 71.32 74.18 171.21 131.85 143.05 148.1"/><polygon class="cls-4" points="71.32 74.18 71.32 106.69 43.16 90.43 71.32 74.18"/><polygon class="cls-5" points="171.21 132.45 171.21 131.85 143.05 148.1 143.57 148.4 171.21 132.45"/><polygon class="cls-4" points="143.05 146.5 71.32 105.09 71.32 72.58 171.21 130.25 143.05 146.5"/><polygon class="cls-4" points="71.32 72.58 71.32 105.09 43.16 88.83 71.32 72.58"/><polygon class="cls-5" points="171.21 130.85 171.21 130.25 143.05 146.5 143.57 146.8 171.21 130.85"/><polygon class="cls-4" points="143.05 144.9 71.32 103.49 71.32 70.98 171.21 128.65 143.05 144.9"/><polygon class="cls-4" points="71.32 70.98 71.32 103.49 43.16 87.23 71.32 70.98"/><polygon class="cls-5" points="171.21 129.25 171.21 128.65 143.05 144.9 143.57 145.2 171.21 129.25"/><polygon class="cls-4" points="143.05 143.3 71.32 101.89 71.32 69.38 171.21 127.05 143.05 143.3"/><polygon class="cls-4" points="71.32 69.38 71.32 101.89 43.16 85.63 71.32 69.38"/><polygon class="cls-5" points="171.21 127.65 171.21 127.05 143.05 143.3 143.57 143.6 171.21 127.65"/><polygon class="cls-4" points="143.05 141.5 71.32 100.09 71.32 67.58 171.21 125.25 143.05 141.5"/><polygon class="cls-4" points="71.32 67.58 71.32 100.09 43.16 83.83 71.32 67.58"/><polygon class="cls-5" points="171.21 125.85 171.21 125.25 143.05 141.5 143.57 141.8 171.21 125.85"/><polygon class="cls-4" points="143.05 139.9 71.32 98.49 71.32 65.98 171.21 123.65 143.05 139.9"/><polygon class="cls-4" points="71.32 65.98 71.32 98.49 43.16 82.23 71.32 65.98"/><polygon class="cls-5" points="171.21 124.25 171.21 123.65 143.05 139.9 143.57 140.2 171.21 124.25"/><polygon class="cls-4" points="143.05 138.3 71.32 96.89 71.32 64.38 171.21 122.05 143.05 138.3"/><polygon class="cls-4" points="71.32 64.38 71.32 96.89 43.16 80.63 71.32 64.38"/><polygon class="cls-5" points="171.21 122.65 171.21 122.05 143.05 138.3 143.05 138.9 171.21 122.65"/><polygon class="cls-5" points="43.16 81.23 43.16 80.63 143.05 138.3 143.05 138.9 43.16 81.23"/><polygon class="cls-4" points="143.05 136.7 71.32 95.29 71.32 62.78 171.21 120.45 143.05 136.7"/><polygon class="cls-4" points="71.32 62.78 71.32 95.29 43.16 79.03 71.32 62.78"/><polygon class="cls-5" points="171.21 121.05 171.21 120.45 143.05 136.7 143.05 137.3 171.21 121.05"/><polygon class="cls-5" points="43.16 79.63 43.16 79.03 143.05 136.7 143.05 137.3 43.16 79.63"/><path class="cls-6" d="M97,94.41c5-2.9,13.26-2.9,18.29,0s5,7.66,0,10.56S102,107.88,97,105,91.92,97.32,97,94.41Z"/><polygon id="Outer_right_side" data-name="Outer right side" class="cls-2" points="152.83 252.94 30.57 182.35 30.57 76.47 152.83 147.06 152.83 252.94"/></g><g id="Front_drawer" data-name="Front drawer"><polygon id="Front" class="cls-7" points="193.58 123.53 152.83 147.06 152.83 252.94 193.58 229.41 193.58 123.53"/><path id="Top_edge" data-name="Top edge" class="cls-8" d="M71.32,52.94,30.57,76.47l122.26,70.59,40.75-23.53ZM34.56,76.47,71.32,55.25l118.26,68.28-36.75,21.22Z"/></g><line class="cls-4" x1="171.21" y1="122.85" x2="143.05" y2="139.1"/></g><polygon class="cls-1" points="132.45 182.36 132.45 135.29 183.4 105.88 183.4 70.59 122.26 105.88 122.26 126.47 122.26 126.47 122.26 138.4 122.26 141.18 122.26 141.18 122.26 258.82 132.45 252.94 132.45 194.12 132.45 182.36"/><polygon id="left_part_box" data-name="left part box" class="cls-9" points="122.26 105.88 0 35.29 0 188.23 122.26 258.82 122.26 105.88"/><polygon id="top_part_box" data-name="top part box" class="cls-10" points="183.4 70.59 61.13 0 0 35.29 122.26 105.88 183.4 70.59"/></svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

View file

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 193.58 258.82"><defs><style>.cls-1{fill:#4b5fef;}.cls-2{fill:#7687ff;}.cls-3{fill:#ebefff;}.cls-4{fill:#5a67ff;}.cls-5{fill:#1b2559;}.cls-6{fill:#ccd8ff;opacity:0.74;}.cls-7{fill:#dee5fc;opacity:0.8;}</style></defs><title>acceptor-left</title><polyline class="cls-1" points="71.32 97.69 124.25 128.26 161 107.04 71.32 55.25"/><polygon class="cls-2" points="163.01 105.88 71.32 52.94 30.57 76.47 122.26 129.41 163.01 105.88"/><polygon class="cls-3" points="183.4 70.59 183.39 223.53 122.26 258.82 122.26 105.88 183.4 70.59"/><polygon class="cls-4" points="193.58 123.53 152.83 147.06 152.83 252.94 193.58 229.41 193.58 123.53"/><polygon class="cls-1" points="152.83 252.94 132.45 241.18 132.45 135.29 152.83 147.06 152.83 252.94"/><polygon class="cls-1" points="122.26 235.3 30.56 182.36 30.57 76.47 122.26 129.41 122.26 235.3"/><polyline class="cls-2" points="132.45 135.29 152.83 147.06 193.58 123.53 173.21 111.77"/><polyline class="cls-1" points="134.45 134.14 152.83 144.75 189.58 123.53 171.21 112.92"/><polygon class="cls-5" points="171.21 112.92 171.21 134.14 152.83 144.75 134.45 134.14 171.21 112.92"/><polygon class="cls-5" points="71.32 55.25 71.32 97.69 52.94 87.08 34.56 76.47 71.32 55.25"/><polygon class="cls-6" points="122.26 105.88 0 35.29 0 188.23 122.26 258.82 122.26 105.88"/><polygon class="cls-7" points="183.4 70.59 61.13 0 0 35.29 122.26 105.88 183.4 70.59"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.1 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 193.58259 258.82261"><defs><style>.a,.l{fill:#fff;}.a,.d,.j{opacity:0.74;}.b,.j{fill:#ccd8ff;}.c{fill:#d2d8ff;}.d,.h{fill:#5a67ff;}.e{fill:#4b5fef;}.f{fill:#7687ff;}.g{fill:#ebefff;}.i{fill:#1b2559;}.k{fill:#dee5fc;opacity:0.8;}.m{fill:#aebaff;}</style></defs><title>v2-1</title><polygon class="a" points="163.012 164.703 50.942 100 10.189 123.53 122.263 188.236 163.012 164.703"/><polyline class="b" points="50.938 144.748 124.248 187.087 161.003 165.867 50.938 102.309"/><polygon class="c" points="122.261 235.293 10.186 170.589 10.189 123.53 122.261 188.234 122.261 235.293"/><polygon class="d" points="50.938 102.309 50.938 144.748 32.56 134.14 14.184 123.529 50.938 102.309"/><polyline class="e" points="71.317 97.688 124.249 128.264 161.004 107.044 71.317 55.25"/><polygon class="f" points="163.013 105.88 71.32 52.94 30.568 76.47 122.264 129.413 163.013 105.88"/><polygon class="g" points="183.396 70.586 183.393 223.529 122.26 258.823 122.264 105.88 183.396 70.586"/><polygon class="c" points="173.205 170.589 132.45 194.119 132.45 241.178 173.206 217.648 173.205 170.589"/><polygon class="h" points="193.582 123.529 152.827 147.059 152.827 194.118 193.583 170.587 193.582 123.529"/><polygon class="e" points="152.827 194.118 132.448 182.353 132.451 135.294 152.827 147.059 152.827 194.118"/><polygon class="e" points="122.261 176.47 30.565 123.529 30.568 76.47 122.261 129.411 122.261 176.47"/><polyline class="f" points="132.451 135.294 152.827 147.059 193.582 123.529 173.206 111.765"/><polyline class="e" points="134.451 134.138 152.827 144.749 189.582 123.53 171.205 112.918"/><polygon class="i" points="171.205 112.918 171.205 134.138 152.827 144.749 134.451 134.138 171.205 112.918"/><polygon class="i" points="71.317 55.25 71.317 97.688 52.939 87.081 34.563 76.47 71.317 55.25"/><polygon class="j" points="122.264 105.88 0.003 35.292 0 188.234 122.26 258.823 122.264 105.88"/><polygon class="k" points="183.396 70.586 61.131 0 0.003 35.292 122.264 105.88 183.396 70.586"/><path class="l" d="M168.29324,169.92639l4.38476-2.48092-.047-11.27756c-.00286-.68706.02246-1.38981.02246-1.38981l-.05636.03136a9.58844,9.58844,0,0,1-.86851,1.6315l-1.60382,2.44627-2.14443-1.10638,4.99115-7.6831,3.16791-1.75169.12588,17.06967,4.38476-2.48092.03567,3.146-12.39164,7.04027Z"/><path class="m" d="M148.46477,220.14711c0-6.74172,8.50209-12.68419,8.49771-16.33186-.00192-1.60372-1.23141-1.8737-2.76652-1.0152a9.13732,9.13732,0,0,0-3.27439,4.03233l-2.4568-.30054a14.47236,14.47236,0,0,1,6.01029-7.06167c3.19687-1.76715,5.91119-1.31443,5.917,2.12668.00994,5.85452-8.13556,11.56521-8.21069,15.11138l8.50983-4.9792.005,2.84873-12.078,7.13776A11.38945,11.38945,0,0,1,148.46477,220.14711Z"/></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 193.58151 258.82261"><defs><style>.a{fill:#4b5fef;}.b{fill:#7687ff;}.c{fill:#1b2559;}.d,.l{fill:#fff;}.d,.g,.i{opacity:0.74;}.e,.i{fill:#ccd8ff;}.f{fill:#d2d8ff;}.g,.k{fill:#5a67ff;}.h{fill:#ebefff;}.j{fill:#dee5fc;opacity:0.8;}</style></defs><title>v2-2</title><polyline class="a" points="71.318 156.512 124.25 187.087 161.005 165.867 71.318 114.073"/><polygon class="b" points="163.014 164.703 71.321 111.764 30.569 135.294 122.265 188.237 163.014 164.703"/><polygon class="a" points="122.262 235.294 30.565 182.353 30.569 135.294 122.262 188.235 122.262 235.294"/><polygon class="c" points="71.318 114.073 71.318 156.512 52.94 145.904 34.564 135.293 71.318 114.073"/><polygon class="d" points="163.014 96.672 50.943 31.969 10.191 55.499 122.265 120.205 163.014 96.672"/><polyline class="e" points="50.94 76.717 124.25 119.056 161.005 97.836 50.94 34.278"/><polygon class="f" points="122.262 167.262 10.188 102.558 10.191 55.499 122.262 120.203 122.262 167.262"/><polygon class="g" points="50.94 34.278 50.94 76.717 32.562 66.109 14.186 55.498 50.94 34.278"/><polygon class="h" points="183.396 70.586 183.393 223.529 122.26 258.823 122.264 105.88 183.396 70.586"/><polygon class="f" points="173.205 100 132.45 123.53 132.45 170.589 173.206 147.058 173.205 100"/><polygon class="i" points="122.264 105.88 0.003 35.292 0 188.234 122.26 258.823 122.264 105.88"/><polygon class="j" points="183.396 70.586 61.131 0 0.003 35.292 122.264 105.88 183.396 70.586"/><polygon class="k" points="193.581 182.354 152.826 205.884 152.826 252.943 193.582 229.412 193.581 182.354"/><polygon class="a" points="152.826 252.943 132.447 241.178 132.45 194.119 152.826 205.884 152.826 252.943"/><polyline class="b" points="132.45 194.119 152.826 205.884 193.581 182.354 173.205 170.59"/><polyline class="a" points="134.45 192.963 152.826 203.574 189.581 182.355 171.204 171.743"/><polygon class="c" points="171.204 171.743 171.204 192.963 152.826 203.574 134.45 192.963 171.204 171.743"/><path class="l" d="M166.09883,231.81817c0-7.5674,9.54391-14.23774,9.539-18.33135-.00216-1.80015-1.38174-2.10383-3.10553-1.13988-2.38357,1.33288-3.67542,4.52582-3.67542,4.52582l-2.758-.33729a16.24393,16.24393,0,0,1,6.74659-7.92622c3.58844-1.98344,6.6354-1.47533,6.642,2.38714.01116,6.57184-9.132,12.98179-9.21626,16.96152l9.5526-5.58888.00556,3.19778-13.55763,8.01151A12.67431,12.67431,0,0,1,166.09883,231.81817Z"/><path class="h" d="M148.45675,147.16772l4.92216-2.785-.0527-12.65868c-.00321-.77094.02451-1.5598.02451-1.5598l-.06255.03481a10.7746,10.7746,0,0,1-.976,1.83219l-1.79958,2.74486-2.407-1.241,5.60186-8.624,3.55679-1.9667.14131,19.16,4.92146-2.78457.04,3.53148-13.90939,7.90252Z"/></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB