diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 83b89b18cb31b1c87548dd99ef87d6468fbdd9c8..092fe79ee2bfaa18c2fc3663b2220e004ce92c98 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -39,8 +39,17 @@ backend test: reports: cobertura: coverage.xml +backend build: + before_script: + - python -V + image: python:3.9-buster + stage: tests and linting + script: + - pip install poetry + - poetry build + frontend test: - image: node:14-alpine + image: node:16-alpine stage: tests and linting script: - cd frontend @@ -51,10 +60,20 @@ frontend test: '/All files[^|]*\|[^|]*\s+([\d\.]+)/' frontend lint: - image: node:14-alpine + image: node:16-alpine stage: tests and linting script: - cd frontend - npm install -g npm@latest - npm ci - npm run lint + +frontend build: + image: node:16-alpine + stage: tests and linting + script: + - cd frontend + - npm install -g npm@latest + - NODE_ENV=production + - npm ci + - npm run build:no-env diff --git a/README.md b/README.md index b9b8f371b6c9c7021a05801e0c3b8572979ff899..de06cd08b3e72629700f69ee779ee41903319f86 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,13 @@ There are two scripts for adding data to the database: where the former uses randomized data, and the latter uses specific data useful in combination with the frontend. See the respective files for how to use them. +## Themes + +The application has three different themes: uio, uib and default. The default uses the palette found in Material UI, +while uio and uib sets a color scheme that matches the institution. + +To set the theme used update REACT_APP_THEME in frontend/.env. + ## Static type analysis Use [mypy](http://mypy-lang.org/) to run static type checks using type hints. diff --git a/frontend/public/index.html b/frontend/public/index.html index 6e242e17b7dac79acd27667a8ea8683a465a9fe4..979dbe86168f4c2ed54e40f548c0b1c76571757d 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -11,6 +11,9 @@ /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> + <link rel="preconnect" href="https://fonts.googleapis.com"> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> + <link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet"> <title>Guest Registration</title> </head> <body> diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json index 0df2f8ab9d4023a36df96b0cbff8e68cbc355835..b9adc25046857afec4bad67e76932c59a9cf43d7 100644 --- a/frontend/public/locales/en/common.json +++ b/frontend/public/locales/en/common.json @@ -94,7 +94,9 @@ "passportNumberRequired": "Passport number required", "mobilePhoneRequired": "Mobile phone is required", "startDateMustBeSet": "Start date must be set", - "startDateMustBeBeforeEndDate": "Start date has to be before end date" + "startDateMustBeBeforeEndDate": "Start date has to be before end date", + "passportNationalityAndNumber": "Both passport nationality and number need to be set", + "nationalIdOrPassport": "National ID or passport information need to be entered" }, "button": { "back": "Back", diff --git a/frontend/public/locales/nb/common.json b/frontend/public/locales/nb/common.json index a4859e3da01c67279912b74afa7a48178e2e0877..f9172a826454e4ca3ad311af0c0cb9ef5b8aae31 100644 --- a/frontend/public/locales/nb/common.json +++ b/frontend/public/locales/nb/common.json @@ -93,7 +93,9 @@ "passportNumberRequired": "Passnummer er obligatorisk", "mobilePhoneRequired": "Mobilnummer er obligatorisk", "startDateMustBeSet": "Startdato må være satt", - "startDateMustBeBeforeEndDate": "Startdato må være før sluttdato" + "startDateMustBeBeforeEndDate": "Startdato må være før sluttdato", + "passportNationalityAndNumber": "Både passnasjonalitet og nummer må være satt", + "nationalIdOrPassport": "Fødselsnummer eller passinformasjon må oppgis" }, "button": { "back": "Tilbake", diff --git a/frontend/public/locales/nn/common.json b/frontend/public/locales/nn/common.json index 966a2aba7412d6cd6eea82f36242cbfd6c9ad7b4..8f13f7c9a04acca248f6ca85251b8b7b26bc97c8 100644 --- a/frontend/public/locales/nn/common.json +++ b/frontend/public/locales/nn/common.json @@ -94,7 +94,9 @@ "passportNumberRequired": "Passnummer er obligatorisk", "mobilePhoneRequired": "Mobilnummer er obligatorisk", "startDateMustBeSet": "Startdato må vere satt", - "startDateMustBeBeforeEndDate": "Startdato må vere før sluttdato" + "startDateMustBeBeforeEndDate": "Startdato må vere før sluttdato", + "passportNationalityAndNumber": "Både passnasjonalitet og nummer må vere satt", + "nationalIdOrPassport": "Fødselsnummer eller passinformasjon må oppgjevast" }, "button": { "back": "Tilbake", diff --git a/frontend/src/components/button/index.tsx b/frontend/src/components/button/index.tsx index 255b7af8f01ad8b96e6e9a7bb1e9984ddbd076f7..f77b51e6dbe80e187e7e9fd9732a26b6ec571e63 100644 --- a/frontend/src/components/button/index.tsx +++ b/frontend/src/components/button/index.tsx @@ -8,11 +8,7 @@ interface IHrefButton { function HrefButton({ to, children }: IHrefButton) { return ( - <Button - variant="contained" - href={to} - sx={{ backgroundColor: 'theme.palette.secondary' }} - > + <Button variant="contained" href={to} color="secondary"> {children} </Button> ) diff --git a/frontend/src/components/button/linebutton.tsx b/frontend/src/components/button/linebutton.tsx index a5ec984a2ab7adc84a396576b829789fcf00771a..7ba63d3e62e2ffd32627a422ee79fb09e0a11e80 100644 --- a/frontend/src/components/button/linebutton.tsx +++ b/frontend/src/components/button/linebutton.tsx @@ -8,7 +8,7 @@ interface IHrefButton { function HrefLineButton({ to, children }: IHrefButton) { return ( - <Button href={to} sx={{ color: 'theme.palette.secondary' }}> + <Button href={to} color="secondary"> {children} </Button> ) diff --git a/frontend/src/components/form/error.tsx b/frontend/src/components/form/error.tsx deleted file mode 100644 index cba24612fde18d6089b5cb108e2c5dd4fdbbd491..0000000000000000000000000000000000000000 --- a/frontend/src/components/form/error.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import styled from '@emotion/styled/macro' - - -const StyledValidationError = styled.span` - color: "red" -` - -export default StyledValidationError \ No newline at end of file diff --git a/frontend/src/components/form/fnr.tsx b/frontend/src/components/form/fnr.tsx deleted file mode 100644 index ee7cd1f2a920bc3b443d11f4c5a084f0321b5065..0000000000000000000000000000000000000000 --- a/frontend/src/components/form/fnr.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react' - -import { UseFormReturn } from 'react-hook-form' -import { isValidFnr } from 'utils' - -interface FnrProps extends Partial<Pick<UseFormReturn, 'register'>> { - name: string - errors?: any -} - -function Fnr(props: FnrProps) { - const { register, name, errors } = props - if (register === undefined) { - return <></> - } - - return ( - <> - <input - type="text" - placeholder={name} - // eslint-disable-next-line react/jsx-props-no-spreading - {...register(name, { - required: 'Fnr is required', - validate: isValidFnr, - })} - id="fnr" - /> - {errors.fnr && errors.fnr.message} - {errors.fnr && errors.fnr.type === 'validate' && 'Invalid fnr'} - </> - ) -} - -Fnr.defaultProps = { - errors: {}, -} - -export default Fnr diff --git a/frontend/src/components/form/form.tsx b/frontend/src/components/form/form.tsx deleted file mode 100644 index 2964e7f2591152ec5e6fb2d5e83fe2ac40861538..0000000000000000000000000000000000000000 --- a/frontend/src/components/form/form.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react' -import { useForm } from 'react-hook-form' - -interface FormProps { - children: any - onSubmit: any -} - -export default function Form(props: FormProps) { - const { children, onSubmit } = props - const methods = useForm() - const { - handleSubmit, - formState: { errors }, - } = methods - return ( - <form onSubmit={handleSubmit(onSubmit)}> - {React.Children.map(children, (child) => - child.props.name - ? React.createElement(child.type, { - // eslint-disable-next-line react/jsx-props-no-spreading - ...{ - // eslint-disable-next-line react/jsx-props-no-spreading - ...child.props, - control: methods.control, - register: methods.register, - errors, - key: child.props.name, - }, - }) - : child - )} - </form> - ) -} diff --git a/frontend/src/components/form/index.tsx b/frontend/src/components/form/index.tsx deleted file mode 100644 index 1d3d7430ae22ba5e53a288393dc725ec272d84da..0000000000000000000000000000000000000000 --- a/frontend/src/components/form/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import Form from './form' -import Input from './input' -import Select from './select' -import Fnr from './fnr' - -export { Fnr, Form, Input, Select } diff --git a/frontend/src/components/form/input.tsx b/frontend/src/components/form/input.tsx deleted file mode 100644 index 4d589d2682b2f7d23945ef150c747bef24c759c0..0000000000000000000000000000000000000000 --- a/frontend/src/components/form/input.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React from 'react' -import styled from '@emotion/styled/macro' -import { UseFormReturn } from 'react-hook-form' - -interface InputProps - extends Partial<React.InputHTMLAttributes<HTMLInputElement>>, - Partial<UseFormReturn> { - name: string - errors?: any - type?: 'text' | 'email' | 'number' -} - -export const StyledInput = styled.input` - width: 50%; - border: 1px solid; - border-width: 0.013rem; - border-radius: 0.3rem; - border-color: #ccc; - box-shadow: inset 0 0 0 0.013rem #4d4d4d; - padding: 0.625rem; -` - -export const StyledLabel = styled.label` - display: block; - font-size: 1rem; - padding: 0.3rem 0 0.3rem 0; -` -function Input(props: InputProps) { - // eslint-disable-next-line react/jsx-props-no-spreading - const { register, name, errors, type, ...rest } = props - if (register === undefined) { - return <></> - } - // eslint-disable-next-line react/jsx-props-no-spreading - return <StyledInput {...register(name)} {...rest} /> -} - -Input.defaultProps = { - type: 'text', - errors: {}, -} - -export default Input diff --git a/frontend/src/components/form/select.tsx b/frontend/src/components/form/select.tsx deleted file mode 100644 index e5eadbd4a9ce5ad91738f41946c79404eb99132a..0000000000000000000000000000000000000000 --- a/frontend/src/components/form/select.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react' -import { UseFormReturn } from 'react-hook-form' - -interface SelectProps extends Partial<Pick<UseFormReturn, 'register'>> { - options: Array<string> - name: string - type?: 'text' | 'email' | 'number' -} - -function Select(props: SelectProps) { - const { register, options, name, ...rest } = props - if (register === undefined) { - return <></> - } - return ( - // eslint-disable-next-line react/jsx-props-no-spreading - <select {...register(name)} {...rest}> - {options.map((value) => ( - <option key={value} value={value}> - {value} - </option> - ))} - </select> - ) -} - -Select.defaultProps = { - type: 'text', -} - -export default Select diff --git a/frontend/src/components/link/index.tsx b/frontend/src/components/link/index.tsx deleted file mode 100644 index 6631dc9107520b7ca3cc8b8098f2d78dc0f0b6f2..0000000000000000000000000000000000000000 --- a/frontend/src/components/link/index.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import React from 'react' -import styled from '@emotion/styled/macro' - -interface IStyledLink { - external?: boolean - underline?: boolean - marginRight?: boolean - inheritColor?: boolean - noUnderline?: boolean -} - -interface ILink { - to: string - external?: boolean - children?: React.ReactNode - marginRight?: boolean - noExternalIcon?: boolean - mail?: boolean - inheritColor?: boolean - underline?: boolean - noUnderline?: boolean -} - -const externalLinkIcon = ( - <svg width="15.3" height="12.6" viewBox="0 0 17 14"> - <g fill="#0F748D" fillRule="evenodd"> - <path d="M13.044 8.157h-.607a.3.3 0 0 0-.218.082.276.276 0 0 0-.085.208v2.907c0 .4-.148.742-.445 1.027a1.493 1.493 0 0 1-1.072.427H2.73c-.417 0-.774-.143-1.071-.427a1.371 1.371 0 0 1-.446-1.027V3.796c0-.4.149-.742.446-1.026a1.493 1.493 0 0 1 1.071-.427h6.674a.302.302 0 0 0 .218-.082.277.277 0 0 0 .085-.209v-.581a.277.277 0 0 0-.085-.21.302.302 0 0 0-.218-.08H2.73c-.752 0-1.395.255-1.93.767-.533.511-.8 1.128-.8 1.848v7.558c0 .721.267 1.337.801 1.849a2.689 2.689 0 0 0 1.93.768h7.886c.752 0 1.395-.256 1.93-.768.534-.512.8-1.128.8-1.849V8.448a.276.276 0 0 0-.085-.21.302.302 0 0 0-.218-.081z" /> - <path d="M16.807.19a.596.596 0 0 0-.426-.173h-4.854a.596.596 0 0 0-.426.173.548.548 0 0 0-.18.409c0 .157.06.294.18.409l1.668 1.598-6.18 5.923a.281.281 0 0 0-.095.21c0 .078.031.148.094.208L7.67 9.983a.306.306 0 0 0 .436 0l6.18-5.923 1.67 1.599c.12.115.262.172.426.172a.596.596 0 0 0 .426-.172.547.547 0 0 0 .18-.409V.599a.548.548 0 0 0-.18-.409z" /> - </g> - </svg> -) - -const ExternalIcon = styled.span` - margin-left: 1.2rem; - position: relative; - top: 1px; - z-index: -1; -` - -const StyledLink = styled.a<IStyledLink>` - display: inline-flex; - align-items: center; -` -// TODO Put back when routes are set up -// const StyledRouterLink = styled(RouterLink)` -// ${baseInputStyles}; -// ` - -function Link(props: ILink) { - const { - children, - external, - to, - noExternalIcon, - mail, - underline, - marginRight, - inheritColor, - noUnderline, - } = props - - if (mail) { - return ( - <StyledLink - href={`mailto:${to}`} - external={external} - underline={underline} - marginRight={marginRight} - inheritColor={inheritColor} - noUnderline={noUnderline} - > - {children} - </StyledLink> - ) - } - - if (external) { - const urlRegex = /^((http|https):\/\/)/ - const href = urlRegex.test(to) ? to : `//${to}` - - return ( - <StyledLink - href={href} - target="_blank" - rel="noopener noreferrer" - external={external} - underline={underline} - marginRight={marginRight} - inheritColor={inheritColor} - noUnderline={noUnderline} - > - {children} - {!noExternalIcon && <ExternalIcon>{externalLinkIcon}</ExternalIcon>} - </StyledLink> - ) - } - - // TODO Use StyledRouterLink for internal links when routes are set up - // return ( - // <StyledRouterLink {...props}> - // {children} - // </StyledRouterLink> - // ) - - return ( - <StyledLink - external={external} - underline={underline} - marginRight={marginRight} - inheritColor={inheritColor} - noUnderline={noUnderline} - > - {children} - </StyledLink> - ) -} - -Link.defaultProps = { - external: false, - children: undefined, - marginRight: false, - noExternalIcon: false, - mail: false, - inheritColor: false, - underline: false, - noUnderline: false, -} - -export default Link diff --git a/frontend/src/components/link/link.test.tsx b/frontend/src/components/link/link.test.tsx deleted file mode 100644 index 0028d1af0f47f55b990bbc757c38a320f2e40499..0000000000000000000000000000000000000000 --- a/frontend/src/components/link/link.test.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' -import { render, waitFor, screen } from '@testing-library/react' -import Link from './index' - -describe('Tests for Link component', () => { - test('External link prefixes route link with //', async () => { - render(<Link external to="example.org" />) - - await waitFor(() => screen.getByRole('link')) - - expect(screen.getByRole('link')).toHaveAttribute('href', '//example.org') - }) -}) diff --git a/frontend/src/components/logobars/UiO.tsx b/frontend/src/components/logobars/UiO.tsx index a75a58bd0bbbcb3ef27dc4ceaa6ef90266bd4fb9..423ad25c1f958f2b0cd15cdc73e96013d6779497 100644 --- a/frontend/src/components/logobars/UiO.tsx +++ b/frontend/src/components/logobars/UiO.tsx @@ -23,7 +23,7 @@ function UiOLogoBar() { return ( <Box sx={{ - backgroundColor: (theme) => theme.greg.headerBackgroundColor, + backgroundColor: (theme) => theme.palette.primary.main, display: 'flex', justifyContent: 'center', }} diff --git a/frontend/src/components/page/page.tsx b/frontend/src/components/page/page.tsx index d07eb9f40ec78d7675726d95bff37049512401d7..b7e745976cddde97af835ca01405ac92e32a9ffc 100644 --- a/frontend/src/components/page/page.tsx +++ b/frontend/src/components/page/page.tsx @@ -6,7 +6,7 @@ import { styled } from '@mui/material/styles' import { Container } from '@mui/material' const StyledPageHeader = styled('h2')(({ theme }) => ({ - color: theme.greg.h2TextColor, + color: theme.greg.textWhite, fontSize: '3rem', fontWeight: 'bold', margin: '1rem 0 1rem 0', diff --git a/frontend/src/components/roleLine/index.tsx b/frontend/src/components/roleLine/index.tsx index 2cdf9cd1e957c16e8ce33fd914d33bd4041b7e33..583fdf03dd1706545e683dff368d5e58f5cb8c3c 100644 --- a/frontend/src/components/roleLine/index.tsx +++ b/frontend/src/components/roleLine/index.tsx @@ -26,6 +26,7 @@ const RoleLine = ({ role, pid }: RoleLineProps) => { <TableCell> <Button variant="contained" + color="secondary" component={Link} to={`/sponsor/guest/${pid}/roles/${role.id}`} > diff --git a/frontend/src/contexts/featureContext.ts b/frontend/src/contexts/featureContext.ts new file mode 100644 index 0000000000000000000000000000000000000000..0fd76a4e800c9e5483994834b9ad0a06cb9717f9 --- /dev/null +++ b/frontend/src/contexts/featureContext.ts @@ -0,0 +1,15 @@ +import { createContext, useContext } from 'react' + +export interface IFeatureContext { + // Controls whether the contact person at unit field is shown in the register new guest wizard + displayContactAtUnit: boolean + // Controls whether the optional field is shown in the register new guest wizard + displayComment: boolean +} + +export const FeatureContext = createContext<IFeatureContext>({ + displayContactAtUnit: true, + displayComment: true, +}) + +export const useFeatureContext = () => useContext(FeatureContext) diff --git a/frontend/src/contexts/index.ts b/frontend/src/contexts/index.ts index d6231cb0f551c506eac6042db83d5a4f601f1c01..c7483440839d9287712efcb094b305e4a826db75 100644 --- a/frontend/src/contexts/index.ts +++ b/frontend/src/contexts/index.ts @@ -1,3 +1,4 @@ import { UserContext, useUserContext } from './userContext' +import { FeatureContext } from './featureContext' -export { UserContext, useUserContext } +export { UserContext, useUserContext, FeatureContext } diff --git a/frontend/src/hooks/useGuest/index.tsx b/frontend/src/hooks/useGuest/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..b719ca0a3aec9073e5e6d556c8090ddd70af30b6 --- /dev/null +++ b/frontend/src/hooks/useGuest/index.tsx @@ -0,0 +1,52 @@ +import { FetchedRole, Guest } from 'interfaces' +import { useEffect, useState } from 'react' +import { parseRole } from 'utils' + +const useGuest = (pid: string) => { + const [guestInfo, setGuest] = useState<Guest>({ + pid: '', + first: '', + last: '', + email: '', + fnr: '', + mobile: '', + active: false, + registered: false, + verified: false, + roles: [], + }) + + const getPerson = async (id: string) => { + try { + const response = await fetch(`/api/ui/v1/person/${id}`) + const rjson = await response.json() + + if (response.ok) { + setGuest({ + pid: rjson.pid, + first: rjson.first, + last: rjson.last, + email: rjson.email, + mobile: rjson.mobile, + fnr: rjson.fnr, + active: rjson.active, + registered: rjson.registered, + verified: rjson.verified, + roles: rjson.roles.map((role: FetchedRole) => parseRole(role)), + }) + } + } catch (error) { + console.error(error) + } + } + const reloadGuestInfo = () => { + getPerson(pid) + } + useEffect(() => { + getPerson(pid) + }, []) + + return { guestInfo, reloadGuestInfo } +} + +export default useGuest diff --git a/frontend/src/hooks/useRoleTypes/index.tsx b/frontend/src/hooks/useRoleTypes/index.tsx index 0a61d01311038623c0769937dbbfc6e6703fc21c..2c8eec3d5019156c0debcbae4d7ee1af7d825fa0 100644 --- a/frontend/src/hooks/useRoleTypes/index.tsx +++ b/frontend/src/hooks/useRoleTypes/index.tsx @@ -19,7 +19,7 @@ function useRoleTypes(): RoleTypeData[] { setRoleTypes(JSON.parse(result)) }) .catch((error) => { - console.error(error) + console.debug(error) }) } diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index becf7b9f7675bec4c76f55837779dc279adbc1f6..6532d0cc78dfe24c6ba31242d36bb480a220afe3 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -11,19 +11,22 @@ import getTheme from 'themes' import App from 'routes' import { UserProvider } from 'providers' import reportWebVitals from './reportWebVitals' +import FeatureProvider from './providers/featureProvider' function appRoot() { return ( <React.StrictMode> <Router> <LocalizationProvider dateAdapter={AdapterDateFns}> - <ThemeProvider theme={getTheme()}> - <UserProvider> - <Suspense fallback={<CircularProgress />}> - <App /> - </Suspense> - </UserProvider> - </ThemeProvider> + <FeatureProvider> + <ThemeProvider theme={getTheme()}> + <UserProvider> + <Suspense fallback={<CircularProgress />}> + <App /> + </Suspense> + </UserProvider> + </ThemeProvider> + </FeatureProvider> </LocalizationProvider> </Router> </React.StrictMode> diff --git a/frontend/src/providers/featureProvider.tsx b/frontend/src/providers/featureProvider.tsx new file mode 100644 index 0000000000000000000000000000000000000000..962e46aa14d866dd640a5ded31bce38c039753c0 --- /dev/null +++ b/frontend/src/providers/featureProvider.tsx @@ -0,0 +1,32 @@ +import { FeatureContext } from 'contexts' +import React from 'react' +import { appInst } from '../appConfig' +import { IFeatureContext } from '../contexts/featureContext' + +type FeatureProviderProps = { + children: React.ReactNode +} + +function FeatureProvider(props: FeatureProviderProps) { + const { children } = props + + let features: IFeatureContext + switch (appInst) { + case 'uib': + features = { displayContactAtUnit: false, displayComment: false } + break + + case 'uio': + default: + features = { displayContactAtUnit: true, displayComment: true } + break + } + + return ( + <FeatureContext.Provider value={features}> + {children} + </FeatureContext.Provider> + ) +} + +export default FeatureProvider diff --git a/frontend/src/routes/components/footer.tsx b/frontend/src/routes/components/footer.tsx index f4b2799405e352b4120196bcb576fe3d6b40e2be..a4afc8529f94a5330c084d50ea42577c18e9600b 100644 --- a/frontend/src/routes/components/footer.tsx +++ b/frontend/src/routes/components/footer.tsx @@ -8,29 +8,22 @@ import { reponsibleOrganization, responsibleOrganizationLink } from 'appConfig' import { getFooterLogo } from './logos' const FooterWrapper = styled('footer')(({ theme }) => ({ - background: theme.greg.footerBackgroundColor, + background: theme.palette.primary.main, height: 'fit-content', padding: '0rem 3.5rem', marginTop: 'auto', })) const FooterSection = styled('section')({ - // header: { - // marginBottom: '0.5rem', - // fontSize: '1.5rem', - // }, - paddingLeft: '1rem', }) const ContentContainer = styled('div')(({ theme }) => ({ - // width: 'fit-content', fontSize: '1.5rem', - color: theme.greg.footerTextColor, + color: theme.palette.primary.main, display: 'flex', flexWrap: 'nowrap', justifyContent: 'space-between', - // margin: '0 1rem', padding: '1rem 0rem 1rem 0', })) diff --git a/frontend/src/routes/components/header.tsx b/frontend/src/routes/components/header.tsx index b692f893b6abd9cb0c6ab1c0a46707262072e7ba..378b45cf93b746c86976ebdd6a1570ed5efd618c 100644 --- a/frontend/src/routes/components/header.tsx +++ b/frontend/src/routes/components/header.tsx @@ -11,8 +11,8 @@ import UserInfo from 'routes/components/userInfo' import { getHeaderLogo } from './logos' const StyledHeader = styled('header')(({ theme }) => ({ - color: theme.greg.h1TextColor, - backgroundColor: theme.greg.headerBackgroundColor, + color: theme.greg.textWhite, + backgroundColor: theme.palette.primary.main, a: { textDecoration: 'none', @@ -41,7 +41,6 @@ const LogoContainer = styled('div')({ const Menu = styled('div')({ display: 'flex', - // listStyleType: 'none', flexDirection: 'row', alignItems: 'flex-end', fontSize: '1rem', @@ -60,7 +59,6 @@ const Header = () => { sx={{ paddingRight: '1.5rem', width: '7rem', - // minWidth: '10rem', }} > {getHeaderLogo()} diff --git a/frontend/src/routes/components/logos/index.tsx b/frontend/src/routes/components/logos/index.tsx index 89e268df43ae2566238280a0718346a93613b65b..7fd3f41cd4a274b514e8d98813a31ff977e09d55 100644 --- a/frontend/src/routes/components/logos/index.tsx +++ b/frontend/src/routes/components/logos/index.tsx @@ -1,8 +1,11 @@ import { useTranslation } from 'react-i18next' import { appInst } from 'appConfig' -import { ReactComponent as UiOLogoNo } from './uio-segl-full-neg-no.svg' -import { ReactComponent as UiOLogoEn } from './uio-segl-full-neg-en.svg' -import { ReactComponent as UiOAcronym } from './uio-logo-acronym-white.svg' +import { ReactComponent as UiOLogoNo } from './uio/uio-segl-full-neg-no.svg' +import { ReactComponent as UiOLogoEn } from './uio/uio-segl-full-neg-en.svg' +import { ReactComponent as UiOAcronym } from './uio/uio-logo-acronym-white.svg' + +import { ReactComponent as UiBLogoNo } from './uib/UiBlogo_hvit_v.svg' +import { ReactComponent as UiBLogoEn } from './uib/UiBlogo_Eng_white_left.svg' function getHeaderLogo() { switch (appInst) { @@ -25,7 +28,10 @@ function getFooterLogo() { } return <UiOLogoNo /> case 'uib': - return <></> + if (i18n.language === 'en') { + return <UiBLogoEn /> + } + return <UiBLogoNo /> default: return <></> } diff --git a/frontend/src/routes/components/logos/uib/UiBlogo_Eng_white_left.svg b/frontend/src/routes/components/logos/uib/UiBlogo_Eng_white_left.svg new file mode 100755 index 0000000000000000000000000000000000000000..0ebfd66ed2b730a3d6984074e0c58848e947f0dc --- /dev/null +++ b/frontend/src/routes/components/logos/uib/UiBlogo_Eng_white_left.svg @@ -0,0 +1,478 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="UiBlogo_grayscale" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" + y="0px" viewBox="0 0 411 99.2" style="enable-background:new 0 0 411 99.2;" xml:space="preserve"> +<style type="text/css"> + .st0{fill:#FFFFFF;} + .st1{fill:none;} +</style> +<g> + <path class="st0" d="M20.5,42.1c-0.6-0.1-1.8-0.3-2.2-0.2c-0.1,0-0.2,0.2-0.3,0.5L18,42.6c-0.1,0.1-0.2,0-0.2-0.1 + c0.1-0.4,0.2-0.8,0.2-1.2c0.1-0.4,0.1-0.7,0.2-1.1c0.1-0.1,0.2,0,0.3,0l0,0.3c0,0.3,0,0.5,0.2,0.6c0.3,0.2,1.5,0.4,2.1,0.5l1.2,0.2 + c0.9,0.2,1.8,0.5,2.3,1.2c0.4,0.5,0.5,1.3,0.4,2.1c-0.1,0.7-0.4,1.4-0.9,1.8c-0.5,0.5-1.3,0.6-2.6,0.4l-2.4-0.4 + c-1.1-0.2-1.3-0.2-1.4,0.4l-0.1,0.3c-0.1,0.1-0.2,0-0.2-0.1c0.1-0.5,0.2-0.9,0.3-1.3c0.1-0.4,0.1-0.8,0.2-1.3c0-0.1,0.2,0,0.3,0 + l0,0.3c-0.1,0.6,0.1,0.7,1.2,0.8l2.2,0.4c1.7,0.3,2.8,0,3.1-1.6c0.3-1.5-0.8-2.3-2.4-2.5L20.5,42.1z"/> + <path class="st0" d="M27.1,33.7c0.3,0.2,1.4,0.8,1.6,0.9c0,0,0.1,0.1,0,0.2c-0.2,0-0.7,0.1-2,0.4L23,36c-0.4,0.1-1.5,0.3-1.8,0.4 + l0,0c0.1,0.1,0.3,0.2,0.6,0.4l2,1.1c0.4,0.2,1.6,0.9,2,0.9c0.1,0,0.3-0.2,0.4-0.4l0.2-0.3c0.1,0,0.2,0.1,0.2,0.1 + c-0.2,0.4-0.4,0.7-0.6,1.1c-0.2,0.4-0.3,0.6-0.5,1c-0.1,0-0.2,0-0.2-0.1l0.1-0.3c0.1-0.2,0.1-0.4,0-0.5c-0.3-0.3-1.4-0.9-1.8-1.2 + l-2.6-1.5c-0.3-0.1-0.5-0.2-0.8-0.2c-0.2,0.1-0.4,0.2-0.5,0.4l-0.1,0.1c-0.1,0-0.2-0.1-0.2-0.1c0.2-0.4,0.5-0.9,0.6-1 + c0.1-0.1,0.2-0.3,0.2-0.4c0.6,0.1,2.4-0.3,2.9-0.4l1.5-0.3c1.1-0.2,1.8-0.4,2.5-0.6l0,0c0-0.1-0.2-0.1-0.4-0.2l-2-1.1 + c-0.4-0.2-1.6-0.9-2-0.9c-0.1,0-0.2,0.1-0.5,0.5l-0.1,0.1c-0.1,0-0.2-0.1-0.2-0.1c0.3-0.4,0.4-0.7,0.6-1.1c0.2-0.4,0.3-0.6,0.5-1 + c0.1,0,0.2,0,0.2,0.1l-0.1,0.1C23,31,23,31.2,23.1,31.3c0.2,0.3,1.4,1,1.8,1.2L27.1,33.7z"/> + <path class="st0" d="M27,28.4c-0.8-0.8-0.9-0.9-1.4-0.5l-0.2,0.2c-0.1,0-0.2-0.1-0.2-0.2c0.4-0.4,0.6-0.6,0.9-0.9 + c0.3-0.3,0.5-0.6,0.9-1c0.1,0,0.2,0.1,0.2,0.2l-0.2,0.2c-0.4,0.5-0.3,0.6,0.5,1.4l2.7,2.6c0.8,0.8,0.9,0.9,1.4,0.5l0.2-0.2 + c0.1,0,0.2,0.1,0.2,0.2c-0.4,0.4-0.6,0.6-0.9,0.9c-0.3,0.3-0.5,0.6-0.9,1c-0.1,0-0.2-0.1-0.2-0.2l0.2-0.2c0.4-0.5,0.3-0.6-0.5-1.4 + L27,28.4z"/> + <path class="st0" d="M30.7,24.3c-0.5-0.4-0.8-0.5-1.2-0.3l-0.2,0.1c-0.1,0-0.2-0.1-0.1-0.2c0.3-0.1,0.6-0.3,0.9-0.6 + c0.4-0.2,0.7-0.5,1.1-0.7c0.1,0,0.2,0.1,0.2,0.2l-0.1,0.1C31,23.2,31,23.3,31,23.4c0.1,0.1,0.5,0.5,1.2,1c1.1,0.8,2.1,1.5,3.2,2.3 + c-0.1-0.8-0.3-1.9-0.4-2.5c-0.1-0.8-0.3-2-0.4-2.5c0-0.2-0.1-0.3-0.1-0.4c0-0.1-0.2-0.1-0.5,0.1l-0.2,0.1c-0.1,0-0.2-0.2-0.1-0.2 + c0.3-0.1,0.6-0.3,0.9-0.6c0.3-0.2,0.6-0.4,0.8-0.6c0.1,0,0.2,0.1,0.2,0.2l-0.3,0.2c-0.2,0.2-0.3,0.3-0.3,0.6c0,0.6,0.1,1.5,0.3,2.7 + l0.2,1.4c0.2,1,0.4,2.3,0.5,2.9c0,0,0,0.1-0.1,0.1c0,0-0.1,0-0.2,0.1c-0.3-0.3-0.8-0.6-1.2-0.9L30.7,24.3z"/> + <path class="st0" d="M39.5,20.2c-0.3-1-0.4-1.2-1-1.1l-0.2,0c-0.1,0-0.1-0.2-0.1-0.3c0.4-0.1,0.8-0.2,1.2-0.3l1.9-0.5 + c0.6-0.2,1.2-0.3,1.4-0.4c0.1,0.2,0.4,0.9,0.5,1.3c0,0.1-0.2,0.1-0.2,0.1c-0.3-0.4-0.5-0.8-1-0.7c-0.2,0-0.6,0.1-1,0.2l-0.7,0.2 + c-0.3,0.1-0.3,0.1-0.2,0.5l0.6,2c0.1,0.3,0.1,0.3,0.4,0.2l0.6-0.2c0.4-0.1,0.7-0.2,0.8-0.3c0.1-0.1,0.2-0.2,0.1-0.4l0-0.4 + c0-0.1,0.2-0.1,0.3-0.1c0.1,0.2,0.1,0.6,0.2,1c0.1,0.4,0.3,0.7,0.3,1c0,0.1-0.2,0.1-0.3,0.1L43,21.7c-0.1-0.2-0.2-0.3-0.4-0.3 + c-0.2,0-0.4,0.1-0.8,0.2l-0.6,0.2c-0.3,0.1-0.3,0.1-0.3,0.4l0.4,1.4c0.2,0.5,0.3,0.9,0.5,1c0.2,0.1,0.4,0.1,1.3-0.1 + c0.8-0.2,1.1-0.3,1.2-0.5c0.2-0.2,0.3-0.6,0.4-1.2c0.1-0.1,0.2-0.1,0.3,0c0,0.4,0,1.2-0.1,1.5c-0.9,0.2-1.8,0.5-2.7,0.7l-0.9,0.3 + c-0.4,0.1-0.8,0.2-1.4,0.4c-0.1,0-0.1-0.2-0.1-0.2l0.3-0.1c0.6-0.2,0.6-0.4,0.3-1.4L39.5,20.2z"/> + <path class="st0" d="M47.8,18.6c0-1,0-1.2-0.5-1.2l-0.3,0c-0.1-0.1-0.1-0.2,0-0.3c0.6,0,1.3-0.1,2.3-0.1c0.6,0,1.3,0.1,1.7,0.3 + c0.5,0.3,0.9,0.7,0.9,1.5c0,1-0.8,1.5-1.3,1.7c-0.1,0.1,0,0.2,0.1,0.3c0.8,1.4,1.4,2.2,2.1,2.8c0.2,0.2,0.4,0.3,0.7,0.3 + c0.1,0,0.1,0.1,0,0.1c-0.1,0-0.3,0.1-0.5,0.1c-0.9,0-1.4-0.3-2.2-1.3c-0.3-0.4-0.7-1.1-1-1.6c-0.2-0.2-0.3-0.3-0.7-0.3 + c-0.5,0-0.5,0-0.5,0.2l0,1.3c0,1.1,0,1.2,0.6,1.3l0.2,0c0.1,0.1,0,0.2,0,0.3c-0.5,0-0.8,0-1.2,0c-0.4,0-0.8,0-1.3,0 + c-0.1,0-0.1-0.2,0-0.3l0.3,0c0.6-0.1,0.6-0.2,0.6-1.3L47.8,18.6z M48.6,20.1c0,0.2,0,0.3,0,0.3c0,0,0.2,0.1,0.7,0.1 + c0.4,0,0.8,0,1.1-0.3C50.7,20,51,19.7,51,19c0-0.8-0.5-1.6-1.7-1.6c-0.7,0-0.7,0-0.7,0.3L48.6,20.1z"/> + <path class="st0" d="M57.1,25.2c-0.8-0.3-1.3-0.7-1.4-0.9c-0.1-0.3,0-1,0.2-1.5c0.1-0.1,0.2,0,0.2,0c0,0.6,0.1,1.7,1.2,2 + c0.8,0.3,1.4-0.2,1.6-0.8c0.1-0.4,0.2-1-0.4-1.7l-0.8-0.9c-0.4-0.5-0.8-1.2-0.5-2.1c0.3-1,1.3-1.5,2.6-1.1c0.3,0.1,0.7,0.3,0.9,0.4 + c0.1,0.1,0.3,0.1,0.3,0.2c0,0.3-0.1,0.9-0.2,1.3c-0.1,0-0.2,0-0.3,0c0-0.5,0-1.3-1-1.6c-1-0.3-1.4,0.3-1.5,0.7 + c-0.2,0.6,0.2,1.2,0.5,1.5l0.6,0.8c0.5,0.6,0.9,1.4,0.6,2.3C59.5,25.2,58.4,25.7,57.1,25.2z"/> + <path class="st0" d="M65.4,23c0.6-0.9,0.7-1.1,0.2-1.5l-0.2-0.2c0-0.1,0.1-0.2,0.2-0.2c0.4,0.3,0.7,0.5,1.1,0.7 + c0.4,0.2,0.7,0.4,1.1,0.7c0,0.1,0,0.2-0.1,0.2l-0.2-0.1c-0.6-0.3-0.7-0.1-1.2,0.8l-2,3.2c-0.6,0.9-0.6,1.1-0.1,1.5l0.2,0.2 + c0,0.1-0.1,0.2-0.2,0.2c-0.4-0.3-0.7-0.5-1.1-0.7c-0.4-0.2-0.7-0.4-1.1-0.7c0-0.1,0-0.2,0.1-0.2l0.2,0.1c0.6,0.3,0.7,0.1,1.2-0.8 + L65.4,23z"/> + <path class="st0" d="M69.9,31.4c-0.8,0.7-0.9,0.9-0.5,1.4l0.2,0.3c0,0.1-0.1,0.2-0.2,0.2c-0.4-0.5-0.6-0.7-0.9-1 + c-0.3-0.3-0.5-0.6-1-1c0-0.1,0.1-0.2,0.2-0.2l0.3,0.3c0.4,0.4,0.6,0.3,1.4-0.4l3.4-3.2c0.2-0.2,0.2-0.2,0-0.5l-0.4-0.4 + c-0.3-0.3-0.7-0.7-1.1-0.8c-0.3,0-0.6,0.1-0.9,0.1c-0.1,0-0.2-0.2-0.1-0.2c0.5-0.2,1.1-0.5,1.4-0.8c0,0,0.1,0.1,0.1,0.1 + c-0.2,0.3,0,0.5,0.4,0.9l2.9,3.1c0.4,0.4,0.5,0.5,0.8,0.4c0,0,0.1,0.1,0.1,0.2c-0.4,0.2-1.1,0.7-1.3,1c-0.1,0-0.2-0.1-0.2-0.2 + c0.2-0.2,0.4-0.5,0.4-0.7c0-0.3-0.2-0.6-0.6-1.1l-0.5-0.5c-0.2-0.2-0.2-0.2-0.5,0L69.9,31.4z"/> + <path class="st0" d="M75.4,38.5c0.2-0.2,0.2-0.2,0.1-0.5l-0.7-1.4c-0.1-0.2-0.2-0.3-0.4-0.2l-1.2,0.1c-0.5,0.1-0.8,0.1-0.9,0.2 + c-0.1,0.1-0.1,0.1-0.1,0.4l0.1,0.3c0,0.1-0.2,0.2-0.2,0.1c-0.1-0.3-0.2-0.6-0.4-1c-0.1-0.3-0.3-0.6-0.5-0.9c0-0.1,0.2-0.2,0.2-0.1 + l0.2,0.3c0.1,0.2,0.3,0.4,0.7,0.3c0.5,0,1.3-0.1,2.5-0.2l3-0.2c0.4,0,0.6-0.1,0.7-0.2c0.2,0.2,0.4,0.3,0.6,0.3c0,0.1,0,0.1,0,0.2 + c-0.4,0.3-0.7,0.7-1.1,1L75,40.1c-0.7,0.7-0.8,0.9-0.6,1.3l0.1,0.3c0,0.1-0.2,0.1-0.2,0.1c-0.2-0.4-0.3-0.7-0.5-1.2 + c-0.2-0.5-0.4-0.8-0.5-1.1c0-0.1,0.1-0.2,0.2-0.1l0.2,0.3c0.1,0.2,0.2,0.3,0.3,0.3c0.1-0.1,0.3-0.2,0.4-0.4L75.4,38.5z M75.4,36.2 + c-0.3,0-0.3,0-0.1,0.3l0.6,1.2c0.1,0.3,0.2,0.3,0.4,0.1l1.3-1.2c0.2-0.2,0.4-0.4,0.5-0.5l0,0c-0.1,0-0.3,0-0.7,0L75.4,36.2z"/> + <path class="st0" d="M74.8,45.6c-0.1-0.9,0.1-1.5,0.1-1.7c0.2-0.2,0.9-0.4,1.4-0.5c0.1,0,0.1,0.2,0.1,0.2c-0.5,0.2-1.5,0.8-1.3,2 + c0.1,0.9,0.8,1.2,1.4,1.1c0.5-0.1,1-0.2,1.3-1.1l0.5-1.1c0.3-0.6,0.8-1.3,1.6-1.4c1-0.1,1.9,0.5,2.1,1.9c0,0.3,0,0.7,0,1 + c0,0.1,0,0.3,0,0.4c-0.2,0.1-0.8,0.3-1.2,0.4c-0.1,0-0.1-0.2-0.1-0.3c0.5-0.2,1.1-0.6,1-1.6c-0.2-1-0.9-1.1-1.3-1.1 + c-0.6,0.1-1,0.7-1.1,1.1L78.8,46c-0.3,0.7-0.8,1.4-1.8,1.6C75.9,47.7,75,47,74.8,45.6z"/> + <path class="st0" d="M23.6,57.3c0.7-0.3,0.9-0.4,0.8-0.8l-0.1-0.3c0-0.1,0.2-0.1,0.2-0.1c0.2,0.5,0.5,1.2,0.9,2.1 + c0.2,0.6,0.4,1.2,0.3,1.8c0,0.5-0.3,1-1,1.2c-0.7,0.3-1.2,0-1.7-0.5c-0.1,0-0.1,0.1-0.1,0.2c0.1,0.6-0.1,1.5-1.2,1.9 + c-1.1,0.4-2.2-0.1-2.9-1.9c-0.1-0.3-0.3-0.8-0.4-1.2c-0.2-0.4-0.3-0.8-0.4-1.1c0-0.1,0.2-0.1,0.2-0.1l0.1,0.2 + c0.3,0.5,0.4,0.5,1.4,0.1L23.6,57.3z M20.3,59.4c-0.4,0.1-0.8,0.3-1,0.6c-0.2,0.3-0.1,0.6,0,0.9c0.3,0.9,1,1.4,1.9,1 + c0.8-0.3,1.5-1,1-2.6c-0.2-0.5-0.3-0.6-0.5-0.5L20.3,59.4z M22.6,58.6c-0.3,0.1-0.3,0.1-0.1,0.6c0.4,1,0.9,1.4,1.8,1.1 + c1-0.4,1.1-1.2,0.8-2c-0.1-0.2-0.2-0.4-0.2-0.4c-0.1-0.1-0.1-0.1-0.3,0L22.6,58.6z"/> + <path class="st0" d="M26.8,64.6c0.9-0.7,1-0.8,0.7-1.3l-0.1-0.1c0-0.1,0.2-0.2,0.2-0.1c0.3,0.4,0.5,0.7,0.7,1l1.2,1.6 + c0.4,0.5,0.8,1,0.9,1.1c-0.1,0.2-0.7,0.7-1,1c-0.1,0-0.2-0.1-0.2-0.2c0.3-0.4,0.5-0.7,0.3-1.2c-0.1-0.2-0.3-0.5-0.6-0.9l-0.5-0.6 + c-0.2-0.3-0.2-0.2-0.5,0L26.3,66c-0.2,0.2-0.2,0.2,0,0.5l0.4,0.5c0.3,0.4,0.5,0.6,0.6,0.7c0.1,0.1,0.2,0.1,0.4,0l0.4-0.2 + c0.1,0,0.2,0.1,0.2,0.2c-0.2,0.2-0.6,0.4-0.9,0.6c-0.3,0.2-0.6,0.5-0.8,0.6c-0.1,0-0.2-0.1-0.2-0.2l0.3-0.3 + c0.1-0.1,0.2-0.3,0.1-0.5c-0.1-0.1-0.2-0.3-0.4-0.7L26,66.7c-0.2-0.2-0.2-0.3-0.4-0.1l-1.2,0.9c-0.4,0.3-0.7,0.6-0.8,0.8 + c0,0.2,0,0.4,0.6,1.2c0.5,0.6,0.7,0.9,0.9,1c0.2,0.1,0.7,0.1,1.3,0c0.1,0,0.1,0.2,0.1,0.3c-0.3,0.2-1.1,0.4-1.4,0.5 + c-0.6-0.8-1.1-1.5-1.7-2.3l-0.6-0.8c-0.3-0.4-0.5-0.6-0.9-1.1c0-0.1,0.1-0.2,0.2-0.2l0.2,0.3c0.4,0.4,0.6,0.4,1.4-0.3L26.8,64.6z" + /> + <path class="st0" d="M31.9,70.4c0.6-0.8,0.7-1,0.4-1.3L32,68.9c0-0.1,0.1-0.2,0.2-0.2c0.5,0.3,1.1,0.7,1.9,1.3 + c0.5,0.4,1,0.8,1.2,1.3c0.3,0.5,0.3,1.1-0.2,1.7c-0.6,0.8-1.5,0.8-2.1,0.6c-0.1,0-0.1,0.1-0.1,0.2c-0.1,1.6-0.2,2.6,0.1,3.5 + c0.1,0.2,0.2,0.5,0.4,0.7c0,0,0,0.1-0.1,0.1c-0.1,0-0.2-0.1-0.4-0.2c-0.7-0.5-1-1.1-1-2.3c0-0.5,0.1-1.3,0.1-1.9 + c0-0.3-0.1-0.5-0.4-0.7c-0.4-0.3-0.4-0.3-0.5-0.1l-0.8,1.1c-0.7,0.9-0.7,1-0.3,1.4l0.2,0.2c0,0.1-0.1,0.2-0.2,0.2 + c-0.4-0.3-0.6-0.5-1-0.8c-0.4-0.3-0.7-0.5-1.1-0.7c0-0.1,0-0.2,0.1-0.2l0.2,0.1c0.5,0.3,0.6,0.2,1.3-0.7L31.9,70.4z M31.7,72.1 + c-0.1,0.2-0.2,0.2-0.2,0.3c0,0,0.1,0.2,0.6,0.5c0.3,0.2,0.7,0.4,1,0.4c0.4,0,0.8-0.2,1.2-0.7c0.5-0.7,0.5-1.6-0.4-2.3 + c-0.5-0.4-0.6-0.4-0.7-0.1L31.7,72.1z"/> + <path class="st0" d="M42.5,80.4c-0.1,0.4-0.1,0.7,0,0.8c0,0,0,0.1,0,0.1c-0.1,0-0.3-0.1-0.5-0.1c-0.6,0-1.3-0.1-1.9-0.3 + c-1.2-0.4-2.2-1.1-2.7-2.1C37,78,37,77.2,37.2,76.3c0.3-0.8,0.8-1.6,1.7-2.1c0.9-0.5,2-0.6,3.5-0.1c0.6,0.2,1.1,0.5,1.2,0.6 + c0.2,0.1,0.5,0.3,0.6,0.3c-0.1,0.3-0.2,0.9-0.3,1.5c-0.1,0.1-0.2,0-0.3-0.1c0.1-1.2-0.6-1.8-1.6-2.1c-1.9-0.6-3.2,0.5-3.7,2 + c-0.6,1.9-0.1,3.7,1.9,4.4c0.6,0.2,1,0.2,1.2,0.1c0.1-0.1,0.2-0.2,0.3-0.5l0.1-0.4c0.3-0.8,0.3-0.9-0.3-1.2l-0.4-0.2 + c-0.1-0.1,0-0.2,0.1-0.2c0.3,0.1,0.8,0.3,1.4,0.5c0.4,0.1,0.7,0.2,1.1,0.3c0.1,0.1,0,0.2-0.1,0.3l-0.2,0c-0.4-0.1-0.5,0.2-0.7,0.7 + L42.5,80.4z"/> + <path class="st0" d="M47.8,76.8c0-1.1,0-1.2-0.6-1.3l-0.2,0c-0.1,0,0-0.2,0-0.3c0.5,0,0.8,0,1.2,0l2,0c0.7,0,1.3,0,1.4,0 + c0.1,0.2,0.1,0.9,0.2,1.4c0,0.1-0.2,0.1-0.3,0c-0.2-0.5-0.2-0.9-0.8-1c-0.2-0.1-0.6-0.1-1-0.1l-0.8,0c-0.3,0-0.3,0-0.3,0.4l0,2.1 + c0,0.3,0,0.3,0.3,0.3l0.6,0c0.4,0,0.8,0,0.9-0.1c0.1,0,0.2-0.1,0.3-0.4l0.1-0.4c0.1-0.1,0.2-0.1,0.3,0c0,0.3,0,0.7,0,1.1 + c0,0.4,0,0.8,0,1c0,0.1-0.2,0.1-0.3,0l-0.1-0.4c0-0.2-0.1-0.3-0.3-0.4c-0.1,0-0.4-0.1-0.8-0.1l-0.6,0c-0.3,0-0.3,0-0.3,0.3l0,1.5 + c0,0.6,0,0.9,0.2,1.1c0.1,0.1,0.3,0.2,1.3,0.2c0.8,0,1.1,0,1.3-0.2c0.2-0.1,0.5-0.5,0.7-1c0.1-0.1,0.2,0,0.3,0.1 + c-0.1,0.4-0.3,1.2-0.5,1.5c-0.9,0-1.9,0-2.8,0l-0.9,0c-0.5,0-0.8,0-1.4,0c-0.1,0-0.1-0.2,0-0.3l0.3,0c0.6-0.1,0.7-0.2,0.7-1.3 + L47.8,76.8z"/> + <path class="st0" d="M62.2,75.1c-0.2-0.5-0.6-1.7-0.6-2.1c0-0.1,0.2-0.2,0.5-0.4l0.1-0.1c0-0.1,0-0.2-0.1-0.2 + c-0.3,0.1-0.6,0.2-1,0.4c-0.4,0.1-0.7,0.3-1.2,0.4c-0.1,0.1,0,0.2,0.1,0.3l0.2,0c0.4-0.1,0.6-0.1,0.7,0c0.3,0.2,0.8,1.5,1,2 + l0.8,2.1c0.1,0.2,0.1,0.4,0.1,0.4l0,0c-0.6-0.3-1.3-0.7-2.3-1.2L59,75.9c-0.5-0.2-2.1-1.1-2.5-1.5c-0.1,0.1-0.3,0.1-0.4,0.2 + c-0.2,0.1-0.7,0.3-1.1,0.4c-0.1,0.1,0,0.2,0.1,0.3l0.2,0c0.2-0.1,0.5-0.1,0.7,0c0.3,0.1,0.4,0.4,0.5,0.6l1.1,2.8 + c0.2,0.5,0.6,1.7,0.6,2.1c0,0.1-0.1,0.2-0.4,0.4l-0.3,0.1c0,0.1,0,0.2,0.1,0.2c0.3-0.2,0.6-0.3,1-0.4c0.4-0.1,0.7-0.3,1.2-0.4 + c0.1-0.1,0-0.2-0.1-0.3l-0.3,0.1c-0.3,0.1-0.5,0.1-0.6,0c-0.3-0.2-0.8-1.5-0.9-2l-0.8-2.1c-0.1-0.3-0.2-0.5-0.2-0.7l0,0 + c0.3,0.1,1.3,0.7,1.6,0.9l3.2,1.7c1.2,0.7,1.6,0.9,1.8,1c0.1,0,0.1-0.1,0.1-0.2c-0.1-0.2-0.6-1.4-0.7-1.7L62.2,75.1z"/> + <path class="st0" d="M70.4,74.9c-0.7,0.6-1.3,0.7-1.5,0.8c-0.2-0.1-0.8-0.6-1.2-0.9c0-0.1,0.1-0.2,0.2-0.2c0.5,0.3,1.5,0.8,2.4,0 + c0.7-0.6,0.6-1.3,0.2-1.8c-0.3-0.4-0.7-0.7-1.6-0.6l-1.2,0.1c-0.6,0.1-1.5,0-2-0.7c-0.6-0.8-0.6-1.9,0.5-2.8 + c0.2-0.2,0.6-0.4,0.8-0.5c0.1-0.1,0.3-0.1,0.3-0.2c0.2,0.1,0.7,0.5,1,0.9c0,0.1-0.1,0.2-0.2,0.2c-0.4-0.3-1.1-0.6-1.9,0 + c-0.8,0.7-0.5,1.3-0.2,1.7c0.4,0.5,1.1,0.5,1.5,0.4l1-0.1c0.8-0.1,1.7-0.1,2.3,0.7C71.6,72.8,71.5,74,70.4,74.9z"/> + <path class="st0" d="M71.6,65.7c-0.9-0.6-1.1-0.7-1.5-0.3l-0.2,0.2c-0.1,0-0.2-0.1-0.2-0.2c0.3-0.4,0.5-0.7,0.8-1.1 + c0.2-0.3,0.4-0.6,0.7-1.1c0.1,0,0.2,0.1,0.2,0.1l-0.1,0.2c-0.3,0.5-0.2,0.7,0.7,1.3l3,2.2c0.9,0.6,1,0.7,1.5,0.2l0.2-0.2 + c0.1,0,0.2,0.1,0.2,0.2c-0.3,0.4-0.5,0.7-0.8,1c-0.3,0.4-0.5,0.7-0.7,1.1c-0.1,0-0.2,0-0.2-0.1l0.1-0.2c0.3-0.5,0.2-0.6-0.7-1.3 + L71.6,65.7z"/> + <path class="st0" d="M80.2,61.3c-0.3,0.8-0.8,1.2-0.9,1.4c-0.3,0-1-0.1-1.5-0.2c0-0.1,0-0.2,0.1-0.2c0.6,0,1.7,0,2.1-1.1 + c0.3-0.8-0.1-1.4-0.7-1.7c-0.4-0.2-0.9-0.3-1.7,0.3l-1,0.7c-0.5,0.4-1.3,0.7-2.1,0.4c-0.9-0.3-1.4-1.4-0.9-2.6 + c0.1-0.3,0.3-0.6,0.5-0.9c0.1-0.1,0.2-0.2,0.2-0.3c0.3,0,0.9,0.1,1.3,0.3c0,0.1,0,0.2-0.1,0.3c-0.5-0.1-1.3,0-1.6,0.9 + c-0.4,1,0.2,1.4,0.7,1.6c0.6,0.2,1.2-0.1,1.5-0.4l0.8-0.6c0.6-0.5,1.4-0.9,2.3-0.5C80.2,58.9,80.7,60,80.2,61.3z"/> + <path class="st0" d="M49.6,14.2C30,14.2,14.2,30,14.2,49.6C14.2,69.2,30,85,49.6,85C69.2,85,85,69.2,85,49.6 + C85,30,69.2,14.2,49.6,14.2z M49.6,84c-19,0-34.4-15.4-34.4-34.4c0-19,15.4-34.4,34.4-34.4c19,0,34.4,15.4,34.4,34.4 + C84,68.6,68.6,84,49.6,84z"/> + <path class="st0" d="M58,66.8c-0.7,0.5-1.2,1.3-1.5,2c0.7,0.5,2.2,1.2,4.7,1.6c1.1-0.6,2-1.2,3-2c-0.9-0.2-1.8-0.7-2.4-1 + C60.7,66.7,59.3,65.7,58,66.8z"/> + <path class="st0" d="M41.4,62.1c-0.9-0.2-1.3-0.2-2.6,0.2c-2.2,0.7-5.7,4.6-5.7,4.6c1,1,2.2,1.9,3.4,2.7c1-1.2,3.5-4.1,5.9-4.1 + c1.3,0,2,0.5,3,1.2c0.1-0.1,0.2-0.3,0.3-0.4C43.8,65.2,41.4,62.1,41.4,62.1z"/> + <path class="st0" d="M48.9,65.5c-1.1,0.1-1.8,1-2.3,1.9c2,1.4,3.8,3,6.4,3.7c2,0.6,2.8,0.8,4.9,0.9c0.9-0.3,1.8-0.7,2.7-1.2 + c-1.3-0.2-3-0.8-4.4-1.4C53.8,68.2,51.1,65.2,48.9,65.5z"/> + <path class="st0" d="M42.8,66.7c-3,0-4.2,2.5-5.1,3.6c3.5,2,7.6,3.2,11.9,3.2c2.3,0,4.5-0.3,6.6-0.9c-1.3-0.1-3-0.4-4.4-1 + C48.5,70.2,45,66.7,42.8,66.7z"/> + <path class="st0" d="M64.1,64.6c-2-2.5-3.5-3-4.3-2.8c-0.8,0.2-0.6,0.8-1.5,1.8c-0.8,1-2.7,2.1-3.1,2.3c0.3,0.3,0.7,0.8,0.8,0.9 + c0.9-0.9,2.2-1.7,3.3-1.7c2.1,0,2.7,1.7,5.5,2.7c0.6-0.5,1.2-1,1.7-1.5C66.6,66.4,65.2,66.1,64.1,64.6z"/> + <path class="st0" d="M59.4,44.1c-0.1-0.1,0-0.3-0.1-0.4c-0.1-0.4-0.3-0.8-0.3-1.3c-0.1-0.3,0.2-0.4,0.4-0.5c0.1-0.3,0.1-0.6,0-0.8 + c-0.1-0.4-0.7-0.5-0.7-1c0-0.3-0.2-0.6-0.2-1c-0.2-0.5-0.1-1.1-0.2-1.6c-0.1-0.6-0.1-1.2-0.2-1.8c-0.1-0.7-0.2-1.4-0.4-2.1 + c-0.1-0.6-0.3-1.2-0.6-1.7c0-0.4-0.4-0.7-0.2-1.1c0.3-0.5,0.6-1,0.8-1.5c0.2-0.3,0.1-0.7,0.2-1.1c0-0.3,0.1-0.6,0-0.9 + c-0.1,0-0.1,0-0.1,0c-0.1,0.5-0.7,0.7-1.1,1c-0.6,0.2-1.2,0.1-1.9,0.2c-0.4,0-0.7,0.4-1.2,0.1c-0.2-0.2-0.4-0.2-0.7-0.3 + c-0.5,0-1,0-1.4,0c-0.7,0-1.2-0.4-1.9-0.3c-0.9,0-1.6,0.4-2.5,0.3c-0.8-0.2-1.6,0.1-2.2,0.4c-0.2,0-0.5-0.2-0.8-0.2 + c-0.7-0.3-1.6,0.2-2.1-0.3c-0.3-0.3-0.5-0.6-0.5-1c-0.1,0.1-0.2,0.2-0.2,0.3c-0.2,0.3-0.3,0.6-0.3,0.9c-0.1,0.4,0,0.9,0.1,1.3 + c0.1,0.7,0.6,1.3,0.5,2c-0.1,0.3-0.3,0.7-0.4,1c-0.3,0.3-0.2,0.8-0.3,1.3c-0.3,0.8-0.1,1.6,0,2.5c-0.3,1-0.4,2-0.5,3 + c-0.1,0.7,0,1.4-0.3,2c-0.4,0.4-0.7,0.7-0.6,1.3c0,0.3,0.2,0.5,0.3,0.7c0.1,0.5,0.1,1.1,0,1.6c0,0.4-0.4,0.6-0.5,0.9 + c-0.1,0.4,0.2,0.6,0.4,0.8c0.1,0.2,0.1,0.6,0.2,0.8c0.1,0.7,0.2,1.3,0.3,2c0.2,1,0.3,2,0.5,2.9c0.2,1.2,0.5,2.3,0.8,3.4 + c0.4,0.8,0.5,1.7,0.8,2.5c0.2,0.7,0.6,1.3,0.6,2c0,0.1,0,0.2,0.1,0.2c0,0.5-0.4,0.8-0.3,1.3c0,0,1.5,2.6,3.2,3.7 + c0.7-0.8,1.7-1.5,3-1.5c2.1,0,4,2.1,6,3.7c0.1-0.2,0.3-0.3,0.5-0.5c-0.7-0.9-3.6-4.3-6-4.7c0,0,0.2-0.5,0-0.7 + c-0.2-0.3-0.2-0.5-0.2-0.8c0-0.1-0.1-0.4,0-0.5c0.4,0.1,0.5,0.5,0.7,0.8c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1-0.1c0-0.4,0.5-0.6,0.7-0.8 + c0.1,0,0.1,0,0.2,0.1c0.1,0.4,0,0.9,0.3,1.2c0.1,0.1,0,0.2-0.1,0.3c0,0.3-0.2,0.2-0.2,0.2c1.8,0.9,2.8,1.9,3.8,3.1 + c0.7-0.5,3.2-2.1,3.1-3.7c0-0.5-0.3-0.5-0.4-0.8c-0.2-0.2-0.4-0.4-0.5-0.7c-0.3-0.5-0.5-1.1-0.4-1.8c0.2-0.5,0.2-1,0.4-1.5 + c0.3-0.9,0.5-1.8,0.7-2.7c0.3-1.2,0.7-2.5,0.8-3.8c0.2-0.4,0.2-0.9,0.3-1.4c0.2-0.4,0.1-1,0.2-1.5c0.1-0.4,0-0.8,0.2-1.1 + c0.1-0.2,0-0.4,0.1-0.6c0-0.3,0.3-0.2,0.3-0.5c0.2-0.1,0.3-0.4,0.4-0.5C60.1,44.7,59.7,44.4,59.4,44.1z M58.3,40.6 + c0.2,0.1,0.4,0.1,0.5,0.3c0.2,0.1,0.2,0.3,0.3,0.5c0,0.1,0,0.3-0.1,0.3c-0.4,0-0.7-0.2-0.9-0.4C58,41,58.2,40.8,58.3,40.6z + M56.2,45.5c0,0.6,0,1.2-0.1,1.8c-0.1,0.1,0,0.2,0,0.3c-0.1,0.6,0,1.3-0.1,1.9l-0.1,0c-0.2-0.3-0.7-0.4-0.7-0.8 + c0.3-1,0.2-2.2,0.3-3.3c0.1-0.9,0.1-1.9,0-2.8c0,0,0-0.1,0.1-0.1c0.3,0.1,0.4,0.4,0.7,0.5C56.2,43.9,56.1,44.6,56.2,45.5z + M42.5,37.6c-0.3,0-0.3-0.3-0.4-0.5c-0.1-0.1-0.1-0.3-0.1-0.4c0.1-0.1,0.1-0.2,0.1-0.3c-0.1-0.1-0.3,0-0.3-0.2 + c0-0.2-0.1-0.5,0.2-0.6c0.2-0.1,0.5,0,0.8-0.2c0,0,0-0.1-0.1-0.1c-0.3,0-0.5,0.1-0.7,0.2c-0.1,0-0.1-0.1-0.1-0.2 + c0-0.7-0.1-1.3,0.1-1.8c0-0.1-0.1-0.3,0-0.4c0.3-0.1,0.4,0.4,0.7,0.3v0c-0.2-0.2-0.4-0.4-0.6-0.4c-0.1-0.2,0-0.5,0-0.7 + c0.1-0.1,0.1-0.2,0.2-0.1c0.2,0.1,0.3,0.3,0.5,0.4c0.1,0,0.1-0.1,0.1-0.2c-0.2-0.3-0.8-0.3-0.5-0.8c0-0.2,0.1-0.4,0.3-0.4 + c0.2,0.1,0.3,0.3,0.5,0.4l0.1,0c-0.2-0.2-0.3-0.4-0.2-0.6c0.1-0.1,0.3,0.1,0.4,0.1l0.2,0.1c0.2,0.1,0.5,0.2,0.5,0.5 + c0.2,0.3,0.2,0.6,0.5,0.8c0.1,0.2,0.2,0.3,0.3,0.4c-0.1,0.1-0.2,0.1-0.2,0c-0.2-0.2-0.3-0.4-0.5-0.6c-0.1,0-0.1,0-0.1,0.1 + c0.1,0.2,0.1,0.5,0.3,0.7l0,0.2c-0.3,0-0.7-0.3-0.9-0.5c0,0-0.1-0.1-0.2,0c-0.1,0.1,0,0.2,0,0.2c0.2,0.3,0.3,0.6,0.6,0.7 + c0.1,0,0.1,0.2,0,0.2c0,0.2-0.2,0.1-0.3,0.1c-0.2-0.2-0.4-0.4-0.6-0.5l-0.1,0c0,0.2,0.2,0.3,0.2,0.4c0.2,0.3,0.6,0.3,0.5,0.7 + c0,0.1,0,0.2-0.1,0.2c-0.5-0.1-1.2-0.3-1.6,0.2c0,0.1,0,0.1,0.1,0.1c0.5,0,0.9,0,1.3,0.3c0.1,0.1,0.2,0.2,0.1,0.3 + c-0.1,0-0.2,0-0.3,0.1c-0.1,0.1-0.3,0.2-0.5,0.3c0,0,0,0.1,0,0.1c0.2-0.1,0.5-0.2,0.7-0.3c0.1,0,0.2,0,0.2,0.1 + c0,0.1-0.1,0.1-0.2,0.2C43.4,35.9,43,36,43,36.3l0.1,0c0.3,0,0.5-0.5,0.8-0.4c0.1,0,0.1,0.1,0.1,0.2c-0.4,0.3-1,0.5-1.1,1.1 + c0,0,0,0.1,0,0.1c0.1,0,0.1-0.1,0.2-0.2c0.4-0.3,0.7-0.6,1.2-0.7c0,0,0.1,0,0.1,0.1c0,0.2-0.4,0.4-0.4,0.6 + c-0.1,0.2-0.1,0.4-0.2,0.6c0,0,0.1,0.1,0.1,0c0.2-0.3,0.4-0.8,0.8-1c0,0.1,0.1,0,0.2,0.1c0.2,0,0.5,0.1,0.6,0.3 + c0,0.5-0.2,1.1,0,1.5c0.1-0.1,0-0.2,0.1-0.3c0-0.4,0.2-0.6,0.3-1c0-0.1,0.2-0.1,0.2-0.1c0.2,0.1,0.2,0.3,0.4,0.4 + c0.1-0.1,0-0.4,0-0.5c0.1-0.1,0.2-0.1,0.3-0.1c0,0,0.1,0,0.2,0c0.1-0.1,0-0.2,0-0.2c0.2-0.2,0.3-0.6,0.7-0.5l0.1,0.1 + c0,0.2,0,0.5-0.1,0.7c-0.1,0-0.1-0.2-0.3-0.1c-0.1,0.1,0,0.2,0,0.3c0.1,0.2,0.2,0.4,0.3,0.6c0,0.1,0.1,0.1,0,0.2 + c-0.3,0-0.4-0.3-0.5-0.4c-0.1-0.1-0.2,0-0.2,0.1c-0.1,0.3,0.2,0.6,0.4,0.8c0.1,0,0.2,0.1,0.2,0.1c0,0.1-0.1,0.2,0,0.3l0.1,0.2 + c-0.1,0.1-0.3,0-0.5-0.1c-0.3-0.2-0.6-0.6-0.7-1c0,0-0.1-0.1-0.1,0c-0.1,0.3,0,0.5,0.2,0.7c0.2,0.1,0.3,0.3,0.3,0.5 + c-0.1,0.1-0.2,0.1-0.3,0.1c-0.3-0.2-0.3-0.6-0.3-0.9c0,0-0.1-0.1-0.1,0c-0.1,0.2-0.1,0.4-0.1,0.5c0,0.2,0.1,0.4-0.1,0.5 + c-0.2,0.1-0.4,0-0.6,0.1c-0.2-0.1-0.2-0.4-0.2-0.6c0-0.1-0.1,0-0.1,0c-0.2,0.1-0.2,0.6-0.5,0.5c-0.2-0.1-0.5-0.2-0.7-0.5 + c-0.1-0.3,0.2-0.4,0.2-0.7c0.1-0.2,0.3-0.3,0.4-0.6c-0.1-0.1-0.3,0.1-0.4,0.2c-0.2,0.3-0.4,0.6-0.5,0.9c0,0.1-0.1,0.1-0.2,0.1 + c-0.3-0.3-1-0.5-0.9-1c0.1-0.1,0.1-0.2,0.2-0.3C42.7,37.3,42.6,37.5,42.5,37.6z M49.5,38.7c0,0,0.1,0,0.1,0 + c0.1-0.2,0.1-0.6,0.1-0.8c0-0.7,0.1-1.4,0.2-2c0-0.1,0-0.2,0.2-0.3c0.2,0,0.5,0.1,0.6,0.3c0.1,0.9,0,1.9-0.3,2.7 + c-0.1,0.4-0.4,0.7-0.6,1.1c-0.1,0.1-0.1,0.4-0.4,0.4c-0.6-0.8-1-1.8-1-2.9c0-0.4-0.2-1,0.1-1.3c0.3-0.1,0.5-0.4,0.8-0.3l0,0.1 + C49.5,36.6,49.2,37.7,49.5,38.7z M52.1,41.6c-0.5-0.2-1-0.7-1-1.3c0-0.1,0.1-0.1,0.1,0l0.5,0.5c0.4,0.2,0.8,0.5,1,0.9 + c0,0.1,0.1,0.3-0.1,0.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.5-0.1-1-0.5-1.2-0.9c-0.1-0.3-0.1-0.7,0-1c0.2,0,0.1,0.2,0.2,0.3 + c0.2,0.4,0.6,1,1.1,1.1C52.2,41.7,52.1,41.6,52.1,41.6z M51.9,36.9c-0.1,0.1-0.2,0.2-0.3,0.3c-0.1-0.2,0.1-0.4,0.1-0.5 + c0,0,0-0.1,0-0.1c-0.1-0.1-0.2,0-0.2-0.2c0-0.1,0-0.1,0-0.2l0.2,0c0.2,0.2,0.5,0.5,0.8,0.7c0,0.2,0,0.4-0.1,0.6 + c0,0.2-0.2,0.4-0.2,0.6c0,0.1,0.1,0.1,0.1,0c0.2-0.3,0.3-0.6,0.6-0.9c0.3-0.1,0.6,0,0.9,0c0.2,0.1,0.1,0.4,0.2,0.6 + c0,0.1,0,0.3,0.1,0.4c0.2,0,0.2-0.3,0.2-0.4c0.1-0.3,0-0.5,0-0.8c0,0,0-0.1,0-0.2c0.1-0.1,0.2-0.1,0.3,0c0.2,0.1,0.3,0.4,0.5,0.5 + c0.1,0,0-0.1,0-0.2c0-0.2-0.3-0.4-0.3-0.6c0-0.1,0.1-0.1,0.2-0.1c0.2,0.1,0.1,0.4,0.3,0.5c0.1,0,0-0.1,0-0.2 + c-0.1-0.2-0.2-0.4-0.2-0.6c0.1-0.1,0.2,0,0.2,0c0.3,0.1,0.5,0.2,0.8,0.4c0.3,0.2,0.3,0.6,0.4,0.9c-0.1,0.3,0.2,0.7-0.1,0.9 + c-0.2,0.1-0.4,0.3-0.6,0.4c-0.1-0.1-0.1-0.2-0.2-0.3c-0.2-0.2-0.3-0.7-0.6-0.6c-0.1,0.1,0.1,0.3,0.1,0.5c0,0.3,0.3,0.6,0.1,0.9 + c-0.3-0.1-0.4,0.3-0.7,0.2c-0.3-0.1-0.6,0.5-0.9,0c0-0.4,0-0.8-0.1-1.3c0-0.1-0.1-0.3-0.2-0.4c-0.1,0.1,0,0.3-0.1,0.5 + c0,0.4-0.1,0.8-0.3,1.1c-0.1,0.1-0.2,0.2-0.3,0.1c0,0-0.1,0-0.1-0.1c0-0.2,0.1-0.4,0.1-0.6c0-0.1-0.1,0-0.1,0 + c-0.2,0.3-0.5,0.7-0.9,0.6c-0.1-0.1-0.1-0.1-0.2-0.1c0.1-0.2,0.4-0.4,0.4-0.6c-0.2,0-0.3,0.2-0.5,0.3c-0.1-0.7,0.6-1.1,0.7-1.8 + C52,36.9,51.9,36.9,51.9,36.9z M51.9,33.6c0.3-0.4,0.8-0.5,1.3-0.6c0.5,0,1.1,0.1,1.4,0.5c0.4,0.5,0.5,1.2,0.3,1.8 + c-0.3,0.6-0.9,1.1-1.6,1.1c-0.3,0.1-0.5-0.1-0.8-0.2c-0.4-0.2-0.5-0.6-0.7-0.9C51.5,34.7,51.6,34.1,51.9,33.6z M57.1,41.6 + c0,0,0.1-0.1,0.2-0.1c0.2,0,0.3,0,0.5,0.1c0.1,0.2,0.2,0.5,0.1,0.7c-0.3,0.1-0.5,0-0.7-0.2C57,41.9,57.2,41.7,57.1,41.6z + M57.3,41.2c-0.3-0.1-0.6-0.4-0.8-0.7c-0.1-0.3-0.3-0.5-0.3-0.8c0-0.2-0.1-0.4,0-0.6h0c0.2,0.5,0.6,0.8,1,1.3 + c0.1,0.1,0.3,0.1,0.4,0.3C57.6,40.9,57.5,41.1,57.3,41.2z M54.9,47.4c-0.3,0.1-0.5-0.3-0.8-0.4c-0.3-0.4-0.6-0.8-0.6-1.3 + c0,0,0.1-0.1,0.1-0.1c0.2,0.3,0.4,0.7,0.8,0.8c0.1,0,0.1,0,0.1-0.1c-0.1-0.3-0.3-0.6-0.2-0.9c0.2,0,0.3,0.3,0.6,0.3 + c0.1,0.1,0.1,0.4,0.1,0.5C54.9,46.6,55,47.1,54.9,47.4z M54.8,53.9c0-0.8,0.2-1.7,0.2-2.5c0.1-0.1,0.3-0.2,0.5-0.2 + c0,0.1,0,0.3,0,0.5c0,0.8-0.1,1.6-0.1,2.5c0,0.3-0.1,0.7-0.1,1c-0.1,0.2-0.1,0.4-0.1,0.7c0,0.7-0.2,1.3-0.3,1.9 + c-0.1,0.1-0.1,0.4-0.3,0.4c-0.2-0.2-0.1-0.5-0.1-0.7c0.1-0.2,0-0.5,0.1-0.7C54.6,55.8,54.9,54.9,54.8,53.9z M54.6,59.7 + c0.2,0.4,0.2,0.8,0.3,1.1c0,0.2,0.1,0.4-0.1,0.5c-0.5-0.1-0.9,0.1-1.3,0.4c-0.1,0-0.2,0-0.3-0.1c-0.1-0.2,0-0.4,0-0.6 + c0.1-0.2,0-0.5,0.2-0.7c0.1-0.1,0.3-0.1,0.3-0.3c-0.2-0.1-0.5,0-0.6-0.2c-0.2-0.3-0.4-0.6-0.4-1c0.3-0.3,0.8-0.4,1.2-0.3 + c0.1,0.1,0.3,0.1,0.3,0.2C54.5,59.2,54.5,59.5,54.6,59.7z M53.9,62.1c0.1-0.3,0.4-0.3,0.6-0.4c0.1,0,0.2,0,0.2,0.1 + c-0.1,0.6-0.2,1.2-0.6,1.7c0,0.1-0.1,0.1-0.2,0.1c-0.1,0,0-0.1,0-0.2C54.1,63,54.1,62.5,53.9,62.1z M52.9,63.1 + c-0.4-0.1-0.9-0.4-0.9-0.9c0-0.1-0.1-0.2-0.1-0.3c0.2-0.2,0.5-0.2,0.8-0.2l0.1,0.1C52.7,62.2,52.6,62.8,52.9,63.1z M52.3,61.4 + c-0.2,0-0.4,0.2-0.6,0.2c-0.1-0.2-0.1-0.4-0.2-0.6c-0.1-0.7,0-1.4,0.6-1.8c0.1-0.1,0.2,0,0.3,0c0.2,0.2,0.3,0.5,0.4,0.7 + c0.1,0.2,0.2,0.3,0.3,0.6c0.1,0.3,0,0.6,0,0.9C52.8,61.5,52.5,61.3,52.3,61.4z M47.7,62.4c0.2-0.1,0.4-0.3,0.7-0.1 + c0.2,0.2,0.2,0.4,0.2,0.6c-0.2,0.4-0.6,0.8-1,0.9c0,0-0.1,0-0.1-0.1c0-0.3,0.2-0.5,0.1-0.8C47.5,62.7,47.6,62.6,47.7,62.4z + M48.5,62c-0.2,0-0.4-0.1-0.5-0.2c-0.2,0-0.2,0.2-0.4,0.3c-0.1,0-0.1,0.1-0.2,0.1c-0.1-0.2-0.1-0.4-0.1-0.6c-0.1-0.2,0-0.5,0.1-0.7 + c0.2-0.1,0.3-0.3,0.5-0.3c0.1-0.1,0.1-0.1,0.1-0.2c-0.1-0.1-0.3-0.1-0.4-0.1c-0.2,0.1-0.3,0.2-0.5,0.4c-0.2-0.3-0.2-0.6-0.2-1 + c0-0.3,0.1-0.7,0.4-0.8c0.2,0.1,0.6,0.1,0.7,0.4c0.4,0.5,0.8,1,0.9,1.7c0,0.4,0.1,0.8-0.1,1.2C48.6,62.2,48.6,62.1,48.5,62z + M47.3,58.2c-0.6-0.3-0.7-1-0.6-1.6c0-0.1,0-0.3,0.2-0.3c0.1,0.1,0.1,0.2,0.2,0.3c0.3,0.6,1,1,1.5,1.5c0.4,0.2,0.6,0.7,0.6,1.2 + c0.1,0.1,0,0.3,0,0.4c0,0-0.1,0-0.1-0.1C48.6,59,48,58.4,47.3,58.2z M44.4,40.8c0.2-0.1,0.3-0.3,0.5-0.4c0.2-0.2,0.3-0.4,0.5-0.6 + c0.1,0,0.2,0,0.2,0.1c0,0.3-0.1,0.5-0.2,0.8c-0.3,0.6-0.7,1.2-1.4,1.3c-0.2,0-0.4-0.1-0.5-0.2c0-0.3-0.1-0.5-0.1-0.7 + c0-0.5,0.4-0.9,0.7-1.4c0.1-0.1,0.3-0.2,0.3,0c-0.1,0.3-0.1,0.7-0.1,1C44.4,40.7,44.4,40.8,44.4,40.8z M45.9,44.5 + c0.4-0.3,0.7-0.8,1-1.1c0,0,0.1,0,0.1,0c0,0.7-0.4,1.3-0.9,1.9c-0.3,0.3-0.8,0.5-1.2,0.4c-0.3-0.1-0.4-0.4-0.5-0.6 + c0-0.3,0.1-0.5,0.2-0.7c0.4-0.3,0.9-0.6,1.1-1c0-0.1,0.1-0.1,0.2-0.1c0,0.5-0.3,0.9-0.5,1.3C45.7,44.7,45.8,44.6,45.9,44.5z + M47,41.8c0.4-0.1,0.6-0.4,0.8-0.7c0-0.2,0.2-0.3,0.3-0.5c0,0,0,0,0.1,0c0,0.7-0.3,1.4-0.9,1.9c-0.1,0.1-0.3,0.1-0.4,0.1 + c-0.2-0.1-0.5-0.2-0.5-0.4c0-0.5,0.1-0.9,0.5-1.1c0.1-0.1,0.2-0.3,0.4-0.3c0,0.3-0.1,0.6-0.2,0.8C47.1,41.6,46.9,41.7,47,41.8z + M48.9,48.7C49,48.7,49,48.7,48.9,48.7c0.2-0.1,0.1-0.3,0.2-0.4c0.1-0.1,0.2,0,0.2,0c0.3,0.2,0.1,0.6,0.2,0.9c0,0.3-0.1,0.7-0.2,1 + c0.1,0.1,0.2,0,0.2,0c0.3-0.4,0.2-0.8,0.3-1.3c0-0.1,0-0.2,0.1-0.3c0.1,0,0.1,0,0.1,0.1c0,0.3,0,0.6,0,0.9l0.1,0 + c0.3-0.4,0.1-0.9,0.3-1.4c0.1-0.2,0-0.5,0.1-0.8c0.2,0,0.2,0.2,0.2,0.4c0,0.2,0.1,0.3,0.2,0.4c0.1,1,0.4,2.4-0.6,3 + c-0.3,0.2-0.8,0.1-1.1,0c-0.3-0.1-0.4-0.5-0.5-0.7c-0.2-0.6-0.4-1.2-0.3-1.9c0.1-0.6,0.2-1.3,0.5-1.8c0.1,0.1,0,0.2,0,0.3 + C48.9,47.7,48.8,48.2,48.9,48.7z M51.8,46.6c-0.1-0.2-0.1-0.5-0.2-0.8c0-0.2,0.2,0,0.2,0.1c0.2,0.6,1.1,0.7,1.1,1.4 + c0.1,0.2,0.1,0.4,0,0.6c-0.2,0.2-0.5,0.3-0.9,0.3c-0.5-0.2-0.8-0.7-1.2-1.1c0-0.3-0.3-0.5-0.1-0.8c0.1,0,0.2,0.1,0.2,0.1 + c0.3,0.3,0.6,0.6,0.9,0.8c0.1,0,0.1,0,0.2-0.1C52.2,46.9,51.9,46.8,51.8,46.6z M51.3,52.4c-0.1-0.2-0.4-0.4-0.4-0.6 + c0-0.1-0.1-0.2,0.1-0.3c0.5,0.2,0.9,0.5,1.2,0.9c0.1,0.3,0.1,0.7,0,0.9c0,0.1-0.1,0.3-0.2,0.3c-0.1,0.1-0.3,0.1-0.5,0.1 + c-0.5-0.3-0.8-0.9-0.9-1.5h0.1c0.2,0.2,0.3,0.7,0.7,0.5C51.4,52.7,51.4,52.5,51.3,52.4z M52.2,51.3c-0.3-0.4-0.6-0.8-0.6-1.4 + c0,0,0.1-0.1,0.1,0c0.1,0.1,0.1,0.2,0.1,0.3c0.1,0.2,0.2,0.5,0.5,0.5c0.1,0,0-0.2,0-0.2c0-0.3-0.2-0.5-0.1-0.8h0 + c0.4,0.4,0.9,0.8,0.7,1.4c0,0.2-0.2,0.3-0.3,0.3C52.5,51.4,52.4,51.4,52.2,51.3z M47.1,50.7c0.3-0.3,0.5-0.6,0.7-0.9 + c0.1,0,0.1,0,0.1,0.1c0.1,0.8-0.3,1.4-0.9,1.8c-0.2,0.1-0.4,0.1-0.5,0.1c-0.1-0.1-0.2-0.3-0.3-0.4c-0.1-0.6,0.1-1.1,0.5-1.5 + c0.2-0.2,0.2-0.4,0.4-0.5c0.2,0.1,0.1,0.5,0.1,0.7c0,0.3-0.2,0.4-0.2,0.7C46.9,50.9,47,50.7,47.1,50.7z M47.6,51.9 + c0.1-0.3,0.4-0.4,0.6-0.7c0.1,0,0.2,0,0.2,0.1c0,0.5-0.3,0.9-0.5,1.3c0.1,0.1,0.2-0.1,0.4-0.1c0.3-0.2,0.3-0.6,0.5-0.9 + c0.1,0,0.2,0.1,0.2,0.1c0.3,0.7-0.1,1.3-0.4,1.8c-0.2,0.4-0.6,0.2-0.9,0.3c-0.2,0-0.4-0.1-0.4-0.3C47.1,52.9,47.5,52.4,47.6,51.9z + M48.5,46.1c0,0.3-0.1,0.5-0.2,0.8L48.2,47c0.1,0.1,0,0.2,0,0.3c-0.1,0.6-0.6,1-1.2,1.1c-0.2,0-0.4-0.1-0.6-0.2 + c-0.3-0.2-0.2-0.6-0.2-1c0.2-0.6,0.6-1.2,1-1.8c0,0,0.1-0.1,0.1,0c0.1,0.6,0,1.1-0.2,1.6c0,0.1,0,0.2,0.1,0.3 + c0.2-0.1,0.2-0.3,0.4-0.4l0-0.1c0.2-0.4,0.5-0.8,0.6-1.3c0-0.1,0.1,0,0.1-0.1C48.6,45.7,48.5,45.9,48.5,46.1z M45.5,43 + c-0.2,0.2-0.5,0.4-0.8,0.4c-0.1,0-0.2-0.1-0.2-0.2c-0.1-0.6,0.4-0.9,0.5-1.4c0.1-0.1,0.2-0.3,0.3-0.3c0.1,0.3-0.1,0.6-0.1,1 + c0.1,0.1,0.2-0.1,0.3-0.2c0.2-0.4,0.4-0.9,0.5-1.3c0-0.1,0.1,0,0.1,0C46.1,41.8,45.8,42.4,45.5,43z M44.4,46.7l0.5-0.5 + c0.1,0,0.1,0,0.1,0.1c0.1,0.3-0.1,0.7-0.2,0.9c0,0.1-0.1,0.3,0,0.4c0.2,0,0.3-0.2,0.4-0.3c0.2-0.3,0.4-0.6,0.7-0.8c0,0,0.1,0,0.1,0 + c0,0.5-0.3,0.9-0.5,1.3c-0.2,0.4-0.6,0.7-1.1,0.6l-0.1-0.1C44.2,47.8,44.1,47.1,44.4,46.7z M46.1,52.7c0.1-0.1,0.1-0.2,0.2-0.2 + c0,0.2-0.2,0.3-0.2,0.5c-0.1,0.2-0.2,0.4-0.2,0.6c0.1,0.1,0.2,0,0.3,0c0.2-0.2,0.4-0.4,0.6-0.6c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1 + c-0.2,0.4-0.4,1-1,1.1c-0.2,0-0.4,0-0.5-0.1c-0.1-0.3,0-0.7,0.2-1C45.7,53.1,45.8,52.8,46.1,52.7z M46,56.6c0,0.4,0.1,0.9-0.1,1.2 + c-0.1,0.1-0.2,0.2-0.3,0.1c-0.2-0.1-0.2-0.2-0.2-0.4c0-0.4-0.1-0.8,0.1-1.2c0.1-0.3,0.1-0.5,0.2-0.8c0-0.2,0.1-0.4,0.1-0.6 + c0.1,0.1,0,0.3,0.1,0.4C46,55.8,45.8,56.2,46,56.6z M45.3,59.6c0.1-0.2,0.2-0.5,0.4-0.7c0.1-0.2,0.4-0.1,0.6-0.2 + c0.2,0.1,0.6-0.1,0.5,0.2c-0.2,0.4-0.4,0.9-0.2,1.3c-0.1,0.2-0.6,0-0.5,0.3c0.2,0.3,0.5,0.1,0.6,0.4c0.1,0.3,0.1,0.7,0.2,1 + c0,0.1-0.1,0-0.1,0c-0.3-0.2-0.6-0.4-0.9-0.2c-0.2,0.1-0.3,0.3-0.5,0.5c-0.1,0.1-0.1-0.1-0.1-0.1C45,61.3,45.1,60.3,45.3,59.6z + M47.8,57c-0.2-0.3-0.3-0.7-0.5-1c0-0.4-0.1-0.7,0-1.1c0-0.1,0-0.2,0.1-0.3l0,0c0,0.8,0.5,1.3,0.9,1.9c0.3,0.3,1,0.4,0.9,1 + c0,0.3,0.2,0.5,0,0.8c-0.1,0-0.1-0.1-0.1-0.1C48.8,57.7,48.2,57.4,47.8,57z M49.3,56c-0.4-0.4-0.7-0.9-0.5-1.5c0-0.4,0.2-0.8,0.5-1 + c0.1-0.1,0-0.3,0.2-0.3c0.1,0.1,0,0.2-0.1,0.2c0.1,0.4,0.3,1-0.1,1.3c0,0.1,0,0.2,0.1,0.2c0.4,0.1,0.3-0.4,0.5-0.5 + c0,0.3-0.2,0.6-0.4,0.8c0,0.1,0.2,0.1,0.2,0.2c0.2,0,0.3-0.3,0.4-0.4c0.1-0.5,0.1-0.9-0.2-1.3c0-0.1-0.1-0.3,0.1-0.5 + c0.3,0,0.4,0.3,0.5,0.5c0.2,0.4,0.3,1,0.1,1.4c0.1,0.5-0.4,0.6-0.6,0.9C49.8,56,49.5,56.2,49.3,56z M50.3,57c0-0.2,0.2-0.3,0.3-0.5 + c0.2-0.5,0.4-0.9,0.7-1.3c0.2-0.2,0.1-0.5,0.2-0.8c0.1,0,0.1,0.2,0.2,0.3c0.1,0.5,0.1,1.1-0.1,1.5c-0.3,0.6-0.8,1.1-1,1.6 + c-0.1,0.1-0.1,0.3-0.2,0.4C50.1,57.9,50.1,57.4,50.3,57z M50.6,58.9c0.1-0.5,0.4-0.9,0.6-1.3c0.4-0.5,0.6-1,0.8-1.5 + c0-0.1-0.1-0.2,0-0.3c0.2,0.3,0.3,0.7,0.2,1.1c0,1-1.1,1.6-1.2,2.5c-0.1,0.1-0.2,0.3-0.3,0.4C50.6,59.6,50.7,59.2,50.6,58.9z + M53,56.9c0-0.6,0.2-1.1,0.2-1.7c0-0.1,0.1-0.2,0.1-0.1c0.1,0.6,0,1.2,0.2,1.7c0,0.4,0.1,0.9-0.3,1.1C53.1,58,53,57.9,53,57.8 + C52.8,57.5,53,57.2,53,56.9z M53.8,53.5c-0.1,0.1-0.2,0.2-0.4,0.1c-0.6-0.2-0.8-0.8-0.9-1.3c0.1,0,0.2,0.2,0.3,0.2 + c0.2,0.1,0.3,0.5,0.6,0.3c0-0.3-0.3-0.4-0.4-0.7c0-0.1-0.1-0.2-0.1-0.3c0.1,0,0.1,0.2,0.3,0.3c0.3,0.1,0.6,0.4,0.7,0.7 + C54,53,54,53.3,53.8,53.5z M52.7,44.8c-0.4-0.3-0.5-0.7-0.6-1.2c0-0.1-0.1-0.3,0-0.4c0.1,0,0.1,0.1,0.1,0.1 + c0.2,0.2,0.4,0.6,0.7,0.7c0.1,0.1,0.1,0.1,0.1,0.2c0.1,0,0.2,0,0.2-0.1c0-0.1-0.1-0.3-0.2-0.4c-0.1-0.3-0.4-0.5-0.3-0.9 + c0.1-0.1,0.2,0.1,0.4,0.2c0.4,0.1,1,0.4,1.1,0.9c0,0.3,0,0.7-0.2,0.9C53.5,45,53,44.9,52.7,44.8z M53.9,41.8 + c0.1,0.1,0.2,0.2,0.3,0.2c0.2,0.2,0.4,0.5,0.3,0.8c-0.1,0.1-0.1,0.3-0.2,0.4c-0.3,0-0.5-0.3-0.7-0.5c-0.2-0.2-0.3-0.4-0.2-0.7 + c0-0.1,0.1,0,0.2,0c0.2,0.1,0.3,0.4,0.5,0.2C54,42.1,53.8,42,53.9,41.8z M54.2,41.6c-0.3-0.5-0.6-0.9-0.6-1.5c0,0,0.1,0,0.1,0 + c0.2,0.3,0.5,0.8,1,0.8c0.1-0.1-0.1-0.3-0.1-0.4c0-0.2-0.1-0.3-0.1-0.5c0.1,0,0.1,0.1,0.2,0.2c0.3,0.2,0.6,0.4,0.7,0.8 + c0,0.3,0,0.7-0.3,1C54.7,41.9,54.4,41.8,54.2,41.6z M51,45.4c-0.3,0.4-0.9,0.8-1.5,0.8c-0.3-0.1-0.6-0.1-0.8-0.4 + c0-0.2-0.3-0.3-0.2-0.6c-0.2-0.5-0.4-1-0.3-1.6c-0.1-0.6,0.1-1.3,0.2-1.9c0.1-0.1,0.2-0.4,0.3-0.2c0,0.6-0.2,1.1,0.1,1.6 + c0.1,0,0.1,0.1,0.2,0.1c0.2-0.1,0-0.4,0.1-0.6c0.1-0.1,0.1,0,0.2,0.1c0.1,0.6,0,1.3,0.3,1.8c0.1,0.1,0.2,0.2,0.3,0.1 + c0.1-0.1,0-0.1,0.1-0.2c-0.3-0.8-0.3-1.8,0-2.6c0.1,0,0.1,0,0.1,0.1c0.1,0.5-0.1,1.1,0.1,1.5c0.2-0.1,0.2-0.3,0.3-0.5 + c0.1-0.5,0-1.1,0.1-1.6c0.1,0,0,0.1,0.1,0.1C51,42.7,51.8,44.2,51,45.4z M48.6,34c0-0.1,0.1-0.3-0.1-0.3c-0.1,0-0.3,0.1-0.4,0.1 + c0,0-0.1-0.1-0.1-0.1c0,0,0,0,0-0.1c0.2-0.1,0.5-0.3,0.7-0.4c0.1-0.1,0.2-0.2,0.3-0.1C49.1,33.5,48.8,33.8,48.6,34 + C48.6,34.1,48.6,34.1,48.6,34z M47.9,33.2c-0.2,0-0.4,0.1-0.6-0.1c0.1-0.2,0.3-0.1,0.4-0.2c0.3-0.1,0.5,0.2,0.7,0.2c0,0,0,0,0,0.1 + C48.3,33.2,48.1,33.1,47.9,33.2z M48.5,31.6c-0.1,0-0.1-0.2-0.2-0.2c-0.1-0.1-0.1-0.1-0.2-0.1c-0.1,0.1-0.2,0.3-0.3,0.5l0,0.1 + c-0.2,0-0.2-0.2-0.4-0.3c-0.1-0.3,0.2-0.5,0.3-0.7c0.2,0,0.5,0.1,0.6,0.3C48.4,31.2,48.6,31.3,48.5,31.6z M47.7,32.2 + c-0.1,0.3,0.3,0.2,0.4,0.3l0,0.1c0,0.1-0.2,0.1-0.3,0.1c-0.3-0.1-0.6-0.1-0.8,0.1c-0.1,0-0.2,0-0.3-0.1c0-0.2,0.3-0.1,0.4-0.1 + c0.1-0.1,0.2-0.1,0.3-0.2c-0.3-0.3-0.7,0-1,0c-0.2,0.1-0.5,0.1-0.7,0c0,0,0-0.1,0.1-0.1c0.3,0.1,0.5-0.2,0.8-0.2 + c0.2-0.1,0.5,0,0.8,0C47.5,32.1,47.6,32.2,47.7,32.2z M46.9,31.7c-0.5,0-0.9,0.3-1.5,0.2c0,0-0.1,0-0.1-0.1c0-0.1,0.1-0.1,0.1-0.1 + c0.1-0.2,0.4-0.1,0.5-0.2c0.1,0,0.3,0,0.4-0.1c0.3,0,0.7,0,0.9,0.3l0,0.1C47.1,31.8,47,31.7,46.9,31.7z M45.6,33.1 + c0.6-0.2,1.2,0,1.6,0.3c0.4,0.5,0.5,1.3,0.2,1.9c-0.2,0.4-0.5,0.9-1,0.9c-0.6,0.3-1.2,0-1.7-0.4c-0.3-0.4-0.6-0.9-0.4-1.4 + C44.4,33.9,45,33.3,45.6,33.1z M43.7,42.8C43.7,42.8,43.7,42.9,43.7,42.8c0,1.2,0.1,2.3,0.2,3.6c0.1,1.1,0.1,2.2,0.2,3.2 + c0,0.2-0.2,0.3-0.3,0.5c-0.1,0.1-0.2,0.3-0.4,0.3c-0.2-0.3-0.1-0.7-0.2-1.1c-0.1-1.7-0.3-3.6-0.3-5.4c0.1-0.2,0.2-0.4,0.3-0.7 + C43.4,43.2,43.6,43,43.7,42.8z M44.2,49.9L44.2,49.9c0.3-0.3,0.6-0.6,0.8-0.8c0,0,0.1,0,0.1,0c-0.1,0.5-0.2,1-0.6,1.5 + c0,0.1,0,0.1,0.1,0.1c0.2-0.3,0.4-0.5,0.7-0.8c0.2-0.2,0.3-0.4,0.5-0.6c0.1,0.2,0,0.4,0,0.5c-0.1,0.8-0.4,1.5-1.2,1.9 + c-0.3,0-0.4,0.2-0.7,0.1c-0.2,0-0.4-0.2-0.5-0.4C43.4,50.9,43.8,50.4,44.2,49.9z M43.8,52.2l0.3-0.1c0,0,0.1,0,0.1,0.1 + c0.1,0.9,0.1,1.8,0.2,2.7c0,0.7,0.1,1.2,0.2,1.9c0.1,0.4,0,0.9,0.2,1.3c0.2,0.4-0.1,0.6-0.2,0.9c-0.3,0,0-0.4-0.2-0.6 + c-0.3-1.2-0.6-2.3-0.7-3.6c-0.1-0.6-0.1-1.2-0.2-1.8c-0.1-0.3,0-0.6-0.1-0.9C43.6,52.1,43.7,52.2,43.8,52.2z M43.6,60.8 + c0-0.4,0.1-0.8,0.3-1.1c0-0.2,0.2-0.2,0.4-0.3c0.2,0,0.4-0.2,0.6,0c0,0.1,0.2,0.2,0.1,0.4c-0.1,0.2-0.2,0.4-0.5,0.6 + c-0.1,0-0.3-0.1-0.3,0.1c0,0.3,0.4,0.1,0.5,0.3c0,0.2,0.1,0.5,0,0.7c-0.2,0-0.5,0-0.7,0.1c-0.1,0.1-0.2,0.2-0.3,0.1 + C43.4,61.5,43.5,61.1,43.6,60.8z M44.1,61.8c0.2-0.1,0.4-0.1,0.6,0c0,0.2-0.1,0.5-0.1,0.7c0,0.3,0.2,0.6,0.5,0.7v0 + c-0.2,0.1-0.4-0.1-0.6-0.2c-0.3-0.2-0.3-0.5-0.4-0.7C44.1,62.2,43.9,61.9,44.1,61.8z M46.1,62c0.2,0,0.4,0,0.6,0.2 + c0,0.2-0.1,0.4-0.1,0.7c0,0.3,0,0.6,0.2,0.8l0,0.1c-0.2,0-0.4-0.2-0.5-0.3c-0.3-0.3-0.6-0.6-0.6-1C45.7,62.2,45.9,62.1,46.1,62z + M55.5,61.8c-0.1,0,0-0.1,0-0.2c0.2-0.3,0.5-0.1,0.8-0.2l0,0c0.1,0.3-0.3,0.5-0.4,0.8c-0.1,0.1-0.1,0.2-0.1,0.2 + c-0.2,0.2-0.3,0.4-0.5,0.6l-0.1,0C55.3,62.7,55.7,62.3,55.5,61.8z M56.4,61.1c-0.1,0.1-0.1,0.1-0.2,0.1c-0.3-0.1-0.5,0.1-0.8,0.1 + c-0.1-0.2-0.2-0.5-0.2-0.7c0.2-0.2,0.4-0.3,0.5-0.5c0-0.1,0-0.1-0.1-0.1c-0.2,0-0.4,0.4-0.6,0.1c-0.1-0.2-0.2-0.5-0.3-0.8 + c0.2-0.1,0.4,0,0.5,0.1l0.3,0.1c0.5,0.1,0.5,0.7,0.8,1C56.4,60.6,56.7,60.9,56.4,61.1z M55.3,51c-0.6,0.1-1.2-0.2-1.6-0.6 + c-0.2-0.3-0.4-0.6-0.4-1c0-0.1,0.1-0.1,0.2-0.1c0.3,0.3,0.7,0.6,1.1,0.7l0.1-0.1c0.1,0,0.1,0.2,0.2,0.1c0,0,0.1-0.1,0-0.1 + c-0.5-0.4-0.8-0.9-0.9-1.4c0-0.1,0.1-0.1,0.2-0.1c0.5,0.3,1,0.7,1.5,1.1c0.2,0.3,0.4,0.6,0.3,0.9C55.7,50.7,55.5,50.9,55.3,51z + M55.6,41.2c0-0.1,0.1,0,0.1,0c0.2,0.2,0.3,0.4,0.5,0.6c0.4,0.3,0.7,0.7,1.2,0.8c0.1,0.2,0.4,0.2,0.5,0.3c0,0.2-0.1,0.4-0.3,0.4 + c-0.6,0-0.9-0.4-1.3-0.8C56,42.2,55.8,41.7,55.6,41.2z M57.9,40.3c-0.1,0.1-0.3,0-0.4-0.1c-0.4-0.2-0.2-0.6-0.3-1 + c0-0.3-0.1-0.6,0.1-0.8c0.1,0,0.1,0.1,0.1,0.1C57.6,39.1,57.9,39.6,57.9,40.3z M57.5,36.4c0,0.1-0.1,0.1-0.2,0 + c-0.1-0.2-0.4-0.3-0.5-0.6c0-0.1-0.2-0.1-0.2,0c0,0-0.1,0.1,0,0.1c0.3,0.4,0.4,0.8,0.7,1.2c0,0.2-0.2,0.4-0.3,0.6c0,0-0.1,0-0.1,0 + c-0.2-0.1-0.2-0.3-0.3-0.5c0-0.1-0.1-0.3-0.1-0.4c0.1-0.4-0.3-0.6-0.4-0.9c-0.2-0.2-0.5-0.2-0.6-0.4c0-0.1,0-0.2,0.1-0.2 + c0.3-0.3,0.6,0.1,0.9-0.1c0.1,0.1,0.3,0,0.4,0c0.2,0.1,0.4,0.3,0.6,0.3c0.2,0.1,0.2,0.3,0.2,0.5C57.6,36.2,57.5,36.3,57.5,36.4z + M57,32.7c0,0.1-0.1,0.3,0,0.4c0.1,0.1,0.3,0.2,0.3,0.3c0,0.1,0,0.2-0.1,0.2c-0.3,0-0.6,0.1-0.8,0.4c0,0.1,0,0.1,0.1,0.1 + c0.2,0,0.2-0.3,0.5-0.3c0.2,0,0.3-0.1,0.5,0c0,0.2,0.2,0.3,0.2,0.4c-0.1,0.3,0.1,0.7-0.1,1c-0.4,0-0.7-0.4-1.1-0.1 + c-0.2,0-0.5-0.2-0.7-0.1c-0.2-0.1-0.3-0.4-0.2-0.6c0.1-0.2,0.3-0.1,0.4-0.3c0.1,0,0.3,0.1,0.3,0c0-0.2-0.3-0.1-0.4-0.1 + c-0.1,0-0.2,0.1-0.4,0.1c-0.1-0.1-0.1-0.2-0.1-0.4c0.2-0.4,0.7-0.5,1-0.6c0,0,0.1-0.1,0-0.1c-0.4-0.3-0.9,0.1-1.2,0.3 + c-0.1,0-0.1,0-0.1-0.1c0.1-0.3,0.2-0.6,0.5-0.7c0,0,0.1-0.1,0.1-0.1c-0.1-0.1-0.2,0-0.3,0c-0.1,0.1-0.3,0.3-0.5,0.4 + c0-0.2,0.3-0.4,0.4-0.7c0,0,0-0.1-0.1-0.1c-0.3,0.2-0.5,0.5-0.9,0.7c-0.1,0-0.2,0-0.3,0c-0.1,0,0-0.1,0-0.2 + c0.2-0.3,0.5-0.6,0.6-0.9c0.2-0.6,0.9-0.5,1.3-0.9c0.2,0.1,0.4-0.1,0.5,0.1C56.2,31,56.1,31,56,31.1c-0.2,0.2-0.6,0.3-0.7,0.6 + c0.2,0.1,0.2-0.2,0.4-0.2c0.1-0.1,0.2-0.2,0.3-0.1c0.2,0.2,0.3-0.3,0.4,0.1c-0.1,0.2-0.3,0.2-0.4,0.3c-0.1,0.1-0.3,0.3-0.3,0.5 + c0,0.1,0.1,0,0.2,0c0.2-0.2,0.4-0.4,0.7-0.4C56.9,32.1,57,32.4,57,32.7z M53.5,29.8c0.2-0.3,0.6-0.2,0.8-0.4c0.7-0.2,1.4,0.1,2-0.4 + l0.7-0.5c0.3,0,0.4-0.3,0.6-0.4c0.1,0,0.2,0,0.2,0.1c-0.1,0.3-0.2,0.6-0.3,1c-0.1,0.5-0.6,0.6-1,0.9c-0.2,0.2-0.5,0.2-0.8,0.2 + c-0.6,0-1.1,0.3-1.4,0.8c0.1,0.2-0.1,0.3-0.2,0.3c-0.1,0.1-0.3,0.1-0.4,0.2c0.1,0.1,0.2,0,0.2,0.2c-0.3,0.3-0.8,0-1.1,0.3 + c0,0-0.1,0.1-0.1,0.1c0.1,0.1,0.3,0,0.3,0.1c-0.2,0.2-0.6,0.1-0.8,0.3c0,0.1,0,0.1,0.1,0.1c0.1,0,0.2-0.1,0.3,0 + c0,0.1-0.1,0.1-0.2,0.2c-0.3,0.1-0.6,0-0.8,0.2c0.1,0.1,0.3,0.1,0.4,0.2c-0.3,0.2-0.7,0.2-0.9,0.4c-0.2,0.2,0.1,0.7-0.3,0.5 + c-0.2-0.2-0.3-0.4-0.4-0.7c0.1-0.1,0-0.4,0.1-0.3c0.2,0.1,0.2,0.3,0.3,0.4c0.1,0,0.2-0.1,0.3-0.2c-0.2-0.3,0.3-0.3,0.4-0.5 + c0-0.3,0.3-0.2,0.4-0.3c0.3-0.1,0.5-0.1,0.8-0.2c0,0-0.1,0-0.1-0.1c0,0-0.1,0-0.1,0c0,0,0,0,0-0.1c0.3-0.4,0.8-0.3,1.2-0.4 + c0-0.1-0.2-0.1-0.1-0.2c0.3-0.2,0.8-0.1,0.9-0.5c0-0.1,0.1-0.2,0-0.2c-0.2,0.1-0.3,0.3-0.5,0.4c-0.2,0.2-0.4,0.3-0.6,0.4 + c0-0.1,0.1-0.2,0.2-0.3c0.3-0.3,0.5-0.7,0.7-1.2c0-0.1-0.1,0-0.2,0c-0.3,0.3-0.7,0.5-1,0.8c-0.1,0-0.2,0.1-0.2,0 + c-0.1-0.2,0.2-0.2,0.2-0.4C53.1,30.2,53.3,30,53.5,29.8z M50.2,31.6c-0.1-0.1-0.1-0.3-0.1-0.5c0,0-0.1,0-0.1,0 + c-0.1,0.1-0.2,0.3-0.2,0.4c0,0-0.1,0-0.1,0c-0.1-0.3,0-0.6,0.1-0.8c0.1-0.1,0.2-0.2,0.3-0.2c0.1,0.1,0.2,0.2,0.3,0.3 + C50.4,31.1,50.4,31.4,50.2,31.6z M51.2,31.2c-0.1-0.1-0.2,0.1-0.3,0.1c-0.1,0.1-0.2,0.3-0.3,0.4c-0.1,0-0.1,0-0.1-0.1 + c0-0.3,0.1-0.5,0.2-0.8c0.1-0.2,0.4-0.2,0.5-0.4c0.1-0.1,0.4-0.2,0.4,0.1c0,0.2,0.1,0.4,0.2,0.6c0,0.2-0.2,0.4-0.2,0.6 + c0,0-0.1,0.1-0.2,0.1C51.4,31.6,51.3,31.4,51.2,31.2z M51.5,28.9c0-0.3,0.3-0.2,0.5-0.3c0.3,0,0.7,0,0.9,0.3 + c0.1,0.1,0.1,0.2,0.1,0.4c-0.2,0.1-0.1,0.4-0.3,0.5c-0.3-0.1-0.2-0.4-0.4-0.6c-0.3-0.2-0.5,0.1-0.8,0.2 + C51.3,29.2,51.5,29,51.5,28.9z M51.8,29.5c0.1,0,0.1,0,0.2,0.1c0,0.4,0.5,0.7,0.1,1c-0.3,0-0.2-0.3-0.3-0.5 + c-0.2-0.2-0.4,0.2-0.6,0.1c-0.1,0-0.2-0.1-0.1-0.2C51.1,29.7,51.5,29.6,51.8,29.5z M49.7,28.9c0.2-0.4,0.6-0.4,1-0.4 + c0.2,0.2,0.2,0.4,0.4,0.5c0,0.1,0,0.3-0.1,0.4c-0.1,0-0.2-0.2-0.3-0.2C50.5,29,50.3,29,50.1,29c-0.1,0-0.2,0.2-0.3,0.1 + C49.7,29.1,49.7,29,49.7,28.9z M50.1,29.4c0.2-0.1,0.3,0.2,0.4,0.4c0,0.1,0.3,0.2,0.2,0.4c-0.1,0.1-0.1,0.2-0.2,0.2 + c-0.2-0.1-0.3-0.4-0.5-0.3c-0.1,0.1-0.2,0.2-0.3,0.2c-0.1-0.1-0.1-0.3-0.1-0.4C49.8,29.6,49.9,29.5,50.1,29.4z M49.6,33.3 + c0.2-0.1,0.4,0.1,0.5-0.1l0,0c0,0.2,0.2,0.5,0.1,0.7c0,0.1,0.1,0.2,0.1,0.4c-0.1,0-0.1-0.2-0.2-0.3c0-0.1-0.1-0.2-0.2-0.2 + c-0.2,0-0.1,0.5-0.3,0.2c-0.1-0.2,0.1-0.4-0.1-0.5c-0.1,0.2-0.2,0.3-0.3,0.5c-0.1,0-0.2-0.1-0.2-0.2c0.3-0.1-0.1-0.5,0.3-0.6 + C49.4,33.2,49.5,33.2,49.6,33.3z M49.4,31.3c-0.1,0-0.1-0.1-0.1-0.2c0-0.1-0.1-0.2-0.2-0.1C49,31.1,49,31.2,49,31.4l0,0 + c-0.2-0.2-0.3-0.4-0.2-0.7c0-0.2,0.2-0.3,0.3-0.4c0.1,0,0.2,0.1,0.3,0.2C49.5,30.8,49.5,31.1,49.4,31.3z M48.7,30.1 + c0,0.1-0.1,0.2-0.2,0.3c-0.1,0-0.2-0.1-0.2-0.1c-0.1-0.1,0-0.2,0-0.3c0.1-0.2,0.2-0.5,0.4-0.6c0.2,0,0.4,0.3,0.6,0.3 + c0.1,0.1,0.1,0.2,0.1,0.3C49.1,30.1,48.8,29.8,48.7,30.1z M48.7,28.4c0.1,0,0.3,0,0.4,0.1c0.1,0.1,0.1,0.3,0.3,0.5 + c0,0.1,0,0.2-0.1,0.2c-0.4,0.1-0.4-0.4-0.8-0.3c-0.1,0.1-0.3,0.3-0.4,0.5c-0.1,0-0.1,0.1-0.2,0.1c-0.1-0.1-0.2-0.2-0.2-0.3 + C47.9,28.8,48.2,28.4,48.7,28.4z M47.9,30c0,0.1,0.1,0.3,0,0.4c-0.2,0-0.5,0-0.6,0.3c-0.1,0.1-0.1,0.3-0.3,0.4 + c-0.1-0.1-0.2-0.2-0.3-0.4c0.1-0.2,0.2-0.5,0.3-0.7c0,0,0.1-0.1,0.1-0.1C47.5,29.9,47.7,30.1,47.9,30z M46.6,28.8 + c0.2,0,0.4,0,0.6,0.2c0.1,0.1,0.2,0.3,0.3,0.3c0.1,0,0.1,0.1,0.1,0.2c-0.1,0.1-0.2,0-0.3,0c-0.2,0-0.5-0.3-0.7,0.1 + c-0.1,0.1-0.1,0.3-0.2,0.3c-0.1-0.1-0.2-0.3-0.2-0.5C46.3,29.2,46.4,28.9,46.6,28.8z M41.5,28.9c0-0.3,0-0.5,0-0.8 + c0,0,0.1-0.1,0.1-0.1c0.3-0.1,0.2,0.3,0.4,0.4c0.1,0.3,0.4,0.6,0.7,0.6c0.6,0,1.2-0.1,1.8,0.1c0.4,0.1,0.8,0.4,1.1,0.8 + c0.1,0,0.1-0.1,0.2-0.1c0.1,0.1,0.4,0.2,0.3,0.4c0.3,0,0.4,0.4,0.7,0.6c-0.2,0.2,0.5,0.5-0.1,0.5c-0.4-0.2-0.8,0.1-1.2,0.1 + c-0.1,0-0.2,0-0.3-0.1l0-0.1c0.2-0.2,0.5-0.3,0.8-0.3c0.1,0,0-0.2,0.2-0.1c0.1,0.1,0.1,0.2,0.2,0.2c0,0,0-0.1,0-0.1 + c-0.2,0-0.2-0.3-0.4-0.3c-0.2,0-0.3,0-0.4-0.2c-0.1-0.3-0.4-0.4-0.6-0.5c-0.1-0.1-0.2-0.1-0.3-0.1c-0.1,0.1-0.1,0.1-0.1,0.2 + c0.2,0.3,0.4,0.6,0.7,0.8v0c-0.3,0-0.5-0.4-0.7-0.3c0,0-0.1,0.1,0,0.2c0.1,0.2,0.4,0.4,0.2,0.6c-0.2,0-0.3-0.2-0.4-0.3 + c0-0.3-0.3-0.3-0.5-0.4c-0.2-0.1-0.4,0-0.7,0c-0.2-0.1-0.4,0.1-0.6-0.1C42,30.2,41.5,29.6,41.5,28.9z M41.3,40 + c0.1-0.4,0-0.8,0.3-1.1c0.2,0,0.1,0.3,0.1,0.4c0.1,0.3,0.1,0.7,0.2,1c-0.1,0.2-0.3,0.3-0.5,0.3C41.2,40.5,41.3,40.2,41.3,40z + M43,39.5c0.1-0.1,0.2-0.1,0.2,0c0,0.3-0.1,0.6-0.2,0.9c-0.3,0.4-0.4,0.9-0.7,1.3c-0.2,0.1-0.4,0.4-0.7,0.4 + c-0.1-0.2-0.3-0.4-0.3-0.7C41.9,40.8,42.6,40.2,43,39.5z M41.8,43.2c-0.1,0.1-0.2,0.2-0.4,0.1c0-0.2-0.1-0.6,0.1-0.7 + c0.1-0.1,0.3-0.3,0.4-0.1C42,42.8,42,43.1,41.8,43.2z M42.2,43.1c0.3-0.4,0.7-0.7,0.9-1.2c0,0,0.1-0.1,0.1-0.1 + c-0.1,0.8-0.4,1.6-0.9,2.2c-0.2,0.3-0.6,0.4-0.9,0.5c-0.1,0-0.2-0.1-0.2-0.2c0-0.1-0.1-0.2-0.1-0.3C41.5,43.8,41.9,43.5,42.2,43.1z + M40.1,42.7c0-0.3,0.1-0.5,0.4-0.7c0.1-0.1,0.3-0.2,0.5-0.2l0.2,0.3c0,0.4-0.4,0.5-0.7,0.8c-0.1,0-0.1,0.1-0.2,0.1 + C40.1,42.9,40.1,42.8,40.1,42.7z M40.3,46.6c-0.1,0-0.2-0.1-0.3-0.1c-0.1-0.1-0.2-0.3-0.2-0.5c0.1-0.2,0.4-0.3,0.5-0.5 + c0.3-0.2,0.5-0.5,0.8-0.8c0.1,0,0.3-0.1,0.4,0C41.3,45.4,40.9,46,40.3,46.6z M42.1,56c-0.4-1.3-0.8-2.6-1-4 + c-0.2-1.2-0.3-2.4-0.5-3.6c0.1-0.5,0-1.1,0-1.6c0.1-0.2,0.3-0.3,0.5-0.4c0,0,0.1,0,0.1,0c0,0.9,0.2,1.7,0.2,2.6 + c0.1,0.7,0.2,1.4,0.2,2c0,0.7,0.1,1.4,0.1,2.1c0.1,0.8,0.2,1.5,0.3,2.2C42,55.6,42.1,55.8,42.1,56L42.1,56z M42.4,55 + c-0.1-0.6-0.1-1.3-0.2-1.9c-0.2-1.2-0.2-2.5-0.3-3.7c-0.1-0.3-0.1-0.7-0.1-1.1c-0.1-0.8-0.1-1.6-0.2-2.3c-0.1-0.5,0.1-0.9,0.2-1.2 + c0.1-0.1,0.3-0.3,0.4-0.2c0.1,0.8,0,1.6,0.1,2.4c0.1,0.3,0.1,0.7,0.1,1c0.1,1.3,0.1,2.5,0.3,3.7c0.2,1.7,0.4,3.4,0.6,5.2 + c0.1,0.6,0.2,1.2,0.3,1.9c0,0-0.1,0.1-0.1,0C42.9,57.6,42.6,56.3,42.4,55z M56.5,55.4c-0.2,0.9-0.3,1.8-0.6,2.7 + c0,0.3-0.1,0.6-0.2,0.8c0,0-0.1,0-0.1,0c0-0.7,0.3-1.2,0.3-1.8c0.1-0.5,0.1-1,0.2-1.5c0.1-0.7,0.1-1.3,0.1-2 + c0.1-0.2,0.1-0.5,0.1-0.7c-0.1-0.5,0.1-1,0.1-1.5c0.1-0.5,0.2-1.1,0.2-1.6c0.1-1,0.2-1.9,0.2-2.9c0.1-0.3,0-0.7,0.1-0.9 + c0-0.3,0-0.5,0-0.8c0.1-0.2-0.2-0.7,0.2-0.8c0.1,0.1,0.3,0.2,0.4,0.3c0,0.3-0.1,0.6-0.1,0.9c0,0.5-0.1,1-0.1,1.6 + c0,0.8,0,1.5-0.1,2.2c-0.1,0.9-0.2,1.8-0.3,2.6C56.9,53.1,56.7,54.2,56.5,55.4z M58.7,45.9c-0.1,0.6,0,1.1-0.1,1.7 + c0,0.5-0.2,1-0.2,1.5c0,0.8-0.3,1.5-0.3,2.3c-0.1,0.8-0.3,1.5-0.5,2.3c-0.2,0.9-0.5,1.8-0.8,2.6c0,0-0.1,0-0.1,0 + c0.1-0.8,0.3-1.7,0.4-2.5c0.2-1,0.4-2.1,0.6-3.1c0.1-0.8,0.1-1.6,0.2-2.4c0.1-1,0.2-2,0.3-2.9c0.1-0.1,0.3,0.1,0.4,0.1 + C58.7,45.6,58.7,45.7,58.7,45.9z M59.3,45.4c-0.5-0.4-1-0.7-1.3-1.2c-0.1-0.1-0.2-0.3-0.2-0.5c0.1-0.1,0.1-0.2,0.2-0.1 + c0.2,0,0.3,0.3,0.6,0.3c0.1,0.1,0.1,0.2,0.1,0.3c0.2,0.2,0.5,0.5,0.7,0.7c0.1,0.1,0.2,0.2,0.1,0.4C59.5,45.3,59.4,45.5,59.3,45.4z" + /> + <path class="st0" d="M42.1,29.1c0.2,0.2,0.5,0.2,0.8,0.2c0.3,0.1,0.6,0,0.8,0.2c0.1,0.1,0.3,0.2,0.3,0.5L44,30 + c-0.6-0.3-1.3,0-1.8-0.5c-0.2,0-0.3-0.2-0.3-0.4c0-0.1,0-0.1,0-0.2C42,28.9,42,29.1,42.1,29.1z"/> + <path class="st0" d="M57.4,29c0,0.2-0.1,0.3-0.3,0.4c-0.5,0.3-1.2,0.5-1.9,0.4c0,0,0-0.1,0-0.1c0.4-0.1,0.9-0.2,1.3-0.4 + C56.7,29.2,57,29,57.4,29L57.4,29z"/> + <path class="st0" d="M45.2,33.9c-0.1,0-0.8,1.1-0.1,1.7c0.9,0.8,2-0.6,1.8-0.9c-0.1,0-0.4,0.8-1.2,0.6 + C44.8,35.1,45.3,33.9,45.2,33.9z"/> + <path class="st0" d="M52.5,35.4c0,0.3,1.1,0.8,1.7,0.1c0.7-1.1-0.3-1.7-0.6-1.4c-0.1,0.1,0.6,0.4,0.3,1.1 + C53.4,35.9,52.5,35.2,52.5,35.4z"/> +</g> +<rect class="st1" width="409.7" height="99.2"/> +<g> + <g> + <path class="st0" d="M111.3,48.1c0-1.3,0-3.7-0.4-4.3c-0.1-0.2-0.5-0.4-1-0.4l-0.5,0c-0.1-0.1-0.1-0.4,0-0.5 + c0.8,0,1.6,0.1,2.4,0.1c0.9,0,1.4,0,2.2-0.1c0.2,0.1,0.1,0.4,0,0.5l-0.5,0c-0.5,0-0.9,0.2-1,0.5c-0.3,0.7-0.3,3.1-0.3,4.2v2.3 + c0,1.8-0.3,3.7-1.5,5c-0.9,1-2.4,1.5-4,1.5c-1.4,0-2.9-0.3-3.9-1.1c-1.1-0.9-1.6-2.4-1.6-4.9V46c0-2.2,0-2.5-1.2-2.6l-0.5,0 + c-0.1-0.1-0.1-0.4,0-0.5c1,0,1.7,0.1,2.6,0.1c0.9,0,1.5,0,2.6-0.1c0.1,0.1,0.2,0.4,0,0.5l-0.5,0c-1.2,0.1-1.2,0.5-1.2,2.6v4.5 + c0,3.3,1,5.5,4.2,5.5c3,0,4.1-2.4,4.1-5.5V48.1z"/> + <path class="st0" d="M131.1,53c0,0.6,0,3.1,0.1,3.6c0,0.1-0.2,0.2-0.4,0.2c-0.2-0.4-0.9-1.1-2.7-3.1l-4.8-5.5 + c-0.6-0.6-2-2.3-2.4-2.8h0c-0.1,0.2-0.1,0.7-0.1,1.3v4.5c0,1,0,3.7,0.4,4.3c0.1,0.2,0.5,0.4,1.1,0.4l0.6,0.1 + c0.1,0.2,0.1,0.4,0,0.5c-0.9,0-1.7-0.1-2.4-0.1c-0.9,0-1.4,0-2.2,0.1c-0.1-0.1-0.2-0.4,0-0.5l0.6-0.1c0.5-0.1,0.8-0.2,0.9-0.4 + c0.3-0.7,0.3-3.3,0.3-4.3v-6c0-0.6,0-1-0.5-1.5c-0.3-0.3-0.8-0.4-1.3-0.5l-0.4,0c-0.1-0.1-0.1-0.4,0-0.5c0.9,0.1,2,0.1,2.3,0.1 + c0.3,0,0.7,0,1-0.1c0.4,1.1,2.9,3.8,3.5,4.6l2,2.3c1.4,1.6,2.4,2.8,3.4,3.8h0c0.1-0.1,0.1-0.4,0.1-0.9v-4.4c0-1,0-3.7-0.4-4.3 + c-0.1-0.2-0.5-0.3-1.3-0.4l-0.4,0c-0.1-0.1-0.1-0.5,0-0.5c1,0,1.7,0.1,2.4,0.1c0.9,0,1.4,0,2.1-0.1c0.2,0.1,0.2,0.4,0,0.5l-0.3,0 + c-0.7,0.1-1.1,0.3-1.2,0.4c-0.4,0.7-0.3,3.3-0.3,4.3V53z"/> + <path class="st0" d="M139.3,46c0-2.2,0-2.6-1.3-2.7l-0.5,0c-0.1-0.1-0.1-0.5,0-0.5c1,0,1.7,0.1,2.6,0.1c0.8,0,1.5,0,2.6-0.1 + c0.1,0.1,0.2,0.4,0,0.5l-0.5,0c-1.2,0.1-1.3,0.5-1.3,2.7v7.4c0,2.2,0,2.5,1.3,2.6l0.5,0.1c0.1,0.1,0.1,0.5,0,0.5 + c-1,0-1.7-0.1-2.6-0.1c-0.9,0-1.6,0-2.6,0.1c-0.1-0.1-0.2-0.4,0-0.5L138,56c1.2-0.1,1.3-0.4,1.3-2.6V46z"/> + <path class="st0" d="M148.8,45.1c-0.5-1.2-0.8-1.6-1.7-1.7l-0.4,0c-0.1-0.1-0.1-0.4,0-0.5c0.6,0,1.3,0.1,2.2,0.1 + c0.9,0,1.6,0,2.5-0.1c0.1,0.1,0.2,0.4,0,0.5l-0.3,0c-0.8,0.1-1,0.2-1,0.4c0,0.2,0.4,1.3,1,2.9c1,2.4,1.9,4.8,2.9,7.2 + c0.6-1.4,1.5-3.5,2-4.6c0.6-1.4,1.6-3.8,1.9-4.6c0.2-0.4,0.2-0.7,0.2-0.8c0-0.1-0.2-0.3-0.9-0.4l-0.4,0c-0.1-0.1-0.1-0.4,0-0.5 + c0.6,0,1.4,0.1,2.2,0.1c0.7,0,1.3,0,2-0.1c0.1,0.1,0.1,0.4,0,0.5l-0.6,0c-0.5,0-0.8,0.3-1.1,0.7c-0.6,1-1.4,2.7-2.3,4.8l-1.1,2.6 + c-0.8,1.9-1.8,4.3-2.2,5.4c-0.1,0-0.1,0.1-0.2,0.1c-0.1,0-0.2,0-0.3-0.1c-0.2-0.9-0.6-1.9-1-2.8L148.8,45.1z"/> + <path class="st0" d="M166.5,46c0-2.2,0-2.5-1.3-2.6l-0.3,0c-0.1-0.1-0.1-0.5,0-0.5c0.9,0,1.6,0.1,2.4,0.1h3.9c1.3,0,2.6,0,2.8-0.1 + c0.1,0.4,0.2,1.8,0.3,2.8c-0.1,0.1-0.4,0.2-0.5,0c-0.3-1-0.5-1.7-1.6-2c-0.4-0.1-1.1-0.1-2-0.1h-1.5c-0.6,0-0.6,0-0.6,0.8v4.1 + c0,0.6,0.1,0.6,0.7,0.6h1.2c0.9,0,1.5,0,1.8-0.1c0.2-0.1,0.4-0.2,0.5-0.7l0.2-0.9c0.1-0.1,0.5-0.1,0.5,0c0,0.5-0.1,1.3-0.1,2.1 + c0,0.7,0.1,1.5,0.1,2c-0.1,0.1-0.4,0.1-0.5,0l-0.2-0.8c-0.1-0.4-0.2-0.7-0.6-0.8c-0.3-0.1-0.8-0.1-1.6-0.1h-1.2 + c-0.6,0-0.7,0-0.7,0.6v2.9c0,1.1,0.1,1.8,0.4,2.2c0.2,0.2,0.7,0.5,2.5,0.5c1.6,0,2.2-0.1,2.7-0.3c0.4-0.2,0.9-0.9,1.5-2 + c0.1-0.1,0.4,0,0.5,0.1c-0.1,0.7-0.7,2.3-0.9,2.9c-1.9,0-3.7-0.1-5.6-0.1h-1.9c-0.9,0-1.6,0-2.8,0.1c-0.1-0.1-0.2-0.4,0-0.5 + l0.7-0.1c1.2-0.1,1.3-0.4,1.3-2.6V46z"/> + <path class="st0" d="M181.8,46c0-2-0.1-2.3-0.9-2.4l-0.7-0.1c-0.1-0.1-0.1-0.4,0-0.5c1.2-0.1,2.6-0.2,4.6-0.2 + c1.3,0,2.5,0.1,3.5,0.6c1,0.5,1.7,1.5,1.7,2.9c0,2-1.6,3-2.6,3.5c-0.1,0.1,0,0.3,0.1,0.5c1.7,2.7,2.8,4.3,4.2,5.5 + c0.4,0.3,0.9,0.5,1.4,0.6c0.1,0,0.1,0.2,0,0.3c-0.2,0.1-0.5,0.1-0.9,0.1c-1.8,0-2.8-0.5-4.3-2.6c-0.5-0.8-1.4-2.2-2-3.1 + c-0.3-0.5-0.6-0.7-1.5-0.7c-0.9,0-1,0-1,0.5v2.6c0,2.2,0,2.4,1.2,2.6l0.4,0.1c0.1,0.1,0.1,0.5,0,0.5c-0.9,0-1.6-0.1-2.5-0.1 + c-0.9,0-1.6,0-2.6,0.1c-0.1-0.1-0.2-0.4,0-0.5l0.5-0.1c1.2-0.1,1.2-0.4,1.2-2.6V46z M183.5,49c0,0.4,0,0.6,0.1,0.7 + c0.1,0.1,0.4,0.1,1.4,0.1c0.7,0,1.5-0.1,2.1-0.5c0.6-0.4,1-1.2,1-2.6c0-1.6-1-3.2-3.3-3.2c-1.3,0-1.3,0.1-1.3,0.7V49z"/> + <path class="st0" d="M200.2,56.9c-1.7,0-2.8-0.5-3.2-0.8c-0.2-0.5-0.5-1.9-0.6-2.9c0.1-0.1,0.4-0.2,0.5-0.1 + c0.3,1.1,1.2,3.1,3.6,3.1c1.7,0,2.6-1.1,2.6-2.4c0-0.9-0.2-1.9-1.7-2.9l-2-1.3c-1-0.7-2.2-1.9-2.2-3.6c0-2,1.5-3.6,4.2-3.6 + c0.6,0,1.4,0.1,1.9,0.3c0.3,0.1,0.6,0.1,0.7,0.1c0.2,0.5,0.4,1.7,0.4,2.5c-0.1,0.1-0.4,0.2-0.5,0.1c-0.3-1-0.8-2.3-2.8-2.3 + c-2,0-2.5,1.3-2.5,2.3c0,1.2,1,2.1,1.8,2.5l1.7,1c1.3,0.8,2.6,2,2.6,4C204.6,55.3,202.9,56.9,200.2,56.9z"/> + <path class="st0" d="M211.5,46c0-2.2,0-2.6-1.3-2.7l-0.5,0c-0.1-0.1-0.1-0.5,0-0.5c1,0,1.7,0.1,2.6,0.1c0.8,0,1.5,0,2.6-0.1 + c0.1,0.1,0.2,0.4,0,0.5l-0.5,0c-1.2,0.1-1.3,0.5-1.3,2.7v7.4c0,2.2,0,2.5,1.3,2.6l0.5,0.1c0.1,0.1,0.1,0.5,0,0.5 + c-1,0-1.7-0.1-2.6-0.1c-0.9,0-1.6,0-2.6,0.1c-0.1-0.1-0.2-0.4,0-0.5l0.5-0.1c1.2-0.1,1.3-0.4,1.3-2.6V46z"/> + <path class="st0" d="M226.6,53.4c0,2.2,0,2.5,1.2,2.6l0.7,0.1c0.1,0.1,0.1,0.5,0,0.5c-1.2,0-1.9-0.1-2.7-0.1c-0.8,0-1.6,0-2.9,0.1 + c-0.1-0.1-0.2-0.4,0-0.5l0.7-0.1c1.2-0.1,1.3-0.4,1.3-2.6v-9.3c0-0.6,0-0.7-0.6-0.7h-1.1c-0.9,0-2,0-2.6,0.5 + c-0.5,0.5-0.7,0.9-0.9,1.4c-0.2,0.1-0.5,0-0.5-0.1c0.3-0.9,0.6-2.3,0.8-3.1c0.1,0,0.3-0.1,0.4,0c0.1,0.7,0.8,0.6,1.8,0.6h8.4 + c1.1,0,1.3,0,1.6-0.6c0.1,0,0.3,0,0.4,0.1c-0.2,0.9-0.4,2.5-0.3,3.2c-0.1,0.2-0.4,0.2-0.5,0c-0.1-0.5-0.2-1.3-0.5-1.5 + c-0.5-0.4-1.3-0.5-2.4-0.5h-1.5c-0.6,0-0.6,0-0.6,0.7V53.4z"/> + <path class="st0" d="M243,53.4c0,2.2,0.1,2.5,1.2,2.6l0.8,0.1c0.1,0.1,0.1,0.5,0,0.5c-1.3,0-2-0.1-2.8-0.1c-0.9,0-1.6,0-2.7,0.1 + c-0.1-0.1-0.2-0.4,0-0.5L240,56c1.2-0.1,1.2-0.4,1.2-2.6v-1.1c0-1.1-0.1-1.4-0.7-2.6l-2.4-4.8c-0.7-1.4-1-1.5-1.6-1.6l-0.6-0.1 + c-0.1-0.1-0.1-0.4,0-0.5c0.7,0,1.4,0.1,2.4,0.1c1,0,1.7,0,2.2-0.1c0.2,0.1,0.2,0.4,0.1,0.5l-0.3,0c-0.7,0.1-0.9,0.2-0.9,0.4 + c0,0.2,0.5,1.4,0.6,1.6c0.8,1.5,1.5,3.2,2.3,4.6c0.6-1.1,1.3-2.3,1.9-3.5c0.6-1.1,1.3-2.5,1.3-2.7c0-0.1-0.4-0.3-0.9-0.3l-0.4,0 + c-0.1-0.1-0.1-0.4,0-0.5c0.7,0,1.3,0.1,2,0.1c0.6,0,1.2,0,1.9-0.1c0.2,0.1,0.2,0.4,0,0.5l-0.6,0.1c-1.1,0.2-1.7,1.5-2.7,3.3 + l-1.3,2.3c-0.9,1.6-1,1.8-1,3.4V53.4z"/> + <path class="st0" d="M260.3,49.9c0-4.1,3.1-7.3,7.4-7.3c4.8,0,7.2,3.5,7.2,7.1c0,4.2-3.2,7.2-7.2,7.2 + C263,56.9,260.3,53.6,260.3,49.9z M272.8,50.3c0-3.4-1.5-7.1-5.5-7.1c-2.2,0-5,1.5-5,6c0,3.1,1.5,7,5.6,7 + C270.4,56.2,272.8,54.4,272.8,50.3z"/> + <path class="st0" d="M283.2,48.7c0,0.6,0.1,0.6,0.7,0.6h1.4c0.8,0,1.5,0,1.8-0.1c0.2-0.1,0.4-0.2,0.5-0.7l0.2-0.8 + c0.1-0.1,0.5-0.1,0.5,0c0,0.5-0.1,1.3-0.1,2.1c0,0.7,0.1,1.5,0.1,2c-0.1,0.1-0.4,0.1-0.5,0l-0.2-0.8c-0.1-0.4-0.3-0.7-0.7-0.8 + c-0.3-0.1-0.8-0.1-1.6-0.1h-1.4c-0.6,0-0.7,0-0.7,0.6v2.9c0,2.2,0,2.5,1.3,2.6l0.7,0.1c0.1,0.1,0.1,0.5,0,0.5 + c-1.2,0-1.9-0.1-2.8-0.1c-0.9,0-1.6,0-2.6,0.1c-0.1-0.1-0.2-0.4,0-0.5l0.5-0.1c1.2-0.1,1.2-0.4,1.2-2.6V46c0-2.2,0-2.5-1.2-2.6 + l-0.3,0c-0.1-0.1-0.1-0.5,0-0.5c0.9,0,1.6,0.1,2.4,0.1h3.8c1.3,0,2.5,0,2.8-0.1c0,1,0,1.9,0.1,2.7c-0.1,0.1-0.4,0.2-0.5,0.1 + c-0.2-0.9-0.4-1.7-1.4-2c-0.5-0.1-1.1-0.1-2-0.1h-1.3c-0.6,0-0.6,0-0.6,0.8V48.7z"/> + <path class="st0" d="M304.1,45.6c0-1.5-0.1-1.9-1-2l-0.7-0.1c-0.2-0.1-0.1-0.4,0-0.5c1.1-0.1,2.5-0.2,4.5-0.2 + c1.3,0,2.5,0.1,3.5,0.6c0.9,0.4,1.6,1.3,1.6,2.6c0,1.5-0.9,2.3-2.1,2.8c0,0.2,0.2,0.3,0.4,0.3c1.1,0.2,2.8,1.2,2.8,3.5 + c0,2.4-1.8,4-5.5,4c-0.6,0-1.6-0.1-2.5-0.1c-0.9,0-1.6,0-2.4,0.1c-0.1-0.1-0.2-0.4,0-0.5L303,56c1.1-0.2,1.1-0.4,1.1-2.6V45.6z + M305.8,48.3c0,0.6,0,0.6,1.1,0.6c2.1-0.1,3.3-0.7,3.3-2.7c0-2-1.5-2.8-3.1-2.8c-0.5,0-0.8,0-1,0.1c-0.2,0.1-0.3,0.2-0.3,0.5V48.3 + z M305.8,53.1c0,0.7,0,1.8,0.4,2.3c0.4,0.5,1,0.6,1.6,0.6c1.8,0,3.3-0.8,3.3-2.9c0-1.6-0.8-3.5-4.1-3.5c-1.1,0-1.2,0.1-1.2,0.5 + V53.1z"/> + <path class="st0" d="M319.8,46c0-2.2,0-2.5-1.3-2.6l-0.3,0c-0.1-0.1-0.1-0.5,0-0.5c0.9,0,1.6,0.1,2.4,0.1h3.9c1.3,0,2.5,0,2.8-0.1 + c0.1,0.4,0.2,1.8,0.3,2.8c-0.1,0.1-0.4,0.2-0.5,0c-0.3-1-0.5-1.7-1.6-2c-0.4-0.1-1.1-0.1-2-0.1h-1.5c-0.6,0-0.6,0-0.6,0.8v4.1 + c0,0.6,0.1,0.6,0.7,0.6h1.2c0.9,0,1.5,0,1.8-0.1c0.2-0.1,0.4-0.2,0.5-0.7l0.2-0.9c0.1-0.1,0.5-0.1,0.5,0c0,0.5-0.1,1.3-0.1,2.1 + c0,0.7,0.1,1.5,0.1,2c-0.1,0.1-0.4,0.1-0.5,0l-0.2-0.8c-0.1-0.4-0.2-0.7-0.6-0.8c-0.3-0.1-0.8-0.1-1.6-0.1h-1.2 + c-0.6,0-0.7,0-0.7,0.6v2.9c0,1.1,0.1,1.8,0.4,2.2c0.2,0.2,0.7,0.5,2.5,0.5c1.6,0,2.2-0.1,2.7-0.3c0.4-0.2,0.9-0.9,1.5-2 + c0.1-0.1,0.4,0,0.5,0.1c-0.1,0.7-0.7,2.3-0.9,2.9c-1.9,0-3.7-0.1-5.6-0.1h-1.9c-0.9,0-1.6,0-2.8,0.1c-0.1-0.1-0.2-0.4,0-0.5 + l0.7-0.1c1.2-0.1,1.3-0.4,1.3-2.6V46z"/> + <path class="st0" d="M335,46c0-2-0.1-2.3-0.9-2.4l-0.7-0.1c-0.1-0.1-0.1-0.4,0-0.5c1.2-0.1,2.6-0.2,4.6-0.2c1.3,0,2.5,0.1,3.5,0.6 + c1,0.5,1.7,1.5,1.7,2.9c0,2-1.6,3-2.6,3.5c-0.1,0.1,0,0.3,0.1,0.5c1.7,2.7,2.8,4.3,4.2,5.5c0.4,0.3,0.9,0.5,1.4,0.6 + c0.1,0,0.1,0.2,0,0.3c-0.2,0.1-0.5,0.1-0.9,0.1c-1.8,0-2.8-0.5-4.3-2.6c-0.5-0.8-1.4-2.2-2-3.1c-0.3-0.5-0.6-0.7-1.5-0.7 + c-0.9,0-1,0-1,0.5v2.6c0,2.2,0,2.4,1.2,2.6l0.4,0.1c0.1,0.1,0.1,0.5,0,0.5c-0.9,0-1.6-0.1-2.5-0.1c-0.9,0-1.6,0-2.6,0.1 + c-0.1-0.1-0.2-0.4,0-0.5l0.5-0.1c1.2-0.1,1.2-0.4,1.2-2.6V46z M336.7,49c0,0.4,0,0.6,0.1,0.7c0.1,0.1,0.4,0.1,1.4,0.1 + c0.7,0,1.5-0.1,2.1-0.5c0.6-0.4,1-1.2,1-2.6c0-1.6-1-3.2-3.3-3.2c-1.3,0-1.3,0.1-1.3,0.7V49z"/> + <path class="st0" d="M361.5,54.4c0,0.8,0.1,1.3,0.5,1.5c0.1,0.1,0.1,0.2,0,0.2c-0.2,0-0.6,0.1-1,0.2c-1.1,0.3-2.6,0.5-3.7,0.5 + c-2.5,0-4.7-0.7-6.3-2.3c-1.2-1.2-1.9-2.9-1.9-4.7c0-1.8,0.6-3.5,1.9-4.9c1.4-1.5,3.4-2.4,6.6-2.4c1.2,0,2.3,0.2,2.6,0.3 + c0.4,0.1,1,0.2,1.3,0.2c0,0.7,0.1,1.8,0.3,3c-0.1,0.2-0.4,0.2-0.6,0.1c-0.6-2.2-2.1-2.9-4.2-2.9c-4,0-5.8,2.9-5.8,6 + c0,4,2.1,7.1,6.2,7.1c1.3,0,2.1-0.3,2.3-0.6c0.1-0.1,0.2-0.5,0.2-1.2v-0.8c0-1.7-0.1-1.9-1.3-2l-0.9-0.1c-0.2-0.1-0.1-0.5,0-0.5 + c0.6,0,1.7,0.1,3,0.1c0.8,0,1.5,0,2.2-0.1c0.1,0.1,0.2,0.4,0,0.5l-0.3,0c-0.9,0.1-0.9,0.7-0.9,1.7V54.4z"/> + <path class="st0" d="M369.3,46c0-2.2,0-2.5-1.3-2.6l-0.3,0c-0.1-0.1-0.1-0.5,0-0.5c0.9,0,1.6,0.1,2.4,0.1h3.9c1.3,0,2.6,0,2.8-0.1 + c0.1,0.4,0.2,1.8,0.3,2.8c-0.1,0.1-0.4,0.2-0.5,0c-0.3-1-0.5-1.7-1.6-2c-0.4-0.1-1.1-0.1-2-0.1h-1.5c-0.6,0-0.6,0-0.6,0.8v4.1 + c0,0.6,0.1,0.6,0.7,0.6h1.2c0.9,0,1.5,0,1.8-0.1c0.2-0.1,0.4-0.2,0.5-0.7l0.2-0.9c0.1-0.1,0.5-0.1,0.5,0c0,0.5-0.1,1.3-0.1,2.1 + c0,0.7,0.1,1.5,0.1,2c-0.1,0.1-0.4,0.1-0.5,0l-0.2-0.8c-0.1-0.4-0.2-0.7-0.6-0.8c-0.3-0.1-0.8-0.1-1.6-0.1h-1.2 + c-0.6,0-0.7,0-0.7,0.6v2.9c0,1.1,0.1,1.8,0.4,2.2c0.2,0.2,0.7,0.5,2.5,0.5c1.6,0,2.2-0.1,2.7-0.3c0.4-0.2,0.9-0.9,1.5-2 + c0.1-0.1,0.4,0,0.5,0.1c-0.1,0.7-0.7,2.3-0.9,2.9c-1.9,0-3.7-0.1-5.6-0.1h-1.9c-0.9,0-1.6,0-2.8,0.1c-0.1-0.1-0.2-0.4,0-0.5 + L368,56c1.2-0.1,1.3-0.4,1.3-2.6V46z"/> + <path class="st0" d="M395.7,53c0,0.6,0,3.1,0.1,3.6c0,0.1-0.2,0.2-0.4,0.2c-0.2-0.4-0.8-1.1-2.7-3.1l-4.8-5.5 + c-0.6-0.6-2-2.3-2.4-2.8h0c-0.1,0.2-0.1,0.7-0.1,1.3v4.5c0,1,0,3.7,0.4,4.3c0.1,0.2,0.5,0.4,1.1,0.4l0.6,0.1 + c0.1,0.2,0.1,0.4,0,0.5c-0.9,0-1.7-0.1-2.4-0.1c-0.9,0-1.4,0-2.2,0.1c-0.1-0.1-0.2-0.4,0-0.5l0.6-0.1c0.5-0.1,0.8-0.2,0.9-0.4 + c0.3-0.7,0.3-3.3,0.3-4.3v-6c0-0.6,0-1-0.5-1.5c-0.3-0.3-0.8-0.4-1.3-0.5l-0.4,0c-0.1-0.1-0.1-0.4,0-0.5c0.9,0.1,2,0.1,2.3,0.1 + c0.3,0,0.7,0,1-0.1c0.4,1.1,2.9,3.8,3.5,4.6l2,2.3c1.4,1.6,2.4,2.8,3.4,3.8h0c0.1-0.1,0.1-0.4,0.1-0.9v-4.4c0-1,0-3.7-0.4-4.3 + c-0.1-0.2-0.5-0.3-1.3-0.4l-0.4,0c-0.1-0.1-0.1-0.5,0-0.5c1,0,1.7,0.1,2.4,0.1c0.9,0,1.4,0,2.1-0.1c0.2,0.1,0.2,0.4,0,0.5l-0.3,0 + c-0.7,0.1-1.1,0.3-1.2,0.4c-0.4,0.7-0.3,3.3-0.3,4.3V53z"/> + </g> +</g> +</svg> diff --git a/frontend/src/routes/components/logos/uib/UiBlogo_hvit_v.svg b/frontend/src/routes/components/logos/uib/UiBlogo_hvit_v.svg new file mode 100755 index 0000000000000000000000000000000000000000..1ed300b324915d85fd4cf33eb6385b918c3efa37 --- /dev/null +++ b/frontend/src/routes/components/logos/uib/UiBlogo_hvit_v.svg @@ -0,0 +1,474 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="UiBlogo_grayscale" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" + y="0px" viewBox="0 0 439.4 99.2" style="enable-background:new 0 0 439.4 99.2;" xml:space="preserve"> +<style type="text/css"> + .st0{fill:#FFFFFF;} + .st1{fill:none;} +</style> +<g> + <path class="st0" d="M20.5,42.1c-0.6-0.1-1.8-0.3-2.2-0.2c-0.1,0-0.2,0.2-0.3,0.5L18,42.6c-0.1,0.1-0.2,0-0.2-0.1 + c0.1-0.4,0.2-0.8,0.2-1.2c0.1-0.4,0.1-0.7,0.2-1.1c0.1-0.1,0.2,0,0.3,0l0,0.3c0,0.3,0,0.5,0.2,0.6c0.3,0.2,1.5,0.4,2.1,0.5l1.2,0.2 + c0.9,0.2,1.8,0.5,2.3,1.2c0.4,0.5,0.5,1.3,0.4,2.1c-0.1,0.7-0.4,1.4-0.9,1.8c-0.5,0.5-1.3,0.6-2.6,0.4l-2.4-0.4 + c-1.1-0.2-1.3-0.2-1.4,0.4l-0.1,0.3c-0.1,0.1-0.2,0-0.2-0.1c0.1-0.5,0.2-0.9,0.3-1.3c0.1-0.4,0.1-0.8,0.2-1.3c0-0.1,0.2,0,0.3,0 + l0,0.3c-0.1,0.6,0.1,0.7,1.2,0.8l2.2,0.4c1.7,0.3,2.8,0,3.1-1.6c0.3-1.5-0.8-2.3-2.4-2.5L20.5,42.1z"/> + <path class="st0" d="M27.1,33.7c0.3,0.2,1.4,0.8,1.6,0.9c0,0,0.1,0.1,0,0.2c-0.2,0-0.7,0.1-2,0.4L23,36c-0.4,0.1-1.5,0.3-1.8,0.4 + l0,0c0.1,0.1,0.3,0.2,0.6,0.4l2,1.1c0.4,0.2,1.6,0.9,2,0.9c0.1,0,0.3-0.2,0.4-0.4l0.2-0.3c0.1,0,0.2,0.1,0.2,0.1 + c-0.2,0.4-0.4,0.7-0.6,1.1c-0.2,0.4-0.3,0.6-0.5,1c-0.1,0-0.2,0-0.2-0.1l0.1-0.3c0.1-0.2,0.1-0.4,0-0.5c-0.3-0.3-1.4-0.9-1.8-1.2 + l-2.6-1.5c-0.3-0.1-0.5-0.2-0.8-0.2c-0.2,0.1-0.4,0.2-0.5,0.4l-0.1,0.1c-0.1,0-0.2-0.1-0.2-0.1c0.2-0.4,0.5-0.9,0.6-1 + c0.1-0.1,0.2-0.3,0.2-0.4c0.6,0.1,2.4-0.3,2.9-0.4l1.5-0.3c1.1-0.2,1.8-0.4,2.5-0.6l0,0c0-0.1-0.2-0.1-0.4-0.2l-2-1.1 + c-0.4-0.2-1.6-0.9-2-0.9c-0.1,0-0.2,0.1-0.5,0.5l-0.1,0.1c-0.1,0-0.2-0.1-0.2-0.1c0.3-0.4,0.4-0.7,0.6-1.1c0.2-0.4,0.3-0.6,0.5-1 + c0.1,0,0.2,0,0.2,0.1l-0.1,0.1C23,31,23,31.2,23.1,31.3c0.2,0.3,1.4,1,1.8,1.2L27.1,33.7z"/> + <path class="st0" d="M27,28.4c-0.8-0.8-0.9-0.9-1.4-0.5l-0.2,0.2c-0.1,0-0.2-0.1-0.2-0.2c0.4-0.4,0.6-0.6,0.9-0.9 + c0.3-0.3,0.5-0.6,0.9-1c0.1,0,0.2,0.1,0.2,0.2l-0.2,0.2c-0.4,0.5-0.3,0.6,0.5,1.4l2.7,2.6c0.8,0.8,0.9,0.9,1.4,0.5l0.2-0.2 + c0.1,0,0.2,0.1,0.2,0.2c-0.4,0.4-0.6,0.6-0.9,0.9c-0.3,0.3-0.5,0.6-0.9,1c-0.1,0-0.2-0.1-0.2-0.2l0.2-0.2c0.4-0.5,0.3-0.6-0.5-1.4 + L27,28.4z"/> + <path class="st0" d="M30.7,24.3c-0.5-0.4-0.8-0.5-1.2-0.3l-0.2,0.1c-0.1,0-0.2-0.1-0.1-0.2c0.3-0.1,0.6-0.3,0.9-0.6 + c0.4-0.2,0.7-0.5,1.1-0.7c0.1,0,0.2,0.1,0.2,0.2l-0.1,0.1C31,23.2,31,23.3,31,23.4c0.1,0.1,0.5,0.5,1.2,1c1.1,0.8,2.1,1.5,3.2,2.3 + c-0.1-0.8-0.3-1.9-0.4-2.5c-0.1-0.8-0.3-2-0.4-2.5c0-0.2-0.1-0.3-0.1-0.4c0-0.1-0.2-0.1-0.5,0.1l-0.2,0.1c-0.1,0-0.2-0.2-0.1-0.2 + c0.3-0.1,0.6-0.3,0.9-0.6c0.3-0.2,0.6-0.4,0.8-0.6c0.1,0,0.2,0.1,0.2,0.2l-0.3,0.2c-0.2,0.2-0.3,0.3-0.3,0.6c0,0.6,0.1,1.5,0.3,2.7 + l0.2,1.4c0.2,1,0.4,2.3,0.5,2.9c0,0,0,0.1-0.1,0.1c0,0-0.1,0-0.2,0.1c-0.3-0.3-0.8-0.6-1.2-0.9L30.7,24.3z"/> + <path class="st0" d="M39.5,20.2c-0.3-1-0.4-1.2-1-1.1l-0.2,0c-0.1,0-0.1-0.2-0.1-0.3c0.4-0.1,0.8-0.2,1.2-0.3l1.9-0.5 + c0.6-0.2,1.2-0.3,1.4-0.4c0.1,0.2,0.4,0.9,0.5,1.3c0,0.1-0.2,0.1-0.2,0.1c-0.3-0.4-0.5-0.8-1-0.7c-0.2,0-0.6,0.1-1,0.2l-0.7,0.2 + c-0.3,0.1-0.3,0.1-0.2,0.5l0.6,2c0.1,0.3,0.1,0.3,0.4,0.2l0.6-0.2c0.4-0.1,0.7-0.2,0.8-0.3c0.1-0.1,0.2-0.2,0.1-0.4l0-0.4 + c0-0.1,0.2-0.1,0.3-0.1c0.1,0.2,0.1,0.6,0.2,1c0.1,0.4,0.3,0.7,0.3,1c0,0.1-0.2,0.1-0.3,0.1L43,21.7c-0.1-0.2-0.2-0.3-0.4-0.3 + c-0.2,0-0.4,0.1-0.8,0.2l-0.6,0.2c-0.3,0.1-0.3,0.1-0.3,0.4l0.4,1.4c0.2,0.5,0.3,0.9,0.5,1c0.2,0.1,0.4,0.1,1.3-0.1 + c0.8-0.2,1.1-0.3,1.2-0.5c0.2-0.2,0.3-0.6,0.4-1.2c0.1-0.1,0.2-0.1,0.3,0c0,0.4,0,1.2-0.1,1.5c-0.9,0.2-1.8,0.5-2.7,0.7l-0.9,0.3 + c-0.4,0.1-0.8,0.2-1.4,0.4c-0.1,0-0.1-0.2-0.1-0.2l0.3-0.1c0.6-0.2,0.6-0.4,0.3-1.4L39.5,20.2z"/> + <path class="st0" d="M47.8,18.6c0-1,0-1.2-0.5-1.2l-0.3,0c-0.1-0.1-0.1-0.2,0-0.3c0.6,0,1.3-0.1,2.3-0.1c0.6,0,1.3,0.1,1.7,0.3 + c0.5,0.3,0.9,0.7,0.9,1.5c0,1-0.8,1.5-1.3,1.7c-0.1,0.1,0,0.2,0.1,0.3c0.8,1.4,1.4,2.2,2.1,2.8c0.2,0.2,0.4,0.3,0.7,0.3 + c0.1,0,0.1,0.1,0,0.1c-0.1,0-0.3,0.1-0.5,0.1c-0.9,0-1.4-0.3-2.2-1.3c-0.3-0.4-0.7-1.1-1-1.6c-0.2-0.2-0.3-0.3-0.7-0.3 + c-0.5,0-0.5,0-0.5,0.2l0,1.3c0,1.1,0,1.2,0.6,1.3l0.2,0c0.1,0.1,0,0.2,0,0.3c-0.5,0-0.8,0-1.2,0c-0.4,0-0.8,0-1.3,0 + c-0.1,0-0.1-0.2,0-0.3l0.3,0c0.6-0.1,0.6-0.2,0.6-1.3L47.8,18.6z M48.6,20.1c0,0.2,0,0.3,0,0.3c0,0,0.2,0.1,0.7,0.1 + c0.4,0,0.8,0,1.1-0.3C50.7,20,51,19.7,51,19c0-0.8-0.5-1.6-1.7-1.6c-0.7,0-0.7,0-0.7,0.3L48.6,20.1z"/> + <path class="st0" d="M57.1,25.2c-0.8-0.3-1.3-0.7-1.4-0.9c-0.1-0.3,0-1,0.2-1.5c0.1-0.1,0.2,0,0.2,0c0,0.6,0.1,1.7,1.2,2 + c0.8,0.3,1.4-0.2,1.6-0.8c0.1-0.4,0.2-1-0.4-1.7l-0.8-0.9c-0.4-0.5-0.8-1.2-0.5-2.1c0.3-1,1.3-1.5,2.6-1.1c0.3,0.1,0.7,0.3,0.9,0.4 + c0.1,0.1,0.3,0.1,0.3,0.2c0,0.3-0.1,0.9-0.2,1.3c-0.1,0-0.2,0-0.3,0c0-0.5,0-1.3-1-1.6c-1-0.3-1.4,0.3-1.5,0.7 + c-0.2,0.6,0.2,1.2,0.5,1.5l0.6,0.8c0.5,0.6,0.9,1.4,0.6,2.3C59.5,25.2,58.4,25.7,57.1,25.2z"/> + <path class="st0" d="M65.4,23c0.6-0.9,0.7-1.1,0.2-1.5l-0.2-0.2c0-0.1,0.1-0.2,0.2-0.2c0.4,0.3,0.7,0.5,1.1,0.7 + c0.4,0.2,0.7,0.4,1.1,0.7c0,0.1,0,0.2-0.1,0.2l-0.2-0.1c-0.6-0.3-0.7-0.1-1.2,0.8l-2,3.2c-0.6,0.9-0.6,1.1-0.1,1.5l0.2,0.2 + c0,0.1-0.1,0.2-0.2,0.2c-0.4-0.3-0.7-0.5-1.1-0.7c-0.4-0.2-0.7-0.4-1.1-0.7c0-0.1,0-0.2,0.1-0.2l0.2,0.1c0.6,0.3,0.7,0.1,1.2-0.8 + L65.4,23z"/> + <path class="st0" d="M69.9,31.4c-0.8,0.7-0.9,0.9-0.5,1.4l0.2,0.3c0,0.1-0.1,0.2-0.2,0.2c-0.4-0.5-0.6-0.7-0.9-1 + c-0.3-0.3-0.5-0.6-1-1c0-0.1,0.1-0.2,0.2-0.2l0.3,0.3c0.4,0.4,0.6,0.3,1.4-0.4l3.4-3.2c0.2-0.2,0.2-0.2,0-0.5l-0.4-0.4 + c-0.3-0.3-0.7-0.7-1.1-0.8c-0.3,0-0.6,0.1-0.9,0.1c-0.1,0-0.2-0.2-0.1-0.2c0.5-0.2,1.1-0.5,1.4-0.8c0,0,0.1,0.1,0.1,0.1 + c-0.2,0.3,0,0.5,0.4,0.9l2.9,3.1c0.4,0.4,0.5,0.5,0.8,0.4c0,0,0.1,0.1,0.1,0.2c-0.4,0.2-1.1,0.7-1.3,1c-0.1,0-0.2-0.1-0.2-0.2 + c0.2-0.2,0.4-0.5,0.4-0.7c0-0.3-0.2-0.6-0.6-1.1l-0.5-0.5c-0.2-0.2-0.2-0.2-0.5,0L69.9,31.4z"/> + <path class="st0" d="M75.4,38.5c0.2-0.2,0.2-0.2,0.1-0.5l-0.7-1.4c-0.1-0.2-0.2-0.3-0.4-0.2l-1.2,0.1c-0.5,0.1-0.8,0.1-0.9,0.2 + c-0.1,0.1-0.1,0.1-0.1,0.4l0.1,0.3c0,0.1-0.2,0.2-0.2,0.1c-0.1-0.3-0.2-0.6-0.4-1c-0.1-0.3-0.3-0.6-0.5-0.9c0-0.1,0.2-0.2,0.2-0.1 + l0.2,0.3c0.1,0.2,0.3,0.4,0.7,0.3c0.5,0,1.3-0.1,2.5-0.2l3-0.2c0.4,0,0.6-0.1,0.7-0.2c0.2,0.2,0.4,0.3,0.6,0.3c0,0.1,0,0.1,0,0.2 + c-0.4,0.3-0.7,0.7-1.1,1L75,40.1c-0.7,0.7-0.8,0.9-0.6,1.3l0.1,0.3c0,0.1-0.2,0.1-0.2,0.1c-0.2-0.4-0.3-0.7-0.5-1.2 + c-0.2-0.5-0.4-0.8-0.5-1.1c0-0.1,0.1-0.2,0.2-0.1l0.2,0.3c0.1,0.2,0.2,0.3,0.3,0.3c0.1-0.1,0.3-0.2,0.4-0.4L75.4,38.5z M75.4,36.2 + c-0.3,0-0.3,0-0.1,0.3l0.6,1.2c0.1,0.3,0.2,0.3,0.4,0.1l1.3-1.2c0.2-0.2,0.4-0.4,0.5-0.5l0,0c-0.1,0-0.3,0-0.7,0L75.4,36.2z"/> + <path class="st0" d="M74.8,45.6c-0.1-0.9,0.1-1.5,0.1-1.7c0.2-0.2,0.9-0.4,1.4-0.5c0.1,0,0.1,0.2,0.1,0.2c-0.5,0.2-1.5,0.8-1.3,2 + c0.1,0.9,0.8,1.2,1.4,1.1c0.5-0.1,1-0.2,1.3-1.1l0.5-1.1c0.3-0.6,0.8-1.3,1.6-1.4c1-0.1,1.9,0.5,2.1,1.9c0,0.3,0,0.7,0,1 + c0,0.1,0,0.3,0,0.4c-0.2,0.1-0.8,0.3-1.2,0.4c-0.1,0-0.1-0.2-0.1-0.3c0.5-0.2,1.1-0.6,1-1.6c-0.2-1-0.9-1.1-1.3-1.1 + c-0.6,0.1-1,0.7-1.1,1.1L78.8,46c-0.3,0.7-0.8,1.4-1.8,1.6C75.9,47.7,75,47,74.8,45.6z"/> + <path class="st0" d="M23.6,57.3c0.7-0.3,0.9-0.4,0.8-0.8l-0.1-0.3c0-0.1,0.2-0.1,0.2-0.1c0.2,0.5,0.5,1.2,0.9,2.1 + c0.2,0.6,0.4,1.2,0.3,1.8c0,0.5-0.3,1-1,1.2c-0.7,0.3-1.2,0-1.7-0.5c-0.1,0-0.1,0.1-0.1,0.2c0.1,0.6-0.1,1.5-1.2,1.9 + c-1.1,0.4-2.2-0.1-2.9-1.9c-0.1-0.3-0.3-0.8-0.4-1.2c-0.2-0.4-0.3-0.8-0.4-1.1c0-0.1,0.2-0.1,0.2-0.1l0.1,0.2 + c0.3,0.5,0.4,0.5,1.4,0.1L23.6,57.3z M20.3,59.4c-0.4,0.1-0.8,0.3-1,0.6c-0.2,0.3-0.1,0.6,0,0.9c0.3,0.9,1,1.4,1.9,1 + c0.8-0.3,1.5-1,1-2.6c-0.2-0.5-0.3-0.6-0.5-0.5L20.3,59.4z M22.6,58.6c-0.3,0.1-0.3,0.1-0.1,0.6c0.4,1,0.9,1.4,1.8,1.1 + c1-0.4,1.1-1.2,0.8-2c-0.1-0.2-0.2-0.4-0.2-0.4c-0.1-0.1-0.1-0.1-0.3,0L22.6,58.6z"/> + <path class="st0" d="M26.8,64.6c0.9-0.7,1-0.8,0.7-1.3l-0.1-0.1c0-0.1,0.2-0.2,0.2-0.1c0.3,0.4,0.5,0.7,0.7,1l1.2,1.6 + c0.4,0.5,0.8,1,0.9,1.1c-0.1,0.2-0.7,0.7-1,1c-0.1,0-0.2-0.1-0.2-0.2c0.3-0.4,0.5-0.7,0.3-1.2c-0.1-0.2-0.3-0.5-0.6-0.9l-0.5-0.6 + c-0.2-0.3-0.2-0.2-0.5,0L26.3,66c-0.2,0.2-0.2,0.2,0,0.5l0.4,0.5c0.3,0.4,0.5,0.6,0.6,0.7c0.1,0.1,0.2,0.1,0.4,0l0.4-0.2 + c0.1,0,0.2,0.1,0.2,0.2c-0.2,0.2-0.6,0.4-0.9,0.6c-0.3,0.2-0.6,0.5-0.8,0.6c-0.1,0-0.2-0.1-0.2-0.2l0.3-0.3 + c0.1-0.1,0.2-0.3,0.1-0.5c-0.1-0.1-0.2-0.3-0.4-0.7L26,66.7c-0.2-0.2-0.2-0.3-0.4-0.1l-1.2,0.9c-0.4,0.3-0.7,0.6-0.8,0.8 + c0,0.2,0,0.4,0.6,1.2c0.5,0.6,0.7,0.9,0.9,1c0.2,0.1,0.7,0.1,1.3,0c0.1,0,0.1,0.2,0.1,0.3c-0.3,0.2-1.1,0.4-1.4,0.5 + c-0.6-0.8-1.1-1.5-1.7-2.3l-0.6-0.8c-0.3-0.4-0.5-0.6-0.9-1.1c0-0.1,0.1-0.2,0.2-0.2l0.2,0.3c0.4,0.4,0.6,0.4,1.4-0.3L26.8,64.6z" + /> + <path class="st0" d="M31.9,70.4c0.6-0.8,0.7-1,0.4-1.3L32,68.9c0-0.1,0.1-0.2,0.2-0.2c0.5,0.3,1.1,0.7,1.9,1.3 + c0.5,0.4,1,0.8,1.2,1.3c0.3,0.5,0.3,1.1-0.2,1.7c-0.6,0.8-1.5,0.8-2.1,0.6c-0.1,0-0.1,0.1-0.1,0.2c-0.1,1.6-0.2,2.6,0.1,3.5 + c0.1,0.2,0.2,0.5,0.4,0.7c0,0,0,0.1-0.1,0.1c-0.1,0-0.2-0.1-0.4-0.2c-0.7-0.5-1-1.1-1-2.3c0-0.5,0.1-1.3,0.1-1.9 + c0-0.3-0.1-0.5-0.4-0.7c-0.4-0.3-0.4-0.3-0.5-0.1l-0.8,1.1c-0.7,0.9-0.7,1-0.3,1.4l0.2,0.2c0,0.1-0.1,0.2-0.2,0.2 + c-0.4-0.3-0.6-0.5-1-0.8c-0.4-0.3-0.7-0.5-1.1-0.7c0-0.1,0-0.2,0.1-0.2l0.2,0.1c0.5,0.3,0.6,0.2,1.3-0.7L31.9,70.4z M31.7,72.1 + c-0.1,0.2-0.2,0.2-0.2,0.3c0,0,0.1,0.2,0.6,0.5c0.3,0.2,0.7,0.4,1,0.4c0.4,0,0.8-0.2,1.2-0.7c0.5-0.7,0.5-1.6-0.4-2.3 + c-0.5-0.4-0.6-0.4-0.7-0.1L31.7,72.1z"/> + <path class="st0" d="M42.5,80.4c-0.1,0.4-0.1,0.7,0,0.8c0,0,0,0.1,0,0.1c-0.1,0-0.3-0.1-0.5-0.1c-0.6,0-1.3-0.1-1.9-0.3 + c-1.2-0.4-2.2-1.1-2.7-2.1C37,78,37,77.2,37.2,76.3c0.3-0.8,0.8-1.6,1.7-2.1c0.9-0.5,2-0.6,3.5-0.1c0.6,0.2,1.1,0.5,1.2,0.6 + c0.2,0.1,0.5,0.3,0.6,0.3c-0.1,0.3-0.2,0.9-0.3,1.5c-0.1,0.1-0.2,0-0.3-0.1c0.1-1.2-0.6-1.8-1.6-2.1c-1.9-0.6-3.2,0.5-3.7,2 + c-0.6,1.9-0.1,3.7,1.9,4.4c0.6,0.2,1,0.2,1.2,0.1c0.1-0.1,0.2-0.2,0.3-0.5l0.1-0.4c0.3-0.8,0.3-0.9-0.3-1.2l-0.4-0.2 + c-0.1-0.1,0-0.2,0.1-0.2c0.3,0.1,0.8,0.3,1.4,0.5c0.4,0.1,0.7,0.2,1.1,0.3c0.1,0.1,0,0.2-0.1,0.3l-0.2,0c-0.4-0.1-0.5,0.2-0.7,0.7 + L42.5,80.4z"/> + <path class="st0" d="M47.8,76.8c0-1.1,0-1.2-0.6-1.3l-0.2,0c-0.1,0,0-0.2,0-0.3c0.5,0,0.8,0,1.2,0l2,0c0.7,0,1.3,0,1.4,0 + c0.1,0.2,0.1,0.9,0.2,1.4c0,0.1-0.2,0.1-0.3,0c-0.2-0.5-0.2-0.9-0.8-1c-0.2-0.1-0.6-0.1-1-0.1l-0.8,0c-0.3,0-0.3,0-0.3,0.4l0,2.1 + c0,0.3,0,0.3,0.3,0.3l0.6,0c0.4,0,0.8,0,0.9-0.1c0.1,0,0.2-0.1,0.3-0.4l0.1-0.4c0.1-0.1,0.2-0.1,0.3,0c0,0.3,0,0.7,0,1.1 + c0,0.4,0,0.8,0,1c0,0.1-0.2,0.1-0.3,0l-0.1-0.4c0-0.2-0.1-0.3-0.3-0.4c-0.1,0-0.4-0.1-0.8-0.1l-0.6,0c-0.3,0-0.3,0-0.3,0.3l0,1.5 + c0,0.6,0,0.9,0.2,1.1c0.1,0.1,0.3,0.2,1.3,0.2c0.8,0,1.1,0,1.3-0.2c0.2-0.1,0.5-0.5,0.7-1c0.1-0.1,0.2,0,0.3,0.1 + c-0.1,0.4-0.3,1.2-0.5,1.5c-0.9,0-1.9,0-2.8,0l-0.9,0c-0.5,0-0.8,0-1.4,0c-0.1,0-0.1-0.2,0-0.3l0.3,0c0.6-0.1,0.7-0.2,0.7-1.3 + L47.8,76.8z"/> + <path class="st0" d="M62.2,75.1c-0.2-0.5-0.6-1.7-0.6-2.1c0-0.1,0.2-0.2,0.5-0.4l0.1-0.1c0-0.1,0-0.2-0.1-0.2 + c-0.3,0.1-0.6,0.2-1,0.4c-0.4,0.1-0.7,0.3-1.2,0.4c-0.1,0.1,0,0.2,0.1,0.3l0.2,0c0.4-0.1,0.6-0.1,0.7,0c0.3,0.2,0.8,1.5,1,2 + l0.8,2.1c0.1,0.2,0.1,0.4,0.1,0.4l0,0c-0.6-0.3-1.3-0.7-2.3-1.2L59,75.9c-0.5-0.2-2.1-1.1-2.5-1.5c-0.1,0.1-0.3,0.1-0.4,0.2 + c-0.2,0.1-0.7,0.3-1.1,0.4c-0.1,0.1,0,0.2,0.1,0.3l0.2,0c0.2-0.1,0.5-0.1,0.7,0c0.3,0.1,0.4,0.4,0.5,0.6l1.1,2.8 + c0.2,0.5,0.6,1.7,0.6,2.1c0,0.1-0.1,0.2-0.4,0.4l-0.3,0.1c0,0.1,0,0.2,0.1,0.2c0.3-0.2,0.6-0.3,1-0.4c0.4-0.1,0.7-0.3,1.2-0.4 + c0.1-0.1,0-0.2-0.1-0.3l-0.3,0.1c-0.3,0.1-0.5,0.1-0.6,0c-0.3-0.2-0.8-1.5-0.9-2l-0.8-2.1c-0.1-0.3-0.2-0.5-0.2-0.7l0,0 + c0.3,0.1,1.3,0.7,1.6,0.9l3.2,1.7c1.2,0.7,1.6,0.9,1.8,1c0.1,0,0.1-0.1,0.1-0.2c-0.1-0.2-0.6-1.4-0.7-1.7L62.2,75.1z"/> + <path class="st0" d="M70.4,74.9c-0.7,0.6-1.3,0.7-1.5,0.8c-0.2-0.1-0.8-0.6-1.2-0.9c0-0.1,0.1-0.2,0.2-0.2c0.5,0.3,1.5,0.8,2.4,0 + c0.7-0.6,0.6-1.3,0.2-1.8c-0.3-0.4-0.7-0.7-1.6-0.6l-1.2,0.1c-0.6,0.1-1.5,0-2-0.7c-0.6-0.8-0.6-1.9,0.5-2.8 + c0.2-0.2,0.6-0.4,0.8-0.5c0.1-0.1,0.3-0.1,0.3-0.2c0.2,0.1,0.7,0.5,1,0.9c0,0.1-0.1,0.2-0.2,0.2c-0.4-0.3-1.1-0.6-1.9,0 + c-0.8,0.7-0.5,1.3-0.2,1.7c0.4,0.5,1.1,0.5,1.5,0.4l1-0.1c0.8-0.1,1.7-0.1,2.3,0.7C71.6,72.8,71.5,74,70.4,74.9z"/> + <path class="st0" d="M71.6,65.7c-0.9-0.6-1.1-0.7-1.5-0.3l-0.2,0.2c-0.1,0-0.2-0.1-0.2-0.2c0.3-0.4,0.5-0.7,0.8-1.1 + c0.2-0.3,0.4-0.6,0.7-1.1c0.1,0,0.2,0.1,0.2,0.1l-0.1,0.2c-0.3,0.5-0.2,0.7,0.7,1.3l3,2.2c0.9,0.6,1,0.7,1.5,0.2l0.2-0.2 + c0.1,0,0.2,0.1,0.2,0.2c-0.3,0.4-0.5,0.7-0.8,1c-0.3,0.4-0.5,0.7-0.7,1.1c-0.1,0-0.2,0-0.2-0.1l0.1-0.2c0.3-0.5,0.2-0.6-0.7-1.3 + L71.6,65.7z"/> + <path class="st0" d="M80.2,61.3c-0.3,0.8-0.8,1.2-0.9,1.4c-0.3,0-1-0.1-1.5-0.2c0-0.1,0-0.2,0.1-0.2c0.6,0,1.7,0,2.1-1.1 + c0.3-0.8-0.1-1.4-0.7-1.7c-0.4-0.2-0.9-0.3-1.7,0.3l-1,0.7c-0.5,0.4-1.3,0.7-2.1,0.4c-0.9-0.3-1.4-1.4-0.9-2.6 + c0.1-0.3,0.3-0.6,0.5-0.9c0.1-0.1,0.2-0.2,0.2-0.3c0.3,0,0.9,0.1,1.3,0.3c0,0.1,0,0.2-0.1,0.3c-0.5-0.1-1.3,0-1.6,0.9 + c-0.4,1,0.2,1.4,0.7,1.6c0.6,0.2,1.2-0.1,1.5-0.4l0.8-0.6c0.6-0.5,1.4-0.9,2.3-0.5C80.2,58.9,80.7,60,80.2,61.3z"/> + <path class="st0" d="M49.6,14.2C30,14.2,14.2,30,14.2,49.6C14.2,69.2,30,85,49.6,85C69.2,85,85,69.2,85,49.6 + C85,30,69.2,14.2,49.6,14.2z M49.6,84c-19,0-34.4-15.4-34.4-34.4c0-19,15.4-34.4,34.4-34.4c19,0,34.4,15.4,34.4,34.4 + C84,68.6,68.6,84,49.6,84z"/> + <path class="st0" d="M58,66.8c-0.7,0.5-1.2,1.3-1.5,2c0.7,0.5,2.2,1.2,4.7,1.6c1.1-0.6,2-1.2,3-2c-0.9-0.2-1.8-0.7-2.4-1 + C60.7,66.7,59.3,65.7,58,66.8z"/> + <path class="st0" d="M41.4,62.1c-0.9-0.2-1.3-0.2-2.6,0.2c-2.2,0.7-5.7,4.6-5.7,4.6c1,1,2.2,1.9,3.4,2.7c1-1.2,3.5-4.1,5.9-4.1 + c1.3,0,2,0.5,3,1.2c0.1-0.1,0.2-0.3,0.3-0.4C43.8,65.2,41.4,62.1,41.4,62.1z"/> + <path class="st0" d="M48.9,65.5c-1.1,0.1-1.8,1-2.3,1.9c2,1.4,3.8,3,6.4,3.7c2,0.6,2.8,0.8,4.9,0.9c0.9-0.3,1.8-0.7,2.7-1.2 + c-1.3-0.2-3-0.8-4.4-1.4C53.8,68.2,51.1,65.2,48.9,65.5z"/> + <path class="st0" d="M42.8,66.7c-3,0-4.2,2.5-5.1,3.6c3.5,2,7.6,3.2,11.9,3.2c2.3,0,4.5-0.3,6.6-0.9c-1.3-0.1-3-0.4-4.4-1 + C48.5,70.2,45,66.7,42.8,66.7z"/> + <path class="st0" d="M64.1,64.6c-2-2.5-3.5-3-4.3-2.8c-0.8,0.2-0.6,0.8-1.5,1.8c-0.8,1-2.7,2.1-3.1,2.3c0.3,0.3,0.7,0.8,0.8,0.9 + c0.9-0.9,2.2-1.7,3.3-1.7c2.1,0,2.7,1.7,5.5,2.7c0.6-0.5,1.2-1,1.7-1.5C66.6,66.4,65.2,66.1,64.1,64.6z"/> + <path class="st0" d="M59.4,44.1c-0.1-0.1,0-0.3-0.1-0.4c-0.1-0.4-0.3-0.8-0.3-1.3c-0.1-0.3,0.2-0.4,0.4-0.5c0.1-0.3,0.1-0.6,0-0.8 + c-0.1-0.4-0.7-0.5-0.7-1c0-0.3-0.2-0.6-0.2-1c-0.2-0.5-0.1-1.1-0.2-1.6c-0.1-0.6-0.1-1.2-0.2-1.8c-0.1-0.7-0.2-1.4-0.4-2.1 + c-0.1-0.6-0.3-1.2-0.6-1.7c0-0.4-0.4-0.7-0.2-1.1c0.3-0.5,0.6-1,0.8-1.5c0.2-0.3,0.1-0.7,0.2-1.1c0-0.3,0.1-0.6,0-0.9 + c-0.1,0-0.1,0-0.1,0c-0.1,0.5-0.7,0.7-1.1,1c-0.6,0.2-1.2,0.1-1.9,0.2c-0.4,0-0.7,0.4-1.2,0.1c-0.2-0.2-0.4-0.2-0.7-0.3 + c-0.5,0-1,0-1.4,0c-0.7,0-1.2-0.4-1.9-0.3c-0.9,0-1.6,0.4-2.5,0.3c-0.8-0.2-1.6,0.1-2.2,0.4c-0.2,0-0.5-0.2-0.8-0.2 + c-0.7-0.3-1.6,0.2-2.1-0.3c-0.3-0.3-0.5-0.6-0.5-1c-0.1,0.1-0.2,0.2-0.2,0.3c-0.2,0.3-0.3,0.6-0.3,0.9c-0.1,0.4,0,0.9,0.1,1.3 + c0.1,0.7,0.6,1.3,0.5,2c-0.1,0.3-0.3,0.7-0.4,1c-0.3,0.3-0.2,0.8-0.3,1.3c-0.3,0.8-0.1,1.6,0,2.5c-0.3,1-0.4,2-0.5,3 + c-0.1,0.7,0,1.4-0.3,2c-0.4,0.4-0.7,0.7-0.6,1.3c0,0.3,0.2,0.5,0.3,0.7c0.1,0.5,0.1,1.1,0,1.6c0,0.4-0.4,0.6-0.5,0.9 + c-0.1,0.4,0.2,0.6,0.4,0.8c0.1,0.2,0.1,0.6,0.2,0.8c0.1,0.7,0.2,1.3,0.3,2c0.2,1,0.3,2,0.5,2.9c0.2,1.2,0.5,2.3,0.8,3.4 + c0.4,0.8,0.5,1.7,0.8,2.5c0.2,0.7,0.6,1.3,0.6,2c0,0.1,0,0.2,0.1,0.2c0,0.5-0.4,0.8-0.3,1.3c0,0,1.5,2.6,3.2,3.7 + c0.7-0.8,1.7-1.5,3-1.5c2.1,0,4,2.1,6,3.7c0.1-0.2,0.3-0.3,0.5-0.5c-0.7-0.9-3.6-4.3-6-4.7c0,0,0.2-0.5,0-0.7 + c-0.2-0.3-0.2-0.5-0.2-0.8c0-0.1-0.1-0.4,0-0.5c0.4,0.1,0.5,0.5,0.7,0.8c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1-0.1c0-0.4,0.5-0.6,0.7-0.8 + c0.1,0,0.1,0,0.2,0.1c0.1,0.4,0,0.9,0.3,1.2c0.1,0.1,0,0.2-0.1,0.3c0,0.3-0.2,0.2-0.2,0.2c1.8,0.9,2.8,1.9,3.8,3.1 + c0.7-0.5,3.2-2.1,3.1-3.7c0-0.5-0.3-0.5-0.4-0.8c-0.2-0.2-0.4-0.4-0.5-0.7c-0.3-0.5-0.5-1.1-0.4-1.8c0.2-0.5,0.2-1,0.4-1.5 + c0.3-0.9,0.5-1.8,0.7-2.7c0.3-1.2,0.7-2.5,0.8-3.8c0.2-0.4,0.2-0.9,0.3-1.4c0.2-0.4,0.1-1,0.2-1.5c0.1-0.4,0-0.8,0.2-1.1 + c0.1-0.2,0-0.4,0.1-0.6c0-0.3,0.3-0.2,0.3-0.5c0.2-0.1,0.3-0.4,0.4-0.5C60.1,44.7,59.7,44.4,59.4,44.1z M58.3,40.6 + c0.2,0.1,0.4,0.1,0.5,0.3c0.2,0.1,0.2,0.3,0.3,0.5c0,0.1,0,0.3-0.1,0.3c-0.4,0-0.7-0.2-0.9-0.4C58,41,58.2,40.8,58.3,40.6z + M56.2,45.5c0,0.6,0,1.2-0.1,1.8c-0.1,0.1,0,0.2,0,0.3c-0.1,0.6,0,1.3-0.1,1.9l-0.1,0c-0.2-0.3-0.7-0.4-0.7-0.8 + c0.3-1,0.2-2.2,0.3-3.3c0.1-0.9,0.1-1.9,0-2.8c0,0,0-0.1,0.1-0.1c0.3,0.1,0.4,0.4,0.7,0.5C56.2,43.9,56.1,44.6,56.2,45.5z + M42.5,37.6c-0.3,0-0.3-0.3-0.4-0.5c-0.1-0.1-0.1-0.3-0.1-0.4c0.1-0.1,0.1-0.2,0.1-0.3c-0.1-0.1-0.3,0-0.3-0.2 + c0-0.2-0.1-0.5,0.2-0.6c0.2-0.1,0.5,0,0.8-0.2c0,0,0-0.1-0.1-0.1c-0.3,0-0.5,0.1-0.7,0.2c-0.1,0-0.1-0.1-0.1-0.2 + c0-0.7-0.1-1.3,0.1-1.8c0-0.1-0.1-0.3,0-0.4c0.3-0.1,0.4,0.4,0.7,0.3v0c-0.2-0.2-0.4-0.4-0.6-0.4c-0.1-0.2,0-0.5,0-0.7 + c0.1-0.1,0.1-0.2,0.2-0.1c0.2,0.1,0.3,0.3,0.5,0.4c0.1,0,0.1-0.1,0.1-0.2c-0.2-0.3-0.8-0.3-0.5-0.8c0-0.2,0.1-0.4,0.3-0.4 + c0.2,0.1,0.3,0.3,0.5,0.4l0.1,0c-0.2-0.2-0.3-0.4-0.2-0.6c0.1-0.1,0.3,0.1,0.4,0.1l0.2,0.1c0.2,0.1,0.5,0.2,0.5,0.5 + c0.2,0.3,0.2,0.6,0.5,0.8c0.1,0.2,0.2,0.3,0.3,0.4c-0.1,0.1-0.2,0.1-0.2,0c-0.2-0.2-0.3-0.4-0.5-0.6c-0.1,0-0.1,0-0.1,0.1 + c0.1,0.2,0.1,0.5,0.3,0.7l0,0.2c-0.3,0-0.7-0.3-0.9-0.5c0,0-0.1-0.1-0.2,0c-0.1,0.1,0,0.2,0,0.2c0.2,0.3,0.3,0.6,0.6,0.7 + c0.1,0,0.1,0.2,0,0.2c0,0.2-0.2,0.1-0.3,0.1c-0.2-0.2-0.4-0.4-0.6-0.5l-0.1,0c0,0.2,0.2,0.3,0.2,0.4c0.2,0.3,0.6,0.3,0.5,0.7 + c0,0.1,0,0.2-0.1,0.2c-0.5-0.1-1.2-0.3-1.6,0.2c0,0.1,0,0.1,0.1,0.1c0.5,0,0.9,0,1.3,0.3c0.1,0.1,0.2,0.2,0.1,0.3 + c-0.1,0-0.2,0-0.3,0.1c-0.1,0.1-0.3,0.2-0.5,0.3c0,0,0,0.1,0,0.1c0.2-0.1,0.5-0.2,0.7-0.3c0.1,0,0.2,0,0.2,0.1 + c0,0.1-0.1,0.1-0.2,0.2C43.4,35.9,43,36,43,36.3l0.1,0c0.3,0,0.5-0.5,0.8-0.4c0.1,0,0.1,0.1,0.1,0.2c-0.4,0.3-1,0.5-1.1,1.1 + c0,0,0,0.1,0,0.1c0.1,0,0.1-0.1,0.2-0.2c0.4-0.3,0.7-0.6,1.2-0.7c0,0,0.1,0,0.1,0.1c0,0.2-0.4,0.4-0.4,0.6 + c-0.1,0.2-0.1,0.4-0.2,0.6c0,0,0.1,0.1,0.1,0c0.2-0.3,0.4-0.8,0.8-1c0,0.1,0.1,0,0.2,0.1c0.2,0,0.5,0.1,0.6,0.3 + c0,0.5-0.2,1.1,0,1.5c0.1-0.1,0-0.2,0.1-0.3c0-0.4,0.2-0.6,0.3-1c0-0.1,0.2-0.1,0.2-0.1c0.2,0.1,0.2,0.3,0.4,0.4 + c0.1-0.1,0-0.4,0-0.5c0.1-0.1,0.2-0.1,0.3-0.1c0,0,0.1,0,0.2,0c0.1-0.1,0-0.2,0-0.2c0.2-0.2,0.3-0.6,0.7-0.5l0.1,0.1 + c0,0.2,0,0.5-0.1,0.7c-0.1,0-0.1-0.2-0.3-0.1c-0.1,0.1,0,0.2,0,0.3c0.1,0.2,0.2,0.4,0.3,0.6c0,0.1,0.1,0.1,0,0.2 + c-0.3,0-0.4-0.3-0.5-0.4c-0.1-0.1-0.2,0-0.2,0.1c-0.1,0.3,0.2,0.6,0.4,0.8c0.1,0,0.2,0.1,0.2,0.1c0,0.1-0.1,0.2,0,0.3l0.1,0.2 + c-0.1,0.1-0.3,0-0.5-0.1c-0.3-0.2-0.6-0.6-0.7-1c0,0-0.1-0.1-0.1,0c-0.1,0.3,0,0.5,0.2,0.7c0.2,0.1,0.3,0.3,0.3,0.5 + c-0.1,0.1-0.2,0.1-0.3,0.1c-0.3-0.2-0.3-0.6-0.3-0.9c0,0-0.1-0.1-0.1,0c-0.1,0.2-0.1,0.4-0.1,0.5c0,0.2,0.1,0.4-0.1,0.5 + c-0.2,0.1-0.4,0-0.6,0.1c-0.2-0.1-0.2-0.4-0.2-0.6c0-0.1-0.1,0-0.1,0c-0.2,0.1-0.2,0.6-0.5,0.5c-0.2-0.1-0.5-0.2-0.7-0.5 + c-0.1-0.3,0.2-0.4,0.2-0.7c0.1-0.2,0.3-0.3,0.4-0.6c-0.1-0.1-0.3,0.1-0.4,0.2c-0.2,0.3-0.4,0.6-0.5,0.9c0,0.1-0.1,0.1-0.2,0.1 + c-0.3-0.3-1-0.5-0.9-1c0.1-0.1,0.1-0.2,0.2-0.3C42.7,37.3,42.6,37.5,42.5,37.6z M49.5,38.7c0,0,0.1,0,0.1,0 + c0.1-0.2,0.1-0.6,0.1-0.8c0-0.7,0.1-1.4,0.2-2c0-0.1,0-0.2,0.2-0.3c0.2,0,0.5,0.1,0.6,0.3c0.1,0.9,0,1.9-0.3,2.7 + c-0.1,0.4-0.4,0.7-0.6,1.1c-0.1,0.1-0.1,0.4-0.4,0.4c-0.6-0.8-1-1.8-1-2.9c0-0.4-0.2-1,0.1-1.3c0.3-0.1,0.5-0.4,0.8-0.3l0,0.1 + C49.5,36.6,49.2,37.7,49.5,38.7z M52.1,41.6c-0.5-0.2-1-0.7-1-1.3c0-0.1,0.1-0.1,0.1,0l0.5,0.5c0.4,0.2,0.8,0.5,1,0.9 + c0,0.1,0.1,0.3-0.1,0.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.5-0.1-1-0.5-1.2-0.9c-0.1-0.3-0.1-0.7,0-1c0.2,0,0.1,0.2,0.2,0.3 + c0.2,0.4,0.6,1,1.1,1.1C52.2,41.7,52.1,41.6,52.1,41.6z M51.9,36.9c-0.1,0.1-0.2,0.2-0.3,0.3c-0.1-0.2,0.1-0.4,0.1-0.5 + c0,0,0-0.1,0-0.1c-0.1-0.1-0.2,0-0.2-0.2c0-0.1,0-0.1,0-0.2l0.2,0c0.2,0.2,0.5,0.5,0.8,0.7c0,0.2,0,0.4-0.1,0.6 + c0,0.2-0.2,0.4-0.2,0.6c0,0.1,0.1,0.1,0.1,0c0.2-0.3,0.3-0.6,0.6-0.9c0.3-0.1,0.6,0,0.9,0c0.2,0.1,0.1,0.4,0.2,0.6 + c0,0.1,0,0.3,0.1,0.4c0.2,0,0.2-0.3,0.2-0.4c0.1-0.3,0-0.5,0-0.8c0,0,0-0.1,0-0.2c0.1-0.1,0.2-0.1,0.3,0c0.2,0.1,0.3,0.4,0.5,0.5 + c0.1,0,0-0.1,0-0.2c0-0.2-0.3-0.4-0.3-0.6c0-0.1,0.1-0.1,0.2-0.1c0.2,0.1,0.1,0.4,0.3,0.5c0.1,0,0-0.1,0-0.2 + c-0.1-0.2-0.2-0.4-0.2-0.6c0.1-0.1,0.2,0,0.2,0c0.3,0.1,0.5,0.2,0.8,0.4c0.3,0.2,0.3,0.6,0.4,0.9c-0.1,0.3,0.2,0.7-0.1,0.9 + c-0.2,0.1-0.4,0.3-0.6,0.4c-0.1-0.1-0.1-0.2-0.2-0.3c-0.2-0.2-0.3-0.7-0.6-0.6c-0.1,0.1,0.1,0.3,0.1,0.5c0,0.3,0.3,0.6,0.1,0.9 + c-0.3-0.1-0.4,0.3-0.7,0.2c-0.3-0.1-0.6,0.5-0.9,0c0-0.4,0-0.8-0.1-1.3c0-0.1-0.1-0.3-0.2-0.4c-0.1,0.1,0,0.3-0.1,0.5 + c0,0.4-0.1,0.8-0.3,1.1c-0.1,0.1-0.2,0.2-0.3,0.1c0,0-0.1,0-0.1-0.1c0-0.2,0.1-0.4,0.1-0.6c0-0.1-0.1,0-0.1,0 + c-0.2,0.3-0.5,0.7-0.9,0.6c-0.1-0.1-0.1-0.1-0.2-0.1c0.1-0.2,0.4-0.4,0.4-0.6c-0.2,0-0.3,0.2-0.5,0.3c-0.1-0.7,0.6-1.1,0.7-1.8 + C52,36.9,51.9,36.9,51.9,36.9z M51.9,33.6c0.3-0.4,0.8-0.5,1.3-0.6c0.5,0,1.1,0.1,1.4,0.5c0.4,0.5,0.5,1.2,0.3,1.8 + c-0.3,0.6-0.9,1.1-1.6,1.1c-0.3,0.1-0.5-0.1-0.8-0.2c-0.4-0.2-0.5-0.6-0.7-0.9C51.5,34.7,51.6,34.1,51.9,33.6z M57.1,41.6 + c0,0,0.1-0.1,0.2-0.1c0.2,0,0.3,0,0.5,0.1c0.1,0.2,0.2,0.5,0.1,0.7c-0.3,0.1-0.5,0-0.7-0.2C57,41.9,57.2,41.7,57.1,41.6z + M57.3,41.2c-0.3-0.1-0.6-0.4-0.8-0.7c-0.1-0.3-0.3-0.5-0.3-0.8c0-0.2-0.1-0.4,0-0.6h0c0.2,0.5,0.6,0.8,1,1.3 + c0.1,0.1,0.3,0.1,0.4,0.3C57.6,40.9,57.5,41.1,57.3,41.2z M54.9,47.4c-0.3,0.1-0.5-0.3-0.8-0.4c-0.3-0.4-0.6-0.8-0.6-1.3 + c0,0,0.1-0.1,0.1-0.1c0.2,0.3,0.4,0.7,0.8,0.8c0.1,0,0.1,0,0.1-0.1c-0.1-0.3-0.3-0.6-0.2-0.9c0.2,0,0.3,0.3,0.6,0.3 + c0.1,0.1,0.1,0.4,0.1,0.5C54.9,46.6,55,47.1,54.9,47.4z M54.8,53.9c0-0.8,0.2-1.7,0.2-2.5c0.1-0.1,0.3-0.2,0.5-0.2 + c0,0.1,0,0.3,0,0.5c0,0.8-0.1,1.6-0.1,2.5c0,0.3-0.1,0.7-0.1,1c-0.1,0.2-0.1,0.4-0.1,0.7c0,0.7-0.2,1.3-0.3,1.9 + c-0.1,0.1-0.1,0.4-0.3,0.4c-0.2-0.2-0.1-0.5-0.1-0.7c0.1-0.2,0-0.5,0.1-0.7C54.6,55.8,54.9,54.9,54.8,53.9z M54.6,59.7 + c0.2,0.4,0.2,0.8,0.3,1.1c0,0.2,0.1,0.4-0.1,0.5c-0.5-0.1-0.9,0.1-1.3,0.4c-0.1,0-0.2,0-0.3-0.1c-0.1-0.2,0-0.4,0-0.6 + c0.1-0.2,0-0.5,0.2-0.7c0.1-0.1,0.3-0.1,0.3-0.3c-0.2-0.1-0.5,0-0.6-0.2c-0.2-0.3-0.4-0.6-0.4-1c0.3-0.3,0.8-0.4,1.2-0.3 + c0.1,0.1,0.3,0.1,0.3,0.2C54.5,59.2,54.5,59.5,54.6,59.7z M53.9,62.1c0.1-0.3,0.4-0.3,0.6-0.4c0.1,0,0.2,0,0.2,0.1 + c-0.1,0.6-0.2,1.2-0.6,1.7c0,0.1-0.1,0.1-0.2,0.1c-0.1,0,0-0.1,0-0.2C54.1,63,54.1,62.5,53.9,62.1z M52.9,63.1 + c-0.4-0.1-0.9-0.4-0.9-0.9c0-0.1-0.1-0.2-0.1-0.3c0.2-0.2,0.5-0.2,0.8-0.2l0.1,0.1C52.7,62.2,52.6,62.8,52.9,63.1z M52.3,61.4 + c-0.2,0-0.4,0.2-0.6,0.2c-0.1-0.2-0.1-0.4-0.2-0.6c-0.1-0.7,0-1.4,0.6-1.8c0.1-0.1,0.2,0,0.3,0c0.2,0.2,0.3,0.5,0.4,0.7 + c0.1,0.2,0.2,0.3,0.3,0.6c0.1,0.3,0,0.6,0,0.9C52.8,61.5,52.5,61.3,52.3,61.4z M47.7,62.4c0.2-0.1,0.4-0.3,0.7-0.1 + c0.2,0.2,0.2,0.4,0.2,0.6c-0.2,0.4-0.6,0.8-1,0.9c0,0-0.1,0-0.1-0.1c0-0.3,0.2-0.5,0.1-0.8C47.5,62.7,47.6,62.6,47.7,62.4z + M48.5,62c-0.2,0-0.4-0.1-0.5-0.2c-0.2,0-0.2,0.2-0.4,0.3c-0.1,0-0.1,0.1-0.2,0.1c-0.1-0.2-0.1-0.4-0.1-0.6c-0.1-0.2,0-0.5,0.1-0.7 + c0.2-0.1,0.3-0.3,0.5-0.3c0.1-0.1,0.1-0.1,0.1-0.2c-0.1-0.1-0.3-0.1-0.4-0.1c-0.2,0.1-0.3,0.2-0.5,0.4c-0.2-0.3-0.2-0.6-0.2-1 + c0-0.3,0.1-0.7,0.4-0.8c0.2,0.1,0.6,0.1,0.7,0.4c0.4,0.5,0.8,1,0.9,1.7c0,0.4,0.1,0.8-0.1,1.2C48.6,62.2,48.6,62.1,48.5,62z + M47.3,58.2c-0.6-0.3-0.7-1-0.6-1.6c0-0.1,0-0.3,0.2-0.3c0.1,0.1,0.1,0.2,0.2,0.3c0.3,0.6,1,1,1.5,1.5c0.4,0.2,0.6,0.7,0.6,1.2 + c0.1,0.1,0,0.3,0,0.4c0,0-0.1,0-0.1-0.1C48.6,59,48,58.4,47.3,58.2z M44.4,40.8c0.2-0.1,0.3-0.3,0.5-0.4c0.2-0.2,0.3-0.4,0.5-0.6 + c0.1,0,0.2,0,0.2,0.1c0,0.3-0.1,0.5-0.2,0.8c-0.3,0.6-0.7,1.2-1.4,1.3c-0.2,0-0.4-0.1-0.5-0.2c0-0.3-0.1-0.5-0.1-0.7 + c0-0.5,0.4-0.9,0.7-1.4c0.1-0.1,0.3-0.2,0.3,0c-0.1,0.3-0.1,0.7-0.1,1C44.4,40.7,44.4,40.8,44.4,40.8z M45.9,44.5 + c0.4-0.3,0.7-0.8,1-1.1c0,0,0.1,0,0.1,0c0,0.7-0.4,1.3-0.9,1.9c-0.3,0.3-0.8,0.5-1.2,0.4c-0.3-0.1-0.4-0.4-0.5-0.6 + c0-0.3,0.1-0.5,0.2-0.7c0.4-0.3,0.9-0.6,1.1-1c0-0.1,0.1-0.1,0.2-0.1c0,0.5-0.3,0.9-0.5,1.3C45.7,44.7,45.8,44.6,45.9,44.5z + M47,41.8c0.4-0.1,0.6-0.4,0.8-0.7c0-0.2,0.2-0.3,0.3-0.5c0,0,0,0,0.1,0c0,0.7-0.3,1.4-0.9,1.9c-0.1,0.1-0.3,0.1-0.4,0.1 + c-0.2-0.1-0.5-0.2-0.5-0.4c0-0.5,0.1-0.9,0.5-1.1c0.1-0.1,0.2-0.3,0.4-0.3c0,0.3-0.1,0.6-0.2,0.8C47.1,41.6,46.9,41.7,47,41.8z + M48.9,48.7C49,48.7,49,48.7,48.9,48.7c0.2-0.1,0.1-0.3,0.2-0.4c0.1-0.1,0.2,0,0.2,0c0.3,0.2,0.1,0.6,0.2,0.9c0,0.3-0.1,0.7-0.2,1 + c0.1,0.1,0.2,0,0.2,0c0.3-0.4,0.2-0.8,0.3-1.3c0-0.1,0-0.2,0.1-0.3c0.1,0,0.1,0,0.1,0.1c0,0.3,0,0.6,0,0.9l0.1,0 + c0.3-0.4,0.1-0.9,0.3-1.4c0.1-0.2,0-0.5,0.1-0.8c0.2,0,0.2,0.2,0.2,0.4c0,0.2,0.1,0.3,0.2,0.4c0.1,1,0.4,2.4-0.6,3 + c-0.3,0.2-0.8,0.1-1.1,0c-0.3-0.1-0.4-0.5-0.5-0.7c-0.2-0.6-0.4-1.2-0.3-1.9c0.1-0.6,0.2-1.3,0.5-1.8c0.1,0.1,0,0.2,0,0.3 + C48.9,47.7,48.8,48.2,48.9,48.7z M51.8,46.6c-0.1-0.2-0.1-0.5-0.2-0.8c0-0.2,0.2,0,0.2,0.1c0.2,0.6,1.1,0.7,1.1,1.4 + c0.1,0.2,0.1,0.4,0,0.6c-0.2,0.2-0.5,0.3-0.9,0.3c-0.5-0.2-0.8-0.7-1.2-1.1c0-0.3-0.3-0.5-0.1-0.8c0.1,0,0.2,0.1,0.2,0.1 + c0.3,0.3,0.6,0.6,0.9,0.8c0.1,0,0.1,0,0.2-0.1C52.2,46.9,51.9,46.8,51.8,46.6z M51.3,52.4c-0.1-0.2-0.4-0.4-0.4-0.6 + c0-0.1-0.1-0.2,0.1-0.3c0.5,0.2,0.9,0.5,1.2,0.9c0.1,0.3,0.1,0.7,0,0.9c0,0.1-0.1,0.3-0.2,0.3c-0.1,0.1-0.3,0.1-0.5,0.1 + c-0.5-0.3-0.8-0.9-0.9-1.5h0.1c0.2,0.2,0.3,0.7,0.7,0.5C51.4,52.7,51.4,52.5,51.3,52.4z M52.2,51.3c-0.3-0.4-0.6-0.8-0.6-1.4 + c0,0,0.1-0.1,0.1,0c0.1,0.1,0.1,0.2,0.1,0.3c0.1,0.2,0.2,0.5,0.5,0.5c0.1,0,0-0.2,0-0.2c0-0.3-0.2-0.5-0.1-0.8h0 + c0.4,0.4,0.9,0.8,0.7,1.4c0,0.2-0.2,0.3-0.3,0.3C52.5,51.4,52.4,51.4,52.2,51.3z M47.1,50.7c0.3-0.3,0.5-0.6,0.7-0.9 + c0.1,0,0.1,0,0.1,0.1c0.1,0.8-0.3,1.4-0.9,1.8c-0.2,0.1-0.4,0.1-0.5,0.1c-0.1-0.1-0.2-0.3-0.3-0.4c-0.1-0.6,0.1-1.1,0.5-1.5 + c0.2-0.2,0.2-0.4,0.4-0.5c0.2,0.1,0.1,0.5,0.1,0.7c0,0.3-0.2,0.4-0.2,0.7C46.9,50.9,47,50.7,47.1,50.7z M47.6,51.9 + c0.1-0.3,0.4-0.4,0.6-0.7c0.1,0,0.2,0,0.2,0.1c0,0.5-0.3,0.9-0.5,1.3c0.1,0.1,0.2-0.1,0.4-0.1c0.3-0.2,0.3-0.6,0.5-0.9 + c0.1,0,0.2,0.1,0.2,0.1c0.3,0.7-0.1,1.3-0.4,1.8c-0.2,0.4-0.6,0.2-0.9,0.3c-0.2,0-0.4-0.1-0.4-0.3C47.1,52.9,47.5,52.4,47.6,51.9z + M48.5,46.1c0,0.3-0.1,0.5-0.2,0.8L48.2,47c0.1,0.1,0,0.2,0,0.3c-0.1,0.6-0.6,1-1.2,1.1c-0.2,0-0.4-0.1-0.6-0.2 + c-0.3-0.2-0.2-0.6-0.2-1c0.2-0.6,0.6-1.2,1-1.8c0,0,0.1-0.1,0.1,0c0.1,0.6,0,1.1-0.2,1.6c0,0.1,0,0.2,0.1,0.3 + c0.2-0.1,0.2-0.3,0.4-0.4l0-0.1c0.2-0.4,0.5-0.8,0.6-1.3c0-0.1,0.1,0,0.1-0.1C48.6,45.7,48.5,45.9,48.5,46.1z M45.5,43 + c-0.2,0.2-0.5,0.4-0.8,0.4c-0.1,0-0.2-0.1-0.2-0.2c-0.1-0.6,0.4-0.9,0.5-1.4c0.1-0.1,0.2-0.3,0.3-0.3c0.1,0.3-0.1,0.6-0.1,1 + c0.1,0.1,0.2-0.1,0.3-0.2c0.2-0.4,0.4-0.9,0.5-1.3c0-0.1,0.1,0,0.1,0C46.1,41.8,45.8,42.4,45.5,43z M44.4,46.7l0.5-0.5 + c0.1,0,0.1,0,0.1,0.1c0.1,0.3-0.1,0.7-0.2,0.9c0,0.1-0.1,0.3,0,0.4c0.2,0,0.3-0.2,0.4-0.3c0.2-0.3,0.4-0.6,0.7-0.8c0,0,0.1,0,0.1,0 + c0,0.5-0.3,0.9-0.5,1.3c-0.2,0.4-0.6,0.7-1.1,0.6l-0.1-0.1C44.2,47.8,44.1,47.1,44.4,46.7z M46.1,52.7c0.1-0.1,0.1-0.2,0.2-0.2 + c0,0.2-0.2,0.3-0.2,0.5c-0.1,0.2-0.2,0.4-0.2,0.6c0.1,0.1,0.2,0,0.3,0c0.2-0.2,0.4-0.4,0.6-0.6c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1 + c-0.2,0.4-0.4,1-1,1.1c-0.2,0-0.4,0-0.5-0.1c-0.1-0.3,0-0.7,0.2-1C45.7,53.1,45.8,52.8,46.1,52.7z M46,56.6c0,0.4,0.1,0.9-0.1,1.2 + c-0.1,0.1-0.2,0.2-0.3,0.1c-0.2-0.1-0.2-0.2-0.2-0.4c0-0.4-0.1-0.8,0.1-1.2c0.1-0.3,0.1-0.5,0.2-0.8c0-0.2,0.1-0.4,0.1-0.6 + c0.1,0.1,0,0.3,0.1,0.4C46,55.8,45.8,56.2,46,56.6z M45.3,59.6c0.1-0.2,0.2-0.5,0.4-0.7c0.1-0.2,0.4-0.1,0.6-0.2 + c0.2,0.1,0.6-0.1,0.5,0.2c-0.2,0.4-0.4,0.9-0.2,1.3c-0.1,0.2-0.6,0-0.5,0.3c0.2,0.3,0.5,0.1,0.6,0.4c0.1,0.3,0.1,0.7,0.2,1 + c0,0.1-0.1,0-0.1,0c-0.3-0.2-0.6-0.4-0.9-0.2c-0.2,0.1-0.3,0.3-0.5,0.5c-0.1,0.1-0.1-0.1-0.1-0.1C45,61.3,45.1,60.3,45.3,59.6z + M47.8,57c-0.2-0.3-0.3-0.7-0.5-1c0-0.4-0.1-0.7,0-1.1c0-0.1,0-0.2,0.1-0.3l0,0c0,0.8,0.5,1.3,0.9,1.9c0.3,0.3,1,0.4,0.9,1 + c0,0.3,0.2,0.5,0,0.8c-0.1,0-0.1-0.1-0.1-0.1C48.8,57.7,48.2,57.4,47.8,57z M49.3,56c-0.4-0.4-0.7-0.9-0.5-1.5c0-0.4,0.2-0.8,0.5-1 + c0.1-0.1,0-0.3,0.2-0.3c0.1,0.1,0,0.2-0.1,0.2c0.1,0.4,0.3,1-0.1,1.3c0,0.1,0,0.2,0.1,0.2c0.4,0.1,0.3-0.4,0.5-0.5 + c0,0.3-0.2,0.6-0.4,0.8c0,0.1,0.2,0.1,0.2,0.2c0.2,0,0.3-0.3,0.4-0.4c0.1-0.5,0.1-0.9-0.2-1.3c0-0.1-0.1-0.3,0.1-0.5 + c0.3,0,0.4,0.3,0.5,0.5c0.2,0.4,0.3,1,0.1,1.4c0.1,0.5-0.4,0.6-0.6,0.9C49.8,56,49.5,56.2,49.3,56z M50.3,57c0-0.2,0.2-0.3,0.3-0.5 + c0.2-0.5,0.4-0.9,0.7-1.3c0.2-0.2,0.1-0.5,0.2-0.8c0.1,0,0.1,0.2,0.2,0.3c0.1,0.5,0.1,1.1-0.1,1.5c-0.3,0.6-0.8,1.1-1,1.6 + c-0.1,0.1-0.1,0.3-0.2,0.4C50.1,57.9,50.1,57.4,50.3,57z M50.6,58.9c0.1-0.5,0.4-0.9,0.6-1.3c0.4-0.5,0.6-1,0.8-1.5 + c0-0.1-0.1-0.2,0-0.3c0.2,0.3,0.3,0.7,0.2,1.1c0,1-1.1,1.6-1.2,2.5c-0.1,0.1-0.2,0.3-0.3,0.4C50.6,59.6,50.7,59.2,50.6,58.9z + M53,56.9c0-0.6,0.2-1.1,0.2-1.7c0-0.1,0.1-0.2,0.1-0.1c0.1,0.6,0,1.2,0.2,1.7c0,0.4,0.1,0.9-0.3,1.1C53.1,58,53,57.9,53,57.8 + C52.8,57.5,53,57.2,53,56.9z M53.8,53.5c-0.1,0.1-0.2,0.2-0.4,0.1c-0.6-0.2-0.8-0.8-0.9-1.3c0.1,0,0.2,0.2,0.3,0.2 + c0.2,0.1,0.3,0.5,0.6,0.3c0-0.3-0.3-0.4-0.4-0.7c0-0.1-0.1-0.2-0.1-0.3c0.1,0,0.1,0.2,0.3,0.3c0.3,0.1,0.6,0.4,0.7,0.7 + C54,53,54,53.3,53.8,53.5z M52.7,44.8c-0.4-0.3-0.5-0.7-0.6-1.2c0-0.1-0.1-0.3,0-0.4c0.1,0,0.1,0.1,0.1,0.1 + c0.2,0.2,0.4,0.6,0.7,0.7c0.1,0.1,0.1,0.1,0.1,0.2c0.1,0,0.2,0,0.2-0.1c0-0.1-0.1-0.3-0.2-0.4c-0.1-0.3-0.4-0.5-0.3-0.9 + c0.1-0.1,0.2,0.1,0.4,0.2c0.4,0.1,1,0.4,1.1,0.9c0,0.3,0,0.7-0.2,0.9C53.5,45,53,44.9,52.7,44.8z M53.9,41.8 + c0.1,0.1,0.2,0.2,0.3,0.2c0.2,0.2,0.4,0.5,0.3,0.8c-0.1,0.1-0.1,0.3-0.2,0.4c-0.3,0-0.5-0.3-0.7-0.5c-0.2-0.2-0.3-0.4-0.2-0.7 + c0-0.1,0.1,0,0.2,0c0.2,0.1,0.3,0.4,0.5,0.2C54,42.1,53.8,42,53.9,41.8z M54.2,41.6c-0.3-0.5-0.6-0.9-0.6-1.5c0,0,0.1,0,0.1,0 + c0.2,0.3,0.5,0.8,1,0.8c0.1-0.1-0.1-0.3-0.1-0.4c0-0.2-0.1-0.3-0.1-0.5c0.1,0,0.1,0.1,0.2,0.2c0.3,0.2,0.6,0.4,0.7,0.8 + c0,0.3,0,0.7-0.3,1C54.7,41.9,54.4,41.8,54.2,41.6z M51,45.4c-0.3,0.4-0.9,0.8-1.5,0.8c-0.3-0.1-0.6-0.1-0.8-0.4 + c0-0.2-0.3-0.3-0.2-0.6c-0.2-0.5-0.4-1-0.3-1.6c-0.1-0.6,0.1-1.3,0.2-1.9c0.1-0.1,0.2-0.4,0.3-0.2c0,0.6-0.2,1.1,0.1,1.6 + c0.1,0,0.1,0.1,0.2,0.1c0.2-0.1,0-0.4,0.1-0.6c0.1-0.1,0.1,0,0.2,0.1c0.1,0.6,0,1.3,0.3,1.8c0.1,0.1,0.2,0.2,0.3,0.1 + c0.1-0.1,0-0.1,0.1-0.2c-0.3-0.8-0.3-1.8,0-2.6c0.1,0,0.1,0,0.1,0.1c0.1,0.5-0.1,1.1,0.1,1.5c0.2-0.1,0.2-0.3,0.3-0.5 + c0.1-0.5,0-1.1,0.1-1.6c0.1,0,0,0.1,0.1,0.1C51,42.7,51.8,44.2,51,45.4z M48.6,34c0-0.1,0.1-0.3-0.1-0.3c-0.1,0-0.3,0.1-0.4,0.1 + c0,0-0.1-0.1-0.1-0.1c0,0,0,0,0-0.1c0.2-0.1,0.5-0.3,0.7-0.4c0.1-0.1,0.2-0.2,0.3-0.1C49.1,33.5,48.8,33.8,48.6,34 + C48.6,34.1,48.6,34.1,48.6,34z M47.9,33.2c-0.2,0-0.4,0.1-0.6-0.1c0.1-0.2,0.3-0.1,0.4-0.2c0.3-0.1,0.5,0.2,0.7,0.2c0,0,0,0,0,0.1 + C48.3,33.2,48.1,33.1,47.9,33.2z M48.5,31.6c-0.1,0-0.1-0.2-0.2-0.2c-0.1-0.1-0.1-0.1-0.2-0.1c-0.1,0.1-0.2,0.3-0.3,0.5l0,0.1 + c-0.2,0-0.2-0.2-0.4-0.3c-0.1-0.3,0.2-0.5,0.3-0.7c0.2,0,0.5,0.1,0.6,0.3C48.4,31.2,48.6,31.3,48.5,31.6z M47.7,32.2 + c-0.1,0.3,0.3,0.2,0.4,0.3l0,0.1c0,0.1-0.2,0.1-0.3,0.1c-0.3-0.1-0.6-0.1-0.8,0.1c-0.1,0-0.2,0-0.3-0.1c0-0.2,0.3-0.1,0.4-0.1 + c0.1-0.1,0.2-0.1,0.3-0.2c-0.3-0.3-0.7,0-1,0c-0.2,0.1-0.5,0.1-0.7,0c0,0,0-0.1,0.1-0.1c0.3,0.1,0.5-0.2,0.8-0.2 + c0.2-0.1,0.5,0,0.8,0C47.5,32.1,47.6,32.2,47.7,32.2z M46.9,31.7c-0.5,0-0.9,0.3-1.5,0.2c0,0-0.1,0-0.1-0.1c0-0.1,0.1-0.1,0.1-0.1 + c0.1-0.2,0.4-0.1,0.5-0.2c0.1,0,0.3,0,0.4-0.1c0.3,0,0.7,0,0.9,0.3l0,0.1C47.1,31.8,47,31.7,46.9,31.7z M45.6,33.1 + c0.6-0.2,1.2,0,1.6,0.3c0.4,0.5,0.5,1.3,0.2,1.9c-0.2,0.4-0.5,0.9-1,0.9c-0.6,0.3-1.2,0-1.7-0.4c-0.3-0.4-0.6-0.9-0.4-1.4 + C44.4,33.9,45,33.3,45.6,33.1z M43.7,42.8C43.7,42.8,43.7,42.9,43.7,42.8c0,1.2,0.1,2.3,0.2,3.6c0.1,1.1,0.1,2.2,0.2,3.2 + c0,0.2-0.2,0.3-0.3,0.5c-0.1,0.1-0.2,0.3-0.4,0.3c-0.2-0.3-0.1-0.7-0.2-1.1c-0.1-1.7-0.3-3.6-0.3-5.4c0.1-0.2,0.2-0.4,0.3-0.7 + C43.4,43.2,43.6,43,43.7,42.8z M44.2,49.9L44.2,49.9c0.3-0.3,0.6-0.6,0.8-0.8c0,0,0.1,0,0.1,0c-0.1,0.5-0.2,1-0.6,1.5 + c0,0.1,0,0.1,0.1,0.1c0.2-0.3,0.4-0.5,0.7-0.8c0.2-0.2,0.3-0.4,0.5-0.6c0.1,0.2,0,0.4,0,0.5c-0.1,0.8-0.4,1.5-1.2,1.9 + c-0.3,0-0.4,0.2-0.7,0.1c-0.2,0-0.4-0.2-0.5-0.4C43.4,50.9,43.8,50.4,44.2,49.9z M43.8,52.2l0.3-0.1c0,0,0.1,0,0.1,0.1 + c0.1,0.9,0.1,1.8,0.2,2.7c0,0.7,0.1,1.2,0.2,1.9c0.1,0.4,0,0.9,0.2,1.3c0.2,0.4-0.1,0.6-0.2,0.9c-0.3,0,0-0.4-0.2-0.6 + c-0.3-1.2-0.6-2.3-0.7-3.6c-0.1-0.6-0.1-1.2-0.2-1.8c-0.1-0.3,0-0.6-0.1-0.9C43.6,52.1,43.7,52.2,43.8,52.2z M43.6,60.8 + c0-0.4,0.1-0.8,0.3-1.1c0-0.2,0.2-0.2,0.4-0.3c0.2,0,0.4-0.2,0.6,0c0,0.1,0.2,0.2,0.1,0.4c-0.1,0.2-0.2,0.4-0.5,0.6 + c-0.1,0-0.3-0.1-0.3,0.1c0,0.3,0.4,0.1,0.5,0.3c0,0.2,0.1,0.5,0,0.7c-0.2,0-0.5,0-0.7,0.1c-0.1,0.1-0.2,0.2-0.3,0.1 + C43.4,61.5,43.5,61.1,43.6,60.8z M44.1,61.8c0.2-0.1,0.4-0.1,0.6,0c0,0.2-0.1,0.5-0.1,0.7c0,0.3,0.2,0.6,0.5,0.7v0 + c-0.2,0.1-0.4-0.1-0.6-0.2c-0.3-0.2-0.3-0.5-0.4-0.7C44.1,62.2,43.9,61.9,44.1,61.8z M46.1,62c0.2,0,0.4,0,0.6,0.2 + c0,0.2-0.1,0.4-0.1,0.7c0,0.3,0,0.6,0.2,0.8l0,0.1c-0.2,0-0.4-0.2-0.5-0.3c-0.3-0.3-0.6-0.6-0.6-1C45.7,62.2,45.9,62.1,46.1,62z + M55.5,61.8c-0.1,0,0-0.1,0-0.2c0.2-0.3,0.5-0.1,0.8-0.2l0,0c0.1,0.3-0.3,0.5-0.4,0.8c-0.1,0.1-0.1,0.2-0.1,0.2 + c-0.2,0.2-0.3,0.4-0.5,0.6l-0.1,0C55.3,62.7,55.7,62.3,55.5,61.8z M56.4,61.1c-0.1,0.1-0.1,0.1-0.2,0.1c-0.3-0.1-0.5,0.1-0.8,0.1 + c-0.1-0.2-0.2-0.5-0.2-0.7c0.2-0.2,0.4-0.3,0.5-0.5c0-0.1,0-0.1-0.1-0.1c-0.2,0-0.4,0.4-0.6,0.1c-0.1-0.2-0.2-0.5-0.3-0.8 + c0.2-0.1,0.4,0,0.5,0.1l0.3,0.1c0.5,0.1,0.5,0.7,0.8,1C56.4,60.6,56.7,60.9,56.4,61.1z M55.3,51c-0.6,0.1-1.2-0.2-1.6-0.6 + c-0.2-0.3-0.4-0.6-0.4-1c0-0.1,0.1-0.1,0.2-0.1c0.3,0.3,0.7,0.6,1.1,0.7l0.1-0.1c0.1,0,0.1,0.2,0.2,0.1c0,0,0.1-0.1,0-0.1 + c-0.5-0.4-0.8-0.9-0.9-1.4c0-0.1,0.1-0.1,0.2-0.1c0.5,0.3,1,0.7,1.5,1.1c0.2,0.3,0.4,0.6,0.3,0.9C55.7,50.7,55.5,50.9,55.3,51z + M55.6,41.2c0-0.1,0.1,0,0.1,0c0.2,0.2,0.3,0.4,0.5,0.6c0.4,0.3,0.7,0.7,1.2,0.8c0.1,0.2,0.4,0.2,0.5,0.3c0,0.2-0.1,0.4-0.3,0.4 + c-0.6,0-0.9-0.4-1.3-0.8C56,42.2,55.8,41.7,55.6,41.2z M57.9,40.3c-0.1,0.1-0.3,0-0.4-0.1c-0.4-0.2-0.2-0.6-0.3-1 + c0-0.3-0.1-0.6,0.1-0.8c0.1,0,0.1,0.1,0.1,0.1C57.6,39.1,57.9,39.6,57.9,40.3z M57.5,36.4c0,0.1-0.1,0.1-0.2,0 + c-0.1-0.2-0.4-0.3-0.5-0.6c0-0.1-0.2-0.1-0.2,0c0,0-0.1,0.1,0,0.1c0.3,0.4,0.4,0.8,0.7,1.2c0,0.2-0.2,0.4-0.3,0.6c0,0-0.1,0-0.1,0 + c-0.2-0.1-0.2-0.3-0.3-0.5c0-0.1-0.1-0.3-0.1-0.4c0.1-0.4-0.3-0.6-0.4-0.9c-0.2-0.2-0.5-0.2-0.6-0.4c0-0.1,0-0.2,0.1-0.2 + c0.3-0.3,0.6,0.1,0.9-0.1c0.1,0.1,0.3,0,0.4,0c0.2,0.1,0.4,0.3,0.6,0.3c0.2,0.1,0.2,0.3,0.2,0.5C57.6,36.2,57.5,36.3,57.5,36.4z + M57,32.7c0,0.1-0.1,0.3,0,0.4c0.1,0.1,0.3,0.2,0.3,0.3c0,0.1,0,0.2-0.1,0.2c-0.3,0-0.6,0.1-0.8,0.4c0,0.1,0,0.1,0.1,0.1 + c0.2,0,0.2-0.3,0.5-0.3c0.2,0,0.3-0.1,0.5,0c0,0.2,0.2,0.3,0.2,0.4c-0.1,0.3,0.1,0.7-0.1,1c-0.4,0-0.7-0.4-1.1-0.1 + c-0.2,0-0.5-0.2-0.7-0.1c-0.2-0.1-0.3-0.4-0.2-0.6c0.1-0.2,0.3-0.1,0.4-0.3c0.1,0,0.3,0.1,0.3,0c0-0.2-0.3-0.1-0.4-0.1 + c-0.1,0-0.2,0.1-0.4,0.1c-0.1-0.1-0.1-0.2-0.1-0.4c0.2-0.4,0.7-0.5,1-0.6c0,0,0.1-0.1,0-0.1c-0.4-0.3-0.9,0.1-1.2,0.3 + c-0.1,0-0.1,0-0.1-0.1c0.1-0.3,0.2-0.6,0.5-0.7c0,0,0.1-0.1,0.1-0.1c-0.1-0.1-0.2,0-0.3,0c-0.1,0.1-0.3,0.3-0.5,0.4 + c0-0.2,0.3-0.4,0.4-0.7c0,0,0-0.1-0.1-0.1c-0.3,0.2-0.5,0.5-0.9,0.7c-0.1,0-0.2,0-0.3,0c-0.1,0,0-0.1,0-0.2 + c0.2-0.3,0.5-0.6,0.6-0.9c0.2-0.6,0.9-0.5,1.3-0.9c0.2,0.1,0.4-0.1,0.5,0.1C56.2,31,56.1,31,56,31.1c-0.2,0.2-0.6,0.3-0.7,0.6 + c0.2,0.1,0.2-0.2,0.4-0.2c0.1-0.1,0.2-0.2,0.3-0.1c0.2,0.2,0.3-0.3,0.4,0.1c-0.1,0.2-0.3,0.2-0.4,0.3c-0.1,0.1-0.3,0.3-0.3,0.5 + c0,0.1,0.1,0,0.2,0c0.2-0.2,0.4-0.4,0.7-0.4C56.9,32.1,57,32.4,57,32.7z M53.5,29.8c0.2-0.3,0.6-0.2,0.8-0.4c0.7-0.2,1.4,0.1,2-0.4 + l0.7-0.5c0.3,0,0.4-0.3,0.6-0.4c0.1,0,0.2,0,0.2,0.1c-0.1,0.3-0.2,0.6-0.3,1c-0.1,0.5-0.6,0.6-1,0.9c-0.2,0.2-0.5,0.2-0.8,0.2 + c-0.6,0-1.1,0.3-1.4,0.8c0.1,0.2-0.1,0.3-0.2,0.3c-0.1,0.1-0.3,0.1-0.4,0.2c0.1,0.1,0.2,0,0.2,0.2c-0.3,0.3-0.8,0-1.1,0.3 + c0,0-0.1,0.1-0.1,0.1c0.1,0.1,0.3,0,0.3,0.1c-0.2,0.2-0.6,0.1-0.8,0.3c0,0.1,0,0.1,0.1,0.1c0.1,0,0.2-0.1,0.3,0 + c0,0.1-0.1,0.1-0.2,0.2c-0.3,0.1-0.6,0-0.8,0.2c0.1,0.1,0.3,0.1,0.4,0.2c-0.3,0.2-0.7,0.2-0.9,0.4c-0.2,0.2,0.1,0.7-0.3,0.5 + c-0.2-0.2-0.3-0.4-0.4-0.7c0.1-0.1,0-0.4,0.1-0.3c0.2,0.1,0.2,0.3,0.3,0.4c0.1,0,0.2-0.1,0.3-0.2c-0.2-0.3,0.3-0.3,0.4-0.5 + c0-0.3,0.3-0.2,0.4-0.3c0.3-0.1,0.5-0.1,0.8-0.2c0,0-0.1,0-0.1-0.1c0,0-0.1,0-0.1,0c0,0,0,0,0-0.1c0.3-0.4,0.8-0.3,1.2-0.4 + c0-0.1-0.2-0.1-0.1-0.2c0.3-0.2,0.8-0.1,0.9-0.5c0-0.1,0.1-0.2,0-0.2c-0.2,0.1-0.3,0.3-0.5,0.4c-0.2,0.2-0.4,0.3-0.6,0.4 + c0-0.1,0.1-0.2,0.2-0.3c0.3-0.3,0.5-0.7,0.7-1.2c0-0.1-0.1,0-0.2,0c-0.3,0.3-0.7,0.5-1,0.8c-0.1,0-0.2,0.1-0.2,0 + c-0.1-0.2,0.2-0.2,0.2-0.4C53.1,30.2,53.3,30,53.5,29.8z M50.2,31.6c-0.1-0.1-0.1-0.3-0.1-0.5c0,0-0.1,0-0.1,0 + c-0.1,0.1-0.2,0.3-0.2,0.4c0,0-0.1,0-0.1,0c-0.1-0.3,0-0.6,0.1-0.8c0.1-0.1,0.2-0.2,0.3-0.2c0.1,0.1,0.2,0.2,0.3,0.3 + C50.4,31.1,50.4,31.4,50.2,31.6z M51.2,31.2c-0.1-0.1-0.2,0.1-0.3,0.1c-0.1,0.1-0.2,0.3-0.3,0.4c-0.1,0-0.1,0-0.1-0.1 + c0-0.3,0.1-0.5,0.2-0.8c0.1-0.2,0.4-0.2,0.5-0.4c0.1-0.1,0.4-0.2,0.4,0.1c0,0.2,0.1,0.4,0.2,0.6c0,0.2-0.2,0.4-0.2,0.6 + c0,0-0.1,0.1-0.2,0.1C51.4,31.6,51.3,31.4,51.2,31.2z M51.5,28.9c0-0.3,0.3-0.2,0.5-0.3c0.3,0,0.7,0,0.9,0.3 + c0.1,0.1,0.1,0.2,0.1,0.4c-0.2,0.1-0.1,0.4-0.3,0.5c-0.3-0.1-0.2-0.4-0.4-0.6c-0.3-0.2-0.5,0.1-0.8,0.2 + C51.3,29.2,51.5,29,51.5,28.9z M51.8,29.5c0.1,0,0.1,0,0.2,0.1c0,0.4,0.5,0.7,0.1,1c-0.3,0-0.2-0.3-0.3-0.5 + c-0.2-0.2-0.4,0.2-0.6,0.1c-0.1,0-0.2-0.1-0.1-0.2C51.1,29.7,51.5,29.6,51.8,29.5z M49.7,28.9c0.2-0.4,0.6-0.4,1-0.4 + c0.2,0.2,0.2,0.4,0.4,0.5c0,0.1,0,0.3-0.1,0.4c-0.1,0-0.2-0.2-0.3-0.2C50.5,29,50.3,29,50.1,29c-0.1,0-0.2,0.2-0.3,0.1 + C49.7,29.1,49.7,29,49.7,28.9z M50.1,29.4c0.2-0.1,0.3,0.2,0.4,0.4c0,0.1,0.3,0.2,0.2,0.4c-0.1,0.1-0.1,0.2-0.2,0.2 + c-0.2-0.1-0.3-0.4-0.5-0.3c-0.1,0.1-0.2,0.2-0.3,0.2c-0.1-0.1-0.1-0.3-0.1-0.4C49.8,29.6,49.9,29.5,50.1,29.4z M49.6,33.3 + c0.2-0.1,0.4,0.1,0.5-0.1l0,0c0,0.2,0.2,0.5,0.1,0.7c0,0.1,0.1,0.2,0.1,0.4c-0.1,0-0.1-0.2-0.2-0.3c0-0.1-0.1-0.2-0.2-0.2 + c-0.2,0-0.1,0.5-0.3,0.2c-0.1-0.2,0.1-0.4-0.1-0.5c-0.1,0.2-0.2,0.3-0.3,0.5c-0.1,0-0.2-0.1-0.2-0.2c0.3-0.1-0.1-0.5,0.3-0.6 + C49.4,33.2,49.5,33.2,49.6,33.3z M49.4,31.3c-0.1,0-0.1-0.1-0.1-0.2c0-0.1-0.1-0.2-0.2-0.1C49,31.1,49,31.2,49,31.4l0,0 + c-0.2-0.2-0.3-0.4-0.2-0.7c0-0.2,0.2-0.3,0.3-0.4c0.1,0,0.2,0.1,0.3,0.2C49.5,30.8,49.5,31.1,49.4,31.3z M48.7,30.1 + c0,0.1-0.1,0.2-0.2,0.3c-0.1,0-0.2-0.1-0.2-0.1c-0.1-0.1,0-0.2,0-0.3c0.1-0.2,0.2-0.5,0.4-0.6c0.2,0,0.4,0.3,0.6,0.3 + c0.1,0.1,0.1,0.2,0.1,0.3C49.1,30.1,48.8,29.8,48.7,30.1z M48.7,28.4c0.1,0,0.3,0,0.4,0.1c0.1,0.1,0.1,0.3,0.3,0.5 + c0,0.1,0,0.2-0.1,0.2c-0.4,0.1-0.4-0.4-0.8-0.3c-0.1,0.1-0.3,0.3-0.4,0.5c-0.1,0-0.1,0.1-0.2,0.1c-0.1-0.1-0.2-0.2-0.2-0.3 + C47.9,28.8,48.2,28.4,48.7,28.4z M47.9,30c0,0.1,0.1,0.3,0,0.4c-0.2,0-0.5,0-0.6,0.3c-0.1,0.1-0.1,0.3-0.3,0.4 + c-0.1-0.1-0.2-0.2-0.3-0.4c0.1-0.2,0.2-0.5,0.3-0.7c0,0,0.1-0.1,0.1-0.1C47.5,29.9,47.7,30.1,47.9,30z M46.6,28.8 + c0.2,0,0.4,0,0.6,0.2c0.1,0.1,0.2,0.3,0.3,0.3c0.1,0,0.1,0.1,0.1,0.2c-0.1,0.1-0.2,0-0.3,0c-0.2,0-0.5-0.3-0.7,0.1 + c-0.1,0.1-0.1,0.3-0.2,0.3c-0.1-0.1-0.2-0.3-0.2-0.5C46.3,29.2,46.4,28.9,46.6,28.8z M41.5,28.9c0-0.3,0-0.5,0-0.8 + c0,0,0.1-0.1,0.1-0.1c0.3-0.1,0.2,0.3,0.4,0.4c0.1,0.3,0.4,0.6,0.7,0.6c0.6,0,1.2-0.1,1.8,0.1c0.4,0.1,0.8,0.4,1.1,0.8 + c0.1,0,0.1-0.1,0.2-0.1c0.1,0.1,0.4,0.2,0.3,0.4c0.3,0,0.4,0.4,0.7,0.6c-0.2,0.2,0.5,0.5-0.1,0.5c-0.4-0.2-0.8,0.1-1.2,0.1 + c-0.1,0-0.2,0-0.3-0.1l0-0.1c0.2-0.2,0.5-0.3,0.8-0.3c0.1,0,0-0.2,0.2-0.1c0.1,0.1,0.1,0.2,0.2,0.2c0,0,0-0.1,0-0.1 + c-0.2,0-0.2-0.3-0.4-0.3c-0.2,0-0.3,0-0.4-0.2c-0.1-0.3-0.4-0.4-0.6-0.5c-0.1-0.1-0.2-0.1-0.3-0.1c-0.1,0.1-0.1,0.1-0.1,0.2 + c0.2,0.3,0.4,0.6,0.7,0.8v0c-0.3,0-0.5-0.4-0.7-0.3c0,0-0.1,0.1,0,0.2c0.1,0.2,0.4,0.4,0.2,0.6c-0.2,0-0.3-0.2-0.4-0.3 + c0-0.3-0.3-0.3-0.5-0.4c-0.2-0.1-0.4,0-0.7,0c-0.2-0.1-0.4,0.1-0.6-0.1C42,30.2,41.5,29.6,41.5,28.9z M41.3,40 + c0.1-0.4,0-0.8,0.3-1.1c0.2,0,0.1,0.3,0.1,0.4c0.1,0.3,0.1,0.7,0.2,1c-0.1,0.2-0.3,0.3-0.5,0.3C41.2,40.5,41.3,40.2,41.3,40z + M43,39.5c0.1-0.1,0.2-0.1,0.2,0c0,0.3-0.1,0.6-0.2,0.9c-0.3,0.4-0.4,0.9-0.7,1.3c-0.2,0.1-0.4,0.4-0.7,0.4 + c-0.1-0.2-0.3-0.4-0.3-0.7C41.9,40.8,42.6,40.2,43,39.5z M41.8,43.2c-0.1,0.1-0.2,0.2-0.4,0.1c0-0.2-0.1-0.6,0.1-0.7 + c0.1-0.1,0.3-0.3,0.4-0.1C42,42.8,42,43.1,41.8,43.2z M42.2,43.1c0.3-0.4,0.7-0.7,0.9-1.2c0,0,0.1-0.1,0.1-0.1 + c-0.1,0.8-0.4,1.6-0.9,2.2c-0.2,0.3-0.6,0.4-0.9,0.5c-0.1,0-0.2-0.1-0.2-0.2c0-0.1-0.1-0.2-0.1-0.3C41.5,43.8,41.9,43.5,42.2,43.1z + M40.1,42.7c0-0.3,0.1-0.5,0.4-0.7c0.1-0.1,0.3-0.2,0.5-0.2l0.2,0.3c0,0.4-0.4,0.5-0.7,0.8c-0.1,0-0.1,0.1-0.2,0.1 + C40.1,42.9,40.1,42.8,40.1,42.7z M40.3,46.6c-0.1,0-0.2-0.1-0.3-0.1c-0.1-0.1-0.2-0.3-0.2-0.5c0.1-0.2,0.4-0.3,0.5-0.5 + c0.3-0.2,0.5-0.5,0.8-0.8c0.1,0,0.3-0.1,0.4,0C41.3,45.4,40.9,46,40.3,46.6z M42.1,56c-0.4-1.3-0.8-2.6-1-4 + c-0.2-1.2-0.3-2.4-0.5-3.6c0.1-0.5,0-1.1,0-1.6c0.1-0.2,0.3-0.3,0.5-0.4c0,0,0.1,0,0.1,0c0,0.9,0.2,1.7,0.2,2.6 + c0.1,0.7,0.2,1.4,0.2,2c0,0.7,0.1,1.4,0.1,2.1c0.1,0.8,0.2,1.5,0.3,2.2C42,55.6,42.1,55.8,42.1,56L42.1,56z M42.4,55 + c-0.1-0.6-0.1-1.3-0.2-1.9c-0.2-1.2-0.2-2.5-0.3-3.7c-0.1-0.3-0.1-0.7-0.1-1.1c-0.1-0.8-0.1-1.6-0.2-2.3c-0.1-0.5,0.1-0.9,0.2-1.2 + c0.1-0.1,0.3-0.3,0.4-0.2c0.1,0.8,0,1.6,0.1,2.4c0.1,0.3,0.1,0.7,0.1,1c0.1,1.3,0.1,2.5,0.3,3.7c0.2,1.7,0.4,3.4,0.6,5.2 + c0.1,0.6,0.2,1.2,0.3,1.9c0,0-0.1,0.1-0.1,0C42.9,57.6,42.6,56.3,42.4,55z M56.5,55.4c-0.2,0.9-0.3,1.8-0.6,2.7 + c0,0.3-0.1,0.6-0.2,0.8c0,0-0.1,0-0.1,0c0-0.7,0.3-1.2,0.3-1.8c0.1-0.5,0.1-1,0.2-1.5c0.1-0.7,0.1-1.3,0.1-2 + c0.1-0.2,0.1-0.5,0.1-0.7c-0.1-0.5,0.1-1,0.1-1.5c0.1-0.5,0.2-1.1,0.2-1.6c0.1-1,0.2-1.9,0.2-2.9c0.1-0.3,0-0.7,0.1-0.9 + c0-0.3,0-0.5,0-0.8c0.1-0.2-0.2-0.7,0.2-0.8c0.1,0.1,0.3,0.2,0.4,0.3c0,0.3-0.1,0.6-0.1,0.9c0,0.5-0.1,1-0.1,1.6 + c0,0.8,0,1.5-0.1,2.2c-0.1,0.9-0.2,1.8-0.3,2.6C56.9,53.1,56.7,54.2,56.5,55.4z M58.7,45.9c-0.1,0.6,0,1.1-0.1,1.7 + c0,0.5-0.2,1-0.2,1.5c0,0.8-0.3,1.5-0.3,2.3c-0.1,0.8-0.3,1.5-0.5,2.3c-0.2,0.9-0.5,1.8-0.8,2.6c0,0-0.1,0-0.1,0 + c0.1-0.8,0.3-1.7,0.4-2.5c0.2-1,0.4-2.1,0.6-3.1c0.1-0.8,0.1-1.6,0.2-2.4c0.1-1,0.2-2,0.3-2.9c0.1-0.1,0.3,0.1,0.4,0.1 + C58.7,45.6,58.7,45.7,58.7,45.9z M59.3,45.4c-0.5-0.4-1-0.7-1.3-1.2c-0.1-0.1-0.2-0.3-0.2-0.5c0.1-0.1,0.1-0.2,0.2-0.1 + c0.2,0,0.3,0.3,0.6,0.3c0.1,0.1,0.1,0.2,0.1,0.3c0.2,0.2,0.5,0.5,0.7,0.7c0.1,0.1,0.2,0.2,0.1,0.4C59.5,45.3,59.4,45.5,59.3,45.4z" + /> + <path class="st0" d="M42.1,29.1c0.2,0.2,0.5,0.2,0.8,0.2c0.3,0.1,0.6,0,0.8,0.2c0.1,0.1,0.3,0.2,0.3,0.5L44,30 + c-0.6-0.3-1.3,0-1.8-0.5c-0.2,0-0.3-0.2-0.3-0.4c0-0.1,0-0.1,0-0.2C42,28.9,42,29.1,42.1,29.1z"/> + <path class="st0" d="M57.4,29c0,0.2-0.1,0.3-0.3,0.4c-0.5,0.3-1.2,0.5-1.9,0.4c0,0,0-0.1,0-0.1c0.4-0.1,0.9-0.2,1.3-0.4 + C56.7,29.2,57,29,57.4,29L57.4,29z"/> + <path class="st0" d="M45.2,33.9c-0.1,0-0.8,1.1-0.1,1.7c0.9,0.8,2-0.6,1.8-0.9c-0.1,0-0.4,0.8-1.2,0.6 + C44.8,35.1,45.3,33.9,45.2,33.9z"/> + <path class="st0" d="M52.5,35.4c0,0.3,1.1,0.8,1.7,0.1c0.7-1.1-0.3-1.7-0.6-1.4c-0.1,0.1,0.6,0.4,0.3,1.1 + C53.4,35.9,52.5,35.2,52.5,35.4z"/> + <path class="st0" d="M111.3,50.5c0,3.2-1.1,5.5-4.1,5.5c-3.2,0-4.2-2.2-4.2-5.5V46c0-2.2,0-2.5,1.2-2.6l0.5,0 + c0.1-0.1,0.1-0.4,0-0.5c-1,0-1.7,0.1-2.5,0.1c-0.8,0-1.5,0-2.6-0.1c-0.1,0.1-0.2,0.4,0,0.5l0.5,0c1.2,0.1,1.2,0.5,1.2,2.6v4.9 + c0,2.5,0.5,4,1.6,4.9c1,0.9,2.4,1.1,3.9,1.1c1.5,0,3.1-0.5,4-1.5c1.2-1.2,1.5-3.2,1.5-5v-2.3c0-1.2,0-3.5,0.3-4.2 + c0.1-0.3,0.5-0.5,1-0.5l0.5,0c0.1-0.1,0.1-0.4,0-0.5c-0.7,0-1.3,0.1-2.2,0.1c-0.8,0-1.6,0-2.4-0.1c-0.1,0.1-0.2,0.4,0,0.5l0.5,0 + c0.5,0,0.9,0.2,1,0.4c0.4,0.6,0.4,3,0.4,4.3V50.5z M131.1,48.1c0-1,0-3.5,0.3-4.3c0.1-0.2,0.5-0.3,1.2-0.4l0.3,0 + c0.1-0.1,0.1-0.4,0-0.5c-0.7,0-1.2,0.1-2.1,0.1c-0.8,0-1.5,0-2.4-0.1c-0.2,0.1-0.2,0.4,0,0.5l0.4,0c0.8,0.1,1.2,0.2,1.3,0.4 + c0.4,0.6,0.4,3.3,0.4,4.3v4.4c0,0.4,0,0.8-0.1,0.9h0c-1-1-2-2.2-3.4-3.8l-2-2.3c-0.7-0.8-3.1-3.5-3.5-4.6c-0.3,0-0.6,0.1-1,0.1 + c-0.4,0-1.5,0-2.3-0.1c-0.2,0.1-0.2,0.4,0,0.5l0.4,0c0.5,0.1,1,0.2,1.3,0.5c0.4,0.5,0.5,0.9,0.5,1.5v6c0,1,0,3.5-0.3,4.3 + c-0.1,0.2-0.4,0.4-0.9,0.4l-0.6,0.1c-0.1,0.1-0.1,0.4,0,0.5c0.7,0,1.3-0.1,2.2-0.1c0.8,0,1.5,0,2.4,0.1c0.1-0.1,0.2-0.4,0-0.5 + l-0.6-0.1c-0.5,0-0.9-0.2-1.1-0.4c-0.4-0.6-0.4-3.3-0.4-4.3v-4.5c0-0.6,0-1.1,0.1-1.3h0c0.4,0.5,1.8,2.2,2.4,2.8l4.8,5.5 + c1.8,2.1,2.4,2.8,2.7,3.1c0.2,0,0.4-0.1,0.4-0.2c-0.1-0.5-0.1-3-0.1-3.6V48.1z M139.3,53.4c0,2.2,0,2.5-1.3,2.6l-0.5,0.1 + c-0.1,0.1-0.1,0.5,0,0.5c1,0,1.7-0.1,2.6-0.1c0.8,0,1.5,0,2.6,0.1c0.1-0.1,0.2-0.4,0-0.5l-0.5-0.1c-1.2-0.1-1.3-0.4-1.3-2.6V46 + c0-2.2,0-2.6,1.3-2.7l0.5,0c0.1-0.1,0.1-0.5,0-0.5c-1,0-1.7,0.1-2.6,0.1c-0.9,0-1.6,0-2.6-0.1c-0.1,0.1-0.2,0.4,0,0.5l0.5,0 + c1.2,0.1,1.3,0.5,1.3,2.7V53.4z M152.5,54.1c0.4,0.9,0.7,1.9,1,2.8c0.1,0,0.2,0.1,0.3,0.1c0.1,0,0.2,0,0.2-0.1 + c0.4-1.1,1.3-3.5,2.2-5.4l1.1-2.6c0.9-2.1,1.7-3.8,2.3-4.8c0.3-0.4,0.6-0.7,1.1-0.7l0.6,0c0.1-0.1,0.1-0.4,0-0.5 + c-0.7,0-1.3,0.1-2,0.1c-0.8,0-1.6,0-2.2-0.1c-0.1,0.1-0.2,0.4,0,0.5l0.4,0c0.7,0.1,0.9,0.2,0.9,0.4c0,0.1,0,0.4-0.2,0.8 + c-0.4,0.9-1.3,3.2-1.9,4.6c-0.5,1.1-1.3,3.2-2,4.6c-1-2.4-2-4.7-2.9-7.2c-0.6-1.6-1-2.7-1-2.9c0-0.2,0.2-0.3,1-0.4l0.3,0 + c0.1-0.1,0.1-0.4,0-0.5c-0.9,0-1.6,0.1-2.5,0.1c-0.9,0-1.6,0-2.2-0.1c-0.2,0.1-0.2,0.4,0,0.5l0.4,0c0.9,0.1,1.2,0.5,1.7,1.7 + L152.5,54.1z M166.5,53.4c0,2.2-0.1,2.5-1.3,2.6l-0.7,0.1c-0.1,0.1-0.1,0.5,0,0.5c1.2,0,1.9-0.1,2.8-0.1h1.9c1.8,0,3.7,0,5.6,0.1 + c0.3-0.6,0.8-2.2,0.9-2.9c-0.1-0.2-0.4-0.2-0.5-0.1c-0.5,1.1-1.1,1.8-1.5,2c-0.5,0.2-1.1,0.3-2.7,0.3c-1.8,0-2.3-0.2-2.5-0.5 + c-0.3-0.4-0.4-1.1-0.4-2.2v-2.9c0-0.5,0.1-0.6,0.7-0.6h1.2c0.8,0,1.3,0,1.6,0.1c0.4,0.1,0.6,0.4,0.6,0.8l0.2,0.8 + c0.1,0.1,0.5,0.1,0.5,0c0-0.5-0.1-1.2-0.1-2c0-0.8,0.1-1.6,0.1-2.1c-0.1-0.1-0.4-0.1-0.5,0l-0.2,0.8c-0.1,0.5-0.2,0.6-0.5,0.7 + c-0.2,0.1-0.9,0.1-1.8,0.1h-1.2c-0.6,0-0.7,0-0.7-0.6v-4.1c0-0.8,0-0.8,0.6-0.8h1.5c0.9,0,1.6,0,2,0.1c1.1,0.3,1.3,1,1.6,2 + c0.1,0.1,0.4,0.1,0.5,0c-0.1-0.9-0.2-2.4-0.3-2.8c-0.2,0.1-1.5,0.1-2.8,0.1h-3.9c-0.9,0-1.6,0-2.4-0.1c-0.1,0.1-0.2,0.4,0,0.5 + l0.3,0c1.2,0.1,1.3,0.5,1.3,2.6V53.4z M181.8,53.4c0,2.2,0,2.4-1.2,2.6l-0.5,0.1c-0.1,0.1-0.1,0.5,0,0.5c1,0,1.7-0.1,2.6-0.1 + c0.8,0,1.5,0,2.5,0.1c0.1-0.1,0.2-0.4,0-0.5l-0.4-0.1c-1.2-0.2-1.2-0.4-1.2-2.6v-2.6c0-0.4,0-0.5,1-0.5c0.8,0,1.2,0.2,1.5,0.7 + c0.6,0.9,1.5,2.4,2,3.1c1.5,2.1,2.5,2.6,4.3,2.6c0.4,0,0.7,0,0.9-0.1c0.1-0.1,0.1-0.2,0-0.3c-0.6,0-1.1-0.3-1.4-0.6 + c-1.4-1.2-2.5-2.8-4.2-5.5c-0.1-0.2-0.2-0.4-0.1-0.5c1-0.4,2.6-1.5,2.6-3.5c0-1.5-0.7-2.4-1.7-2.9c-1-0.5-2.2-0.6-3.5-0.6 + c-2,0-3.5,0.1-4.6,0.2c-0.2,0.1-0.2,0.4,0,0.5l0.7,0.1c0.9,0.1,0.9,0.5,0.9,2.4V53.4z M183.5,44.1c0-0.6,0.1-0.7,1.3-0.7 + c2.3,0,3.3,1.6,3.3,3.2c0,1.4-0.5,2.1-1,2.6c-0.6,0.5-1.4,0.5-2.1,0.5c-1.1,0-1.4,0-1.4-0.1c-0.1-0.1-0.1-0.3-0.1-0.7V44.1z + M204.6,53.1c0-2-1.3-3.2-2.6-4l-1.7-1c-0.8-0.5-1.8-1.3-1.8-2.6c0-1,0.4-2.3,2.5-2.3c2,0,2.6,1.3,2.8,2.3c0.1,0.1,0.4,0.1,0.5-0.1 + c0-0.9-0.2-2-0.4-2.5c-0.2,0-0.5,0-0.7-0.1c-0.5-0.1-1.3-0.3-1.9-0.3c-2.7,0-4.2,1.6-4.2,3.6c0,1.7,1.2,2.9,2.2,3.6l2,1.3 + c1.5,1,1.7,2,1.7,2.9c0,1.2-0.9,2.4-2.6,2.4c-2.4,0-3.3-2-3.6-3.1c-0.1-0.1-0.4-0.1-0.5,0.1c0,1,0.3,2.4,0.6,2.9 + c0.4,0.2,1.5,0.8,3.2,0.8C202.9,56.9,204.6,55.3,204.6,53.1z M211.5,53.4c0,2.2,0,2.5-1.3,2.6l-0.5,0.1c-0.1,0.1-0.1,0.5,0,0.5 + c1,0,1.7-0.1,2.6-0.1c0.8,0,1.5,0,2.6,0.1c0.1-0.1,0.2-0.4,0-0.5l-0.5-0.1c-1.2-0.1-1.3-0.4-1.3-2.6V46c0-2.2,0-2.6,1.3-2.7l0.5,0 + c0.1-0.1,0.1-0.5,0-0.5c-1,0-1.7,0.1-2.6,0.1c-0.9,0-1.6,0-2.6-0.1c-0.1,0.1-0.2,0.4,0,0.5l0.5,0c1.2,0.1,1.3,0.5,1.3,2.7V53.4z + M226.6,44.2c0-0.7,0-0.7,0.6-0.7h1.5c1.1,0,1.9,0.2,2.4,0.5c0.3,0.2,0.5,1,0.5,1.5c0.1,0.1,0.5,0.1,0.5,0 + c-0.1-0.6,0.1-2.3,0.3-3.2c0-0.1-0.3-0.1-0.4-0.1c-0.3,0.5-0.5,0.6-1.6,0.6H222c-1,0-1.6,0-1.8-0.6c-0.1-0.1-0.3,0-0.4,0 + c-0.1,0.8-0.5,2.2-0.8,3.1c0.1,0.2,0.4,0.3,0.5,0.1c0.2-0.5,0.4-1,0.9-1.4c0.5-0.5,1.7-0.5,2.6-0.5h1.1c0.6,0,0.6,0,0.6,0.7v9.3 + c0,2.2-0.1,2.5-1.3,2.6l-0.7,0.1c-0.2,0.1-0.1,0.5,0,0.5c1.3,0,2.1-0.1,2.9-0.1c0.8,0,1.5,0,2.7,0.1c0.1-0.1,0.2-0.4,0-0.5 + l-0.7-0.1c-1.2-0.1-1.2-0.4-1.2-2.6V44.2z M238.4,53.4c0,2.2-0.1,2.5-1.3,2.6l-0.7,0.1c-0.1,0.1-0.1,0.5,0,0.5 + c1.2,0,1.9-0.1,2.8-0.1h1.9c1.8,0,3.7,0,5.6,0.1c0.3-0.6,0.8-2.2,0.9-2.9c-0.1-0.2-0.4-0.2-0.5-0.1c-0.5,1.1-1.1,1.8-1.5,2 + c-0.5,0.2-1.1,0.3-2.7,0.3c-1.8,0-2.3-0.2-2.5-0.5c-0.3-0.4-0.4-1.1-0.4-2.2v-2.9c0-0.5,0.1-0.6,0.7-0.6h1.2c0.8,0,1.3,0,1.6,0.1 + c0.4,0.1,0.6,0.4,0.6,0.8l0.2,0.8c0.1,0.1,0.5,0.1,0.5,0c0-0.5-0.1-1.2-0.1-2c0-0.8,0.1-1.6,0.1-2.1c-0.1-0.1-0.4-0.1-0.5,0 + l-0.2,0.8c-0.1,0.5-0.2,0.6-0.5,0.7c-0.2,0.1-0.9,0.1-1.8,0.1h-1.2c-0.6,0-0.7,0-0.7-0.6v-4.1c0-0.8,0-0.8,0.6-0.8h1.5 + c0.9,0,1.6,0,2,0.1c1.1,0.3,1.3,1,1.6,2c0.1,0.1,0.4,0.1,0.5,0c-0.1-0.9-0.2-2.4-0.3-2.8c-0.2,0.1-1.5,0.1-2.8,0.1h-3.9 + c-0.9,0-1.6,0-2.4-0.1c-0.1,0.1-0.2,0.4,0,0.5l0.3,0c1.2,0.1,1.3,0.5,1.3,2.6V53.4z M258.6,44.2c0-0.7,0-0.7,0.6-0.7h1.5 + c1.1,0,1.9,0.2,2.4,0.5c0.3,0.2,0.5,1,0.5,1.5c0.1,0.1,0.5,0.1,0.5,0c-0.1-0.6,0.1-2.3,0.3-3.2c0-0.1-0.3-0.1-0.4-0.1 + c-0.3,0.5-0.5,0.6-1.6,0.6h-8.4c-1,0-1.6,0-1.8-0.6c-0.1-0.1-0.3,0-0.4,0c-0.1,0.8-0.5,2.2-0.8,3.1c0.1,0.2,0.4,0.3,0.5,0.1 + c0.2-0.5,0.4-1,0.9-1.4c0.5-0.5,1.7-0.5,2.6-0.5h1.1c0.6,0,0.6,0,0.6,0.7v9.3c0,2.2-0.1,2.5-1.3,2.6l-0.7,0.1 + c-0.2,0.1-0.1,0.5,0,0.5c1.3,0,2.1-0.1,2.9-0.1c0.8,0,1.5,0,2.7,0.1c0.1-0.1,0.2-0.4,0-0.5l-0.7-0.1c-1.2-0.1-1.2-0.4-1.2-2.6V44.2 + z M270.4,53.4c0,2.2-0.1,2.5-1.3,2.6l-0.7,0.1c-0.1,0.1-0.1,0.5,0,0.5c1.2,0,1.9-0.1,2.8-0.1h1.9c1.8,0,3.7,0,5.6,0.1 + c0.3-0.6,0.8-2.2,0.9-2.9c-0.1-0.2-0.4-0.2-0.5-0.1c-0.5,1.1-1.1,1.8-1.5,2c-0.5,0.2-1.1,0.3-2.7,0.3c-1.8,0-2.3-0.2-2.5-0.5 + c-0.3-0.4-0.4-1.1-0.4-2.2v-2.9c0-0.5,0.1-0.6,0.7-0.6h1.2c0.8,0,1.3,0,1.6,0.1c0.4,0.1,0.6,0.4,0.6,0.8l0.2,0.8 + c0.1,0.1,0.5,0.1,0.5,0c0-0.5-0.1-1.2-0.1-2c0-0.8,0.1-1.6,0.1-2.1c-0.1-0.1-0.4-0.1-0.5,0l-0.2,0.8c-0.1,0.5-0.2,0.6-0.5,0.7 + c-0.2,0.1-0.9,0.1-1.8,0.1h-1.2c-0.6,0-0.7,0-0.7-0.6v-4.1c0-0.8,0-0.8,0.6-0.8h1.5c0.9,0,1.6,0,2,0.1c1.1,0.3,1.3,1,1.6,2 + c0.1,0.1,0.4,0.1,0.5,0c-0.1-0.9-0.2-2.4-0.3-2.8c-0.2,0.1-1.5,0.1-2.8,0.1h-3.9c-0.8,0-1.6,0-2.4-0.1c-0.1,0.1-0.2,0.4,0,0.5 + l0.3,0c1.2,0.1,1.3,0.5,1.3,2.6V53.4z M290.6,44.2c0-0.7,0-0.7,0.6-0.7h1.5c1.1,0,1.9,0.2,2.4,0.5c0.3,0.2,0.5,1,0.5,1.5 + c0.1,0.1,0.5,0.1,0.5,0c-0.1-0.6,0.1-2.3,0.3-3.2c0-0.1-0.3-0.1-0.4-0.1c-0.3,0.5-0.5,0.6-1.6,0.6h-8.4c-1,0-1.6,0-1.8-0.6 + c-0.1-0.1-0.3,0-0.4,0c-0.1,0.8-0.5,2.2-0.8,3.1c0.1,0.2,0.4,0.3,0.5,0.1c0.2-0.5,0.4-1,0.9-1.4c0.5-0.5,1.7-0.5,2.6-0.5h1.1 + c0.6,0,0.6,0,0.6,0.7v9.3c0,2.2-0.1,2.5-1.3,2.6l-0.7,0.1c-0.2,0.1-0.1,0.5,0,0.5c1.3,0,2.1-0.1,2.9-0.1c0.8,0,1.5,0,2.7,0.1 + c0.1-0.1,0.2-0.4,0-0.5l-0.7-0.1c-1.2-0.1-1.2-0.4-1.2-2.6V44.2z M310.7,53.4c0,2.2,0,2.5-1.3,2.6l-0.5,0.1c-0.1,0.1-0.1,0.5,0,0.5 + c1,0,1.7-0.1,2.6-0.1c0.8,0,1.5,0,2.6,0.1c0.1-0.1,0.2-0.4,0-0.5l-0.5-0.1c-1.2-0.1-1.3-0.4-1.3-2.6V46c0-2.2,0-2.6,1.3-2.7l0.5,0 + c0.1-0.1,0.1-0.5,0-0.5c-1,0-1.7,0.1-2.6,0.1c-0.9,0-1.6,0-2.6-0.1c-0.1,0.1-0.2,0.4,0,0.5l0.5,0c1.2,0.1,1.3,0.5,1.3,2.7V53.4z + M329.1,53.4c0,2.2,0,2.4-1.1,2.6l-0.4,0.1c-0.1,0.1-0.1,0.5,0,0.5c0.8,0,1.5-0.1,2.4-0.1c0.9,0,1.9,0.1,2.5,0.1 + c3.7,0,5.5-1.6,5.5-4c0-2.2-1.7-3.3-2.8-3.5c-0.2,0-0.4-0.1-0.4-0.3c1.2-0.6,2.1-1.3,2.1-2.8c0-1.3-0.7-2.2-1.6-2.6 + c-0.9-0.5-2.2-0.6-3.5-0.6c-1.9,0-3.3,0.1-4.5,0.2c-0.2,0.1-0.2,0.4,0,0.5l0.7,0.1c0.9,0.1,1,0.5,1,2V53.4z M330.8,50.1 + c0-0.4,0.1-0.5,1.2-0.5c3.3,0,4.1,1.9,4.1,3.5c0,2.1-1.4,2.9-3.3,2.9c-0.6,0-1.2-0.1-1.6-0.6c-0.4-0.5-0.4-1.5-0.4-2.3V50.1z + M330.8,44.1c0-0.4,0.1-0.5,0.3-0.5c0.2-0.1,0.5-0.1,1-0.1c1.6,0,3.1,0.8,3.1,2.8c0,2-1.1,2.6-3.3,2.7c-1.1,0-1.1,0-1.1-0.6V44.1z + M344.8,53.4c0,2.2-0.1,2.5-1.3,2.6l-0.7,0.1c-0.1,0.1-0.1,0.5,0,0.5c1.2,0,1.9-0.1,2.8-0.1h1.9c1.8,0,3.7,0,5.6,0.1 + c0.3-0.6,0.8-2.2,0.9-2.9c-0.1-0.2-0.4-0.2-0.5-0.1c-0.5,1.1-1.1,1.8-1.5,2c-0.5,0.2-1.1,0.3-2.7,0.3c-1.8,0-2.3-0.2-2.5-0.5 + c-0.3-0.4-0.4-1.1-0.4-2.2v-2.9c0-0.5,0.1-0.6,0.7-0.6h1.2c0.8,0,1.3,0,1.6,0.1c0.4,0.1,0.6,0.4,0.6,0.8l0.2,0.8 + c0.1,0.1,0.5,0.1,0.5,0c0-0.5-0.1-1.2-0.1-2c0-0.8,0.1-1.6,0.1-2.1c-0.1-0.1-0.4-0.1-0.5,0l-0.2,0.8c-0.1,0.5-0.2,0.6-0.5,0.7 + c-0.2,0.1-0.9,0.1-1.8,0.1h-1.2c-0.6,0-0.7,0-0.7-0.6v-4.1c0-0.8,0-0.8,0.6-0.8h1.5c0.9,0,1.6,0,2,0.1c1.1,0.3,1.3,1,1.6,2 + c0.1,0.1,0.4,0.1,0.5,0c-0.1-0.9-0.2-2.4-0.3-2.8c-0.2,0.1-1.5,0.1-2.8,0.1h-3.9c-0.8,0-1.6,0-2.4-0.1c-0.1,0.1-0.2,0.4,0,0.5 + l0.3,0c1.2,0.1,1.3,0.5,1.3,2.6V53.4z M360,53.4c0,2.2,0,2.4-1.2,2.6l-0.5,0.1c-0.1,0.1-0.1,0.5,0,0.5c1,0,1.7-0.1,2.6-0.1 + c0.8,0,1.5,0,2.5,0.1c0.1-0.1,0.2-0.4,0-0.5l-0.4-0.1c-1.2-0.2-1.2-0.4-1.2-2.6v-2.6c0-0.4,0-0.5,1-0.5c0.8,0,1.2,0.2,1.5,0.7 + c0.6,0.9,1.5,2.4,2,3.1c1.5,2.1,2.5,2.6,4.3,2.6c0.4,0,0.7,0,0.9-0.1c0.1-0.1,0.1-0.2,0-0.3c-0.6,0-1.1-0.3-1.4-0.6 + c-1.4-1.2-2.5-2.8-4.2-5.5c-0.1-0.2-0.2-0.4-0.1-0.5c1-0.4,2.6-1.5,2.6-3.5c0-1.5-0.7-2.4-1.7-2.9c-1-0.5-2.2-0.6-3.5-0.6 + c-2,0-3.5,0.1-4.6,0.2c-0.2,0.1-0.2,0.4,0,0.5l0.7,0.1c0.9,0.1,0.9,0.5,0.9,2.4V53.4z M361.7,44.1c0-0.6,0.1-0.7,1.3-0.7 + c2.3,0,3.3,1.6,3.3,3.2c0,1.4-0.5,2.1-1,2.6c-0.6,0.5-1.4,0.5-2.1,0.5c-1.1,0-1.4,0-1.4-0.1c-0.1-0.1-0.1-0.3-0.1-0.7V44.1z + M386.5,53.3c0-1.1,0-1.6,0.9-1.7l0.3,0c0.1-0.1,0.1-0.4,0-0.5c-0.7,0-1.4,0.1-2.2,0.1c-1.2,0-2.4,0-3-0.1c-0.1,0.1-0.2,0.4,0,0.5 + l0.9,0.1c1.3,0.1,1.3,0.3,1.3,2v0.8c0,0.7-0.1,1-0.2,1.2c-0.2,0.4-1,0.6-2.3,0.6c-4.2,0-6.2-3.1-6.2-7.1c0-3.1,1.8-6,5.8-6 + c2.1,0,3.7,0.7,4.2,2.9c0.1,0.1,0.5,0.1,0.6-0.1c-0.2-1.2-0.3-2.3-0.3-3c-0.2,0-0.9-0.1-1.3-0.2c-0.4-0.1-1.4-0.3-2.6-0.3 + c-3.1,0-5.2,1-6.6,2.4c-1.3,1.4-1.9,3.2-1.9,4.9c0,1.8,0.7,3.5,1.9,4.7c1.6,1.6,3.9,2.3,6.3,2.3c1.1,0,2.6-0.2,3.7-0.5 + c0.4-0.1,0.8-0.2,1-0.2c0.1-0.1,0.1-0.2,0-0.2c-0.4-0.1-0.5-0.6-0.5-1.5V53.3z M394.3,53.4c0,2.2-0.1,2.5-1.3,2.6l-0.7,0.1 + c-0.1,0.1-0.1,0.5,0,0.5c1.2,0,1.9-0.1,2.8-0.1h1.9c1.8,0,3.7,0,5.6,0.1c0.3-0.6,0.8-2.2,0.9-2.9c-0.1-0.2-0.4-0.2-0.5-0.1 + c-0.5,1.1-1.1,1.8-1.5,2c-0.5,0.2-1.1,0.3-2.7,0.3c-1.8,0-2.3-0.2-2.5-0.5c-0.3-0.4-0.4-1.1-0.4-2.2v-2.9c0-0.5,0.1-0.6,0.7-0.6 + h1.2c0.8,0,1.3,0,1.6,0.1c0.4,0.1,0.6,0.4,0.6,0.8l0.2,0.8c0.1,0.1,0.5,0.1,0.5,0c0-0.5-0.1-1.2-0.1-2c0-0.8,0.1-1.6,0.1-2.1 + c-0.1-0.1-0.4-0.1-0.5,0l-0.2,0.8c-0.1,0.5-0.2,0.6-0.5,0.7c-0.2,0.1-0.9,0.1-1.8,0.1h-1.2c-0.6,0-0.7,0-0.7-0.6v-4.1 + c0-0.8,0-0.8,0.6-0.8h1.5c0.9,0,1.6,0,2,0.1c1.1,0.3,1.3,1,1.6,2c0.1,0.1,0.4,0.1,0.5,0c-0.1-0.9-0.2-2.4-0.3-2.8 + c-0.2,0.1-1.5,0.1-2.8,0.1h-3.9c-0.8,0-1.6,0-2.4-0.1c-0.1,0.1-0.2,0.4,0,0.5l0.3,0c1.2,0.1,1.3,0.5,1.3,2.6V53.4z M420.7,48.1 + c0-1,0-3.5,0.3-4.3c0.1-0.2,0.5-0.3,1.2-0.4l0.3,0c0.1-0.1,0.1-0.4,0-0.5c-0.7,0-1.2,0.1-2.1,0.1c-0.8,0-1.5,0-2.4-0.1 + c-0.2,0.1-0.2,0.4,0,0.5l0.4,0c0.8,0.1,1.2,0.2,1.3,0.4c0.4,0.6,0.4,3.3,0.4,4.3v4.4c0,0.4,0,0.8-0.1,0.9h0c-1-1-2-2.2-3.4-3.8 + l-2-2.3c-0.7-0.8-3.1-3.5-3.5-4.6c-0.3,0-0.6,0.1-1,0.1c-0.4,0-1.5,0-2.3-0.1c-0.2,0.1-0.2,0.4,0,0.5l0.4,0c0.5,0.1,1,0.2,1.3,0.5 + c0.4,0.5,0.5,0.9,0.5,1.5v6c0,1,0,3.5-0.3,4.3c-0.1,0.2-0.4,0.4-0.9,0.4l-0.6,0.1c-0.1,0.1-0.1,0.4,0,0.5c0.7,0,1.3-0.1,2.2-0.1 + c0.8,0,1.5,0,2.4,0.1c0.1-0.1,0.2-0.4,0-0.5l-0.6-0.1c-0.5,0-0.9-0.2-1.1-0.4c-0.4-0.6-0.4-3.3-0.4-4.3v-4.5c0-0.6,0-1.1,0.1-1.3h0 + c0.4,0.5,1.8,2.2,2.4,2.8l4.8,5.5c1.8,2.1,2.4,2.8,2.7,3.1c0.2,0,0.4-0.1,0.4-0.2c-0.1-0.5-0.1-3-0.1-3.6V48.1z"/> +</g> +<rect class="st1" width="439.4" height="99.2"/> +</svg> diff --git a/frontend/src/routes/components/logos/uio-logo-acronym-white.svg b/frontend/src/routes/components/logos/uio/uio-logo-acronym-white.svg similarity index 100% rename from frontend/src/routes/components/logos/uio-logo-acronym-white.svg rename to frontend/src/routes/components/logos/uio/uio-logo-acronym-white.svg diff --git a/frontend/src/routes/components/logos/uio-segl-full-neg-en.svg b/frontend/src/routes/components/logos/uio/uio-segl-full-neg-en.svg similarity index 100% rename from frontend/src/routes/components/logos/uio-segl-full-neg-en.svg rename to frontend/src/routes/components/logos/uio/uio-segl-full-neg-en.svg diff --git a/frontend/src/routes/components/logos/uio-segl-full-neg-no.svg b/frontend/src/routes/components/logos/uio/uio-segl-full-neg-no.svg similarity index 100% rename from frontend/src/routes/components/logos/uio-segl-full-neg-no.svg rename to frontend/src/routes/components/logos/uio/uio-segl-full-neg-no.svg diff --git a/frontend/src/routes/components/overviewGuestButton.tsx b/frontend/src/routes/components/overviewGuestButton.tsx index 4111268f812c1eef908d905f2edec4db7fe81b24..895f6a6c3a7df3abcd8fca6c4eb1620c5a5da849 100644 --- a/frontend/src/routes/components/overviewGuestButton.tsx +++ b/frontend/src/routes/components/overviewGuestButton.tsx @@ -6,7 +6,14 @@ import { useHistory } from 'react-router-dom' import ArrowBackIcon from '@mui/icons-material/ArrowBack' import ArrowForwardIcon from '@mui/icons-material/ArrowForward' -export default function OverviewGuestButton() { +interface OverviewGuestButtonProperties { + backArrow?: string +} + +export default function OverviewGuestButton( + properties: OverviewGuestButtonProperties +) { + const { backArrow } = properties const { t } = useTranslation(['common']) const history = useHistory() @@ -23,8 +30,15 @@ export default function OverviewGuestButton() { justifyContent: 'space-evenly', }} > - {/* TODO Where should the back arrow point to? */} - <ArrowBackIcon /> + {backArrow !== undefined ? ( + <ArrowBackIcon + onClick={() => { + history.push(backArrow) + }} + /> + ) : ( + <ArrowBackIcon visibility="hidden" /> + )} <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }} @@ -35,9 +49,9 @@ export default function OverviewGuestButton() { sx={{ borderRadius: '2rem', borderStyle: 'solid', - borderColor: 'primary.main', + borderColor: 'secondary.main', fill: 'white', - backgroundColor: 'primary.main', + backgroundColor: 'secondary.main', }} /> </IconButton> diff --git a/frontend/src/routes/components/sponsorGuestButtons.tsx b/frontend/src/routes/components/sponsorGuestButtons.tsx index ac290e105bee2aca2213036c3e9455552cbad579..e34b578c099d07bf2c60bba97e3f16318194ec7c 100644 --- a/frontend/src/routes/components/sponsorGuestButtons.tsx +++ b/frontend/src/routes/components/sponsorGuestButtons.tsx @@ -43,12 +43,12 @@ export default function SponsorGuestButtons(props: SponsorGuestButtonsProps) { borderStyle: 'solid', borderColor: (theme: Theme) => yourGuestsActive - ? theme.palette.primary.main + ? theme.palette.secondary.main : theme.greg.deactivatedColor, fill: 'white', backgroundColor: (theme: Theme) => yourGuestsActive - ? theme.palette.primary.main + ? theme.palette.secondary.main : theme.greg.deactivatedColor, }} /> @@ -73,12 +73,12 @@ export default function SponsorGuestButtons(props: SponsorGuestButtonsProps) { borderStyle: 'solid', borderColor: (theme: Theme) => registerNewGuestActive - ? theme.palette.primary.main + ? theme.palette.secondary.main : theme.greg.deactivatedColor, fill: 'white', backgroundColor: (theme: Theme) => registerNewGuestActive - ? theme.palette.primary.main + ? theme.palette.secondary.main : theme.greg.deactivatedColor, }} /> diff --git a/frontend/src/routes/components/sponsorInfoButtons.tsx b/frontend/src/routes/components/sponsorInfoButtons.tsx index ce50eb18df2b7452bd7c5c2d215de70ec2bbad73..f18be1b7e10b6d0e6b59b34c5bcf31a97c8aac4b 100644 --- a/frontend/src/routes/components/sponsorInfoButtons.tsx +++ b/frontend/src/routes/components/sponsorInfoButtons.tsx @@ -38,9 +38,9 @@ export default function SponsorInfoButtons({ sx={{ borderRadius: '2rem', borderStyle: 'solid', - borderColor: (theme: Theme) => theme.palette.primary.main, + borderColor: (theme: Theme) => theme.palette.secondary.main, fill: 'white', - backgroundColor: (theme: Theme) => theme.palette.primary.main, + backgroundColor: (theme: Theme) => theme.palette.secondary.main, }} /> <Box diff --git a/frontend/src/routes/guest/register/enteredGuestData.ts b/frontend/src/routes/guest/register/enteredGuestData.ts index cf5c8662c000dd2a24738d9bd0ba25162bd3fce1..45422db11b05ea077d3b062dbb537e852ec64a86 100644 --- a/frontend/src/routes/guest/register/enteredGuestData.ts +++ b/frontend/src/routes/guest/register/enteredGuestData.ts @@ -8,7 +8,8 @@ export type EnteredGuestData = { lastName: string mobilePhoneCountry: string mobilePhone: string - nationalIdNumber?: string - passportNumber?: string - passportNationality?: string + nationalIdNumber: string + passportNumber: string + passportNationality: string + dateOfBirth?: Date } diff --git a/frontend/src/routes/guest/register/guestDataForm.ts b/frontend/src/routes/guest/register/guestDataForm.ts index 09e7da4288e247fdf95e43dce5e164bd20956daa..0bc7a59b5f7ce0c41604a862e54364374e2607de 100644 --- a/frontend/src/routes/guest/register/guestDataForm.ts +++ b/frontend/src/routes/guest/register/guestDataForm.ts @@ -18,18 +18,17 @@ export type GuestInviteInformation = { feide_id?: string - // These fields are in the form, but it is not expected that - // they are set, with the exception of e-mail, when the guest - // first follows the invite link email?: string + // These fields are in the form, but it is not expected that + // they are set, when the guest first follows the invite link mobile_phone_country_code?: string mobile_phone?: string - fnr?: string passport?: string passportNationality?: string countryForCallingCode?: string + dateOfBirth?: Date authentication_method: AuthenticationMethod } diff --git a/frontend/src/routes/guest/register/guestRegisterMethods.tsx b/frontend/src/routes/guest/register/guestRegisterMethods.tsx deleted file mode 100644 index c4ac5c2e5706cd0f9355c90d52a0e1c225587d6b..0000000000000000000000000000000000000000 --- a/frontend/src/routes/guest/register/guestRegisterMethods.tsx +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Contains methods that GuestRegisterStep can call on in GuestRegister - */ -export interface GuestRegisterMethods { - handleNext: () => void -} diff --git a/frontend/src/routes/guest/register/index.test.tsx b/frontend/src/routes/guest/register/index.test.tsx index 8b264ad24fa70588adcf37ce9309716cae67086a..764b5739350f652d4c661f892b4a002123228175 100644 --- a/frontend/src/routes/guest/register/index.test.tsx +++ b/frontend/src/routes/guest/register/index.test.tsx @@ -1,6 +1,6 @@ import React from 'react' import fetchMock, { enableFetchMocks } from 'jest-fetch-mock' -import { render, waitFor, screen } from 'test-utils' +import { render, screen } from 'test-utils' import AdapterDateFns from '@mui/lab/AdapterDateFns' import { LocalizationProvider } from '@mui/lab' import GuestRegister from './index' @@ -9,12 +9,13 @@ enableFetchMocks() const testData = { person: { - first_name: 'Test', + first_name: 'Test20', last_name: 'Tester', mobile_phone: '+4797543910', email: 'test@example.org', fnr: '04062141242', - passport: 'NO-123456', + passport: 'DK-123456', + date_of_birth: '1995-02-25', }, role: { ou_name_en: 'English organizational unit name', @@ -23,7 +24,8 @@ const testData = { name_nb: 'Gjesterolle', start: '2021-08-10', end: '2021-08-16', - comment: '', + contact_person_unit: 'Test contact person', + comments: 'Test comment', }, meta: { session_type: 'invite', @@ -31,26 +33,38 @@ const testData = { } beforeEach(() => { - fetchMock.mockIf('/api/ui/v1/invited', () => + fetchMock.mockIf('/api/ui/v1/invited/', () => Promise.resolve<any>(JSON.stringify(testData)) ) }) -test('Mobile phone number parsed and split correctly', async () => { +test('Field showing values correctly', async () => { render( <LocalizationProvider dateAdapter={AdapterDateFns}> <GuestRegister /> </LocalizationProvider> ) - await waitFor(() => screen.queryByText(testData.person.first_name)) - await waitFor(() => screen.queryByText(testData.person.last_name)) - await waitFor(() => screen.queryByText(testData.person.email)) - await waitFor(() => screen.queryByText(testData.person.fnr)) - await waitFor(() => screen.queryByText('NO')) - await waitFor(() => screen.queryByText('123456')) + await screen.findByDisplayValue(testData.person.first_name) + await screen.findByDisplayValue(testData.person.last_name) + await screen.findByDisplayValue(testData.person.email) + await screen.findByDisplayValue(testData.person.fnr) - // There is no proper i18n loaded so the country name will be undefined, the country code should still show though - await waitFor(() => screen.queryByText('undefined (47)')) - await waitFor(() => screen.queryByText('97543910')) + // Passport nationality. The i18n-mock sets up en as the i18n.language property, so look for the English name + await screen.findByText('Denmark') + await screen.findByDisplayValue('123456') + await screen.findByDisplayValue(testData.person.date_of_birth) + + // Mobile phone country code + await screen.findByDisplayValue('NO') + await screen.findByDisplayValue('97543910') + + // Role information + await screen.findByDisplayValue(testData.role.ou_name_en) + // TODO Haven't been able to mock getting role types properly yet, so not checking role name + // await screen.findByDisplayValue(testData.role.name_en) + await screen.findByDisplayValue( + `${testData.role.start} - ${testData.role.end}` + ) + await screen.findByDisplayValue(testData.role.comments) }) diff --git a/frontend/src/routes/guest/register/index.tsx b/frontend/src/routes/guest/register/index.tsx index 4ba89d738b5de3bf256842236d9bfcbbd04a2234..712e30e2d1f229d4c6a177571e3b121e90e23733 100644 --- a/frontend/src/routes/guest/register/index.tsx +++ b/frontend/src/routes/guest/register/index.tsx @@ -10,6 +10,7 @@ import { getCountries, getCountryCallingCode, } from 'libphonenumber-js' +import format from 'date-fns/format' import OverviewGuestButton from '../../components/overviewGuestButton' import GuestRegisterStep from './registerPage' import { GuestRegisterCallableMethods } from './guestRegisterCallableMethods' @@ -62,20 +63,16 @@ export default function GuestRegister() { passport: '', passportNationality: '', countryForCallingCode: '', + dateOfBirth: undefined, authentication_method: AuthenticationMethod.Invite, }) - const [errorState, setErrorState] = useState<string>('') - const guestContactInfo = async () => { try { - const response = await fetch('/api/ui/v1/invited') + const response = await fetch('/api/ui/v1/invited/') if (response.ok) { response.json().then((jsonResponse) => { - // TODO Remove after development - console.log(`Data from server: ${JSON.stringify(jsonResponse)}`) - const authenticationMethod = jsonResponse.meta.session_type === 'invite' ? AuthenticationMethod.Invite @@ -96,7 +93,25 @@ export default function GuestRegister() { } } + let passportNumber = '' + let passportCountry = '' + if (jsonResponse.person.passport) { + const index = jsonResponse.person.passport.indexOf('-') + + if (index !== -1) { + passportCountry = jsonResponse.person.passport.substring(0, index) + passportNumber = jsonResponse.person.passport.substring( + index + 1, + jsonResponse.person.passport.length + ) + } + } + setGuestFormData({ + fnr: jsonResponse.person.fnr, + passportNationality: passportCountry, + passport: passportNumber, + first_name: jsonResponse.person.first_name, last_name: jsonResponse.person.last_name, ou_name_en: jsonResponse.role.ou_name_en, @@ -111,12 +126,10 @@ export default function GuestRegister() { feide_id: jsonResponse.person.feide_id, mobile_phone_country_code: countryCode, mobile_phone: nationalNumber, - fnr: jsonResponse.fnr, - passport: jsonResponse.passport, - // TODO Separate out nationality based on what is in the server response - passportNationality: '', countryForCallingCode: extractedCountryCode, + dateOfBirth: jsonResponse.person.date_of_birth, + authentication_method: authenticationMethod, }) }) @@ -148,6 +161,7 @@ export default function GuestRegister() { ): void => { // TODO Should go to consent page here, if there are consents defined in the database. Submit should happen after after consent page + // Only add fields to the objects that the user can change (this is also checked on the server side) const payload: any = {} payload.person = {} payload.person.mobile_phone = `+${getCountryCallingCode( @@ -155,24 +169,13 @@ export default function GuestRegister() { )}${updateFormData.mobilePhone}` if (guestFormData.authentication_method === AuthenticationMethod.Invite) { + // The authentication method is Invite, so the name does not come from a + // trusted third-party source, and the user can update it payload.person.first_name = updateFormData.firstName payload.person.last_name = updateFormData.lastName } if (updateFormData.passportNumber && updateFormData.passportNationality) { - // The user has entered some passport information, check that both nationality and number are present - if ( - (updateFormData.passportNumber && - !updateFormData.passportNationality) || - (!updateFormData.passportNumber && updateFormData.passportNationality) - ) { - // TODO Make better text and use translation - setErrorState( - 'Both passport nationality and passport number need to be set' - ) - return - } - setErrorState('') payload.person.passport = `${updateFormData.passportNationality}-${updateFormData.passportNumber}` } @@ -180,8 +183,12 @@ export default function GuestRegister() { payload.person.fnr = updateFormData.nationalIdNumber } - // TODO Remove after development - console.log(`Payload: ${JSON.stringify(payload)}`) + if (updateFormData.dateOfBirth) { + payload.person.date_of_birth = format( + updateFormData.dateOfBirth as Date, + 'yyyy-MM-dd' + ) + } fetch('/api/ui/v1/invited/', submitJsonOpts('POST', payload)) .then((response) => { @@ -229,7 +236,8 @@ export default function GuestRegister() { {activeStep === Step.RegisterStep && ( <Button data-testid="button-next" - sx={{ color: 'theme.palette.secondary', mr: 1 }} + color="secondary" + sx={{ mr: 1 }} onClick={handleNext} > {t('button.next')} @@ -238,7 +246,9 @@ export default function GuestRegister() { {activeStep !== Step.SubmitSuccessStep && ( <> - <Button onClick={handleCancel}>{t('button.cancel')}</Button> + <Button color="secondary" onClick={handleCancel}> + {t('button.cancel')} + </Button> {/* TODO This button is only for testing while developing */} <Button onClick={handleSave}>{t('button.save')}</Button> @@ -247,9 +257,6 @@ export default function GuestRegister() { </Box> {activeStep === Step.SubmitSuccessStep && <StepSubmitSuccessGuest />} - - {/* TODO Give better feedback to user */} - {errorState && <h2>{errorState}</h2>} </Page> ) } diff --git a/frontend/src/routes/guest/register/registerPage.tsx b/frontend/src/routes/guest/register/registerPage.tsx index 356e497c42f5fa6bacf673beae504cbef921e4e4..04e55fe60f96da84e105a78546e3d8440f3d0165 100644 --- a/frontend/src/routes/guest/register/registerPage.tsx +++ b/frontend/src/routes/guest/register/registerPage.tsx @@ -23,6 +23,8 @@ import { getCountryCallingCode, } from 'libphonenumber-js' import { getAlpha2Codes, getName } from 'i18n-iso-countries' +import { DatePicker } from '@mui/lab' +import { subYears } from 'date-fns/fp' import { GuestInviteInformation } from './guestDataForm' import { EnteredGuestData } from './enteredGuestData' import { GuestRegisterCallableMethods } from './guestRegisterCallableMethods' @@ -45,12 +47,39 @@ const GuestRegisterStep = forwardRef( const { i18n, t } = useTranslation(['common']) const { nextHandler, guestData } = props + // For select-components it seems to be easier to tie them to a state + // and then handle the updating of the form using this, than to tie the + // components directly to the form-field using useForm const [countryCode, setCountryCode] = useState< CountryCallingCode | undefined >(undefined) - const [mobilePhone, setMobilePhone] = useState<string>('') + const [passportNationality, setPassportNationality] = useState< + string | undefined + >(undefined) + const [idErrorState, setIdErrorState] = useState<string>('') const submit: SubmitHandler<EnteredGuestData> = (data) => { + if ( + !data.nationalIdNumber && + !data.passportNumber && + !data.passportNationality + ) { + // The user has not entered a national ID number nor passport information. + // In this case the user should not be allowed to send in the registration + setIdErrorState(t('validation.nationalIdOrPassport')) + return + } + + // The user has entered some passport information, check that both nationality and number are present + if ( + (data.passportNumber && !data.passportNationality) || + (!data.passportNumber && data.passportNationality) + ) { + setIdErrorState(t('validation.passportNationalityAndNumber')) + return + } + setIdErrorState('') + nextHandler(data) } @@ -65,6 +94,14 @@ const GuestRegisterStep = forwardRef( } = useForm<EnteredGuestData>() const onSubmit = handleSubmit<EnteredGuestData>(submit) + const handlePassportNationalityChange = (event: SelectChangeEvent) => { + if (event.target.value) { + const passportValue = event.target.value as string + setValue('passportNationality', passportValue) + setPassportNationality(passportValue) + } + } + const handleCountryCodeChange = (event: SelectChangeEvent) => { if (event.target.value) { const countryCodeType = event.target.value as CountryCode @@ -99,28 +136,55 @@ const GuestRegisterStep = forwardRef( } } - setMobilePhone(value.target.value) + setValue('mobilePhone', value.target.value) } + const today = new Date() + const minBirthDate = subYears(100)(today) + const maxBirthDate = subYears(1)(today) + useEffect(() => { + // Take values coming from the server, if present, and insert them into the form. + // This effect has guestData as a dependency, so the data will be reloaded + // if guestData changes + setValue('firstName', guestData.first_name) + setValue('lastName', guestData.last_name) + setValue( + 'mobilePhone', + guestData.mobile_phone ? guestData.mobile_phone : '' + ) + + setValue( + 'nationalIdNumber', + guestData.fnr === undefined ? '' : guestData.fnr + ) + setValue( + 'passportNationality', + guestData.passportNationality === undefined + ? '' + : guestData.passportNationality + ) + setPassportNationality(guestData.passportNationality) + setValue( + 'passportNumber', + guestData.passport === undefined ? '' : guestData.passport + ) + setCountryCode(guestData.countryForCallingCode) - setMobilePhone(guestData.mobile_phone ? guestData.mobile_phone : '') setValue( 'mobilePhoneCountry', guestData.countryForCallingCode ? guestData.countryForCallingCode : '' ) - setValue('firstName', guestData.first_name) - setValue('lastName', guestData.last_name) + + setValue('dateOfBirth', guestData.dateOfBirth) }, [guestData]) function doSubmit() { return onSubmit() } - register('mobilePhone', { - required: t<string>('validation.mobilePhoneRequired'), - }) register('mobilePhoneCountry') + register('passportNationality') useImperativeHandle(ref, () => ({ doSubmit })) @@ -195,6 +259,31 @@ const GuestRegisterStep = forwardRef( </> )} + <Controller + name="dateOfBirth" + control={control} + render={({ field }) => ( + <DatePicker + mask="____-__-__" + label={t('input.dateOfBirth')} + // If value is set to undefined the birth date is set to today. Using null makes the field blank + value={field.value === undefined ? null : field.value} + minDate={minBirthDate} + maxDate={maxBirthDate} + inputFormat="yyyy-MM-dd" + onChange={(value) => { + field.onChange(value) + }} + renderInput={(params) => <TextField {...params} />} + /> + )} + /> + {errors.dateOfBirth && ( + <Typography color="error"> + {errors.dateOfBirth.message} + </Typography> + )} + <TextField id="email" label={t('input.email')} @@ -212,6 +301,7 @@ const GuestRegisterStep = forwardRef( /> )} + {/* Box with phone country code and mobile phone */} <Box sx={{ display: 'flex', @@ -276,40 +366,68 @@ const GuestRegisterStep = forwardRef( ))} </Select> - <TextField - sx={{ flexGrow: 2 }} - label={t('input.mobilePhone')} - error={!!errors.mobilePhone} - value={mobilePhone} - helperText={errors.mobilePhone && errors.mobilePhone.message} - onChange={handleMobilePhoneChange} + <Controller + name="mobilePhone" + control={control} + rules={{ + required: true, + }} + defaultValue="" + render={({ field }) => ( + <TextField + sx={{ flexGrow: 2 }} + label={t('input.mobilePhone')} + error={!!errors.mobilePhone} + value={field.value === undefined ? null : field.value} + helperText={ + errors.mobilePhone && errors.mobilePhone.message + } + onChange={handleMobilePhoneChange} + /> + )} /> </Box> {guestData.authentication_method === AuthenticationMethod.Invite && ( <> {/* The guest should fill in one of national ID number or passport number */} - <TextField - id="national_id_number" - label={t('input.nationalIdNumber')} - error={!!errors.nationalIdNumber} - helperText={ - errors.nationalIdNumber && errors.nationalIdNumber.message - } - {...register('nationalIdNumber', { + <Controller + name="nationalIdNumber" + control={control} + defaultValue="" + rules={{ // It is not required that the national ID number be filled in, the guest may not have // one, so allow empty values for the validation to pass validate: (value) => isValidFnr(value, true), - })} + }} + render={({ field }) => ( + <TextField + id="nationalIdNumber" + label={t('input.nationalIdNumber')} + error={!!errors.nationalIdNumber} + value={field.value} + onChange={field.onChange} + helperText={ + errors.nationalIdNumber && + errors.nationalIdNumber.message + } + /> + )} /> - <TextField - id="passport-number-id" - data-testid="passport_number_input" - label={t('input.passportNumber')} - {...register('passportNumber', { - required: false, - })} + <Controller + name="passportNumber" + control={control} + defaultValue="" + render={({ field }) => ( + <TextField + id="passportNumber" + data-testid="passport_number_input" + value={field.value} + label={t('input.passportNumber')} + onChange={field.onChange} + /> + )} /> <Select @@ -321,9 +439,12 @@ const GuestRegisterStep = forwardRef( label={t('input.passportNationality')} displayEmpty defaultValue="" - {...register('passportNationality', { - required: false, - })} + value={ + passportNationality === undefined + ? '' + : passportNationality + } + onChange={handlePassportNationalityChange} renderValue={(selected: any) => { if (!selected || selected.length === 0) { return t('input.passportNationality') @@ -361,6 +482,9 @@ const GuestRegisterStep = forwardRef( </MenuItem> ))} </Select> + {idErrorState && ( + <Typography color="error">{idErrorState}</Typography> + )} </> )} diff --git a/frontend/src/routes/guest/register/submitSuccessPage.tsx b/frontend/src/routes/guest/register/submitSuccessPage.tsx index e139c067b87f0f1cd25dfb97a0ea152918a64aa1..1c7e394612f1cb31ea7916795b21afbf23ba8e73 100644 --- a/frontend/src/routes/guest/register/submitSuccessPage.tsx +++ b/frontend/src/routes/guest/register/submitSuccessPage.tsx @@ -24,9 +24,9 @@ const StepSubmitSuccessGuest = () => { <Box sx={{ marginTop: '2rem' }}>{t('guestSubmitSuccessDescription')}</Box> <Button + color="secondary" sx={{ marginTop: '2rem', - color: 'theme.palette.dark', }} onClick={() => { history.push('/') diff --git a/frontend/src/routes/landing/index.tsx b/frontend/src/routes/landing/index.tsx index ab2dee56dd0ece21fb69f8f81f683fa360b29c40..9fe40b7acf128abf10bbbc7790e4e7a8f599141b 100644 --- a/frontend/src/routes/landing/index.tsx +++ b/frontend/src/routes/landing/index.tsx @@ -29,7 +29,7 @@ const GuestPage = () => { <h4>{t('guestInfo.contactInfo')}</h4> <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label="simple table"> - <TableHead sx={{ backgroundColor: 'primary.light' }}> + <TableHead sx={{ backgroundColor: 'secondary.light' }}> <TableRow> <TableCell align="left">{t('guestInfo.contactInfo')}</TableCell> <TableCell /> @@ -66,7 +66,7 @@ const GuestPage = () => { <h4>{t('guestInfo.roleInfoHead')}</h4> <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label="simple table"> - <TableHead sx={{ backgroundColor: 'primary.light' }}> + <TableHead sx={{ backgroundColor: 'secondary.light' }}> <TableRow> <TableCell align="left">{t('common:role')}</TableCell> <TableCell align="left">{t('common:period')}</TableCell> diff --git a/frontend/src/routes/sponsor/frontpage/index.tsx b/frontend/src/routes/sponsor/frontpage/index.tsx index 3c9ecdee9af823f2a4c185192a248c944e7694e1..66210c95c62d03fb5d2a7f68d569c207898bfe06 100644 --- a/frontend/src/routes/sponsor/frontpage/index.tsx +++ b/frontend/src/routes/sponsor/frontpage/index.tsx @@ -69,6 +69,7 @@ const PersonLine = ({ person, role, showStatusColumn }: PersonLineProps) => { <TableCell align="left"> <Button variant="contained" + color="secondary" component={Link} to={`/sponsor/guest/${person.pid}`} > @@ -107,7 +108,7 @@ const WaitingForGuestRegistration = ({ persons }: GuestProps) => { <p>{t('common:sentInvitationsDescription')}</p> <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label="simple table"> - <TableHead sx={{ backgroundColor: 'primary.light' }}> + <TableHead sx={{ backgroundColor: 'secondary.light' }}> <TableRow> <TableCell>{t('common:name')}</TableCell> <TableCell align="left">{t('common:role')}</TableCell> @@ -167,7 +168,7 @@ const ActiveGuests = ({ persons }: GuestProps) => { <p>{t('common:activeGuestsDescription')}</p> <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label="simple table"> - <TableHead sx={{ backgroundColor: 'primary.light' }}> + <TableHead sx={{ backgroundColor: 'secondary.light' }}> <TableRow> <TableCell>{t('common:name')}</TableCell> <TableCell align="left">{t('common:role')}</TableCell> @@ -237,7 +238,7 @@ const WaitingGuests = ({ persons }: GuestProps) => { <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label="simple table"> - <TableHead sx={{ backgroundColor: 'primary.light' }}> + <TableHead sx={{ backgroundColor: 'secondary.light' }}> <TableRow> <TableCell>{t('common:name')}</TableCell> <TableCell align="left">{t('common:role')}</TableCell> diff --git a/frontend/src/routes/sponsor/guest/guestInfo/index.tsx b/frontend/src/routes/sponsor/guest/guestInfo/index.tsx index d162a06b881d5745e7c5b1d64da990f6ca7d5d94..453d413980749f102d208c0b511e711dccd583a2 100644 --- a/frontend/src/routes/sponsor/guest/guestInfo/index.tsx +++ b/frontend/src/routes/sponsor/guest/guestInfo/index.tsx @@ -19,7 +19,7 @@ import { DialogActions, TextField, } from '@mui/material' -import { Guest, Role } from 'interfaces' +import { Guest } from 'interfaces' import SponsorInfoButtons from 'routes/components/sponsorInfoButtons' import { useEffect, useState } from 'react' import { SubmitHandler, useForm } from 'react-hook-form' @@ -31,7 +31,6 @@ type GuestInfoParams = { type GuestInfoProps = { guest: Guest - roles: Role[] updateEmail: (validEmail: string) => void resend: () => void } @@ -63,10 +62,10 @@ function CancelConfirmationDialog({ {t('confirmationDialog.cancelInvitationDescription')} </DialogContent> <DialogActions> - <Button autoFocus onClick={handleCancel}> + <Button autoFocus color="secondary" onClick={handleCancel}> {t('button.cancel')} </Button> - <Button autoFocus onClick={handleOk}> + <Button autoFocus color="secondary" onClick={handleOk}> {t('button.ok')} </Button> </DialogActions> @@ -80,7 +79,6 @@ type Email = { export default function GuestInfo({ guest, - roles, updateEmail, resend, }: GuestInfoProps) { @@ -163,7 +161,7 @@ export default function GuestInfo({ <h4>{t('guestInfo.contactInfo')}</h4> <TableContainer sx={{ marginBottom: '0.8rem' }} component={Paper}> <Table sx={{ minWidth: 650 }} aria-label="simple table"> - <TableHead sx={{ backgroundColor: 'primary.light' }}> + <TableHead sx={{ backgroundColor: 'secondary.light' }}> <TableRow> <TableCell align="left">{t('guestInfo.contactInfo')}</TableCell> <TableCell /> @@ -206,12 +204,14 @@ export default function GuestInfo({ }} > <Button + color="secondary" sx={{ maxHeight: '2.3rem', marginLeft: '1rem' }} onClick={resend} > {t('button.resendInvitation')} </Button> <Button + color="secondary" sx={{ maxHeight: '2.3rem', marginLeft: '0.5rem' }} onClick={handleCancel} > @@ -237,7 +237,11 @@ export default function GuestInfo({ </TableBody> </Table> </TableContainer> - <Button disabled={!errors.email && !emailDirty} onClick={onSubmit}> + <Button + color="secondary" + disabled={!errors.email && !emailDirty} + onClick={onSubmit} + > {t('button.save')} </Button> @@ -246,6 +250,7 @@ export default function GuestInfo({ {t('guestInfo.roleInfoBody')} <Button variant="contained" + color="secondary" component={Link} to={`/sponsor/guest/${pid}/newrole`} > @@ -255,7 +260,7 @@ export default function GuestInfo({ <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label="simple table"> - <TableHead sx={{ backgroundColor: 'primary.light' }}> + <TableHead sx={{ backgroundColor: 'secondary.light' }}> <TableRow> <TableCell align="left">{t('common:role')}</TableCell> <TableCell align="left">{t('common:period')}</TableCell> @@ -264,7 +269,7 @@ export default function GuestInfo({ </TableRow> </TableHead> <TableBody> - {roles.map((role) => ( + {guest.roles.map((role) => ( <RoleLine key={role.id} pid={pid} role={role} /> ))} </TableBody> diff --git a/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx b/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx index 6445c4ac23c5778e3b2707eba9865ce5a389cf42..66112b9c0b155e2022323a20b0e131b2a7f5bc16 100644 --- a/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx +++ b/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx @@ -12,7 +12,7 @@ import { TextField, } from '@mui/material' import Page from 'components/page' -import { Guest, Role } from 'interfaces' +import { Guest } from 'interfaces' import { useTranslation } from 'react-i18next' import { useParams } from 'react-router-dom' import SponsorInfoButtons from 'routes/components/sponsorInfoButtons' @@ -22,7 +22,6 @@ import { submitJsonOpts } from '../../../../utils' interface GuestRoleInfoProps { guest: Guest - roles: Role[] } const endPeriodPost = (id: string, data: { end_date: Date }) => { const payload = { @@ -57,12 +56,12 @@ type RoleFormData = { end_date: Date } -export default function GuestRoleInfo({ guest, roles }: GuestRoleInfoProps) { +export default function GuestRoleInfo({ guest }: GuestRoleInfoProps) { const { pid, id } = useParams<GuestRoleInfoParams>() const [t, i18n] = useTranslation('common') // Find the role info relevant for this page - const roleInfo = roles.filter((role) => role.id.toString() === id)[0] + const roleInfo = guest.roles.filter((role) => role.id.toString() === id)[0] // Prepare min and max date values const today = new Date() @@ -172,7 +171,9 @@ export default function GuestRoleInfo({ guest, roles }: GuestRoleInfoProps) { /> </TableCell> <TableCell> - <Button onClick={endPeriod()}>{t('sponsor.endNow')}</Button> + <Button color="secondary" onClick={endPeriod()}> + {t('sponsor.endNow')} + </Button> </TableCell> </TableRow> <TableRow> @@ -185,7 +186,7 @@ export default function GuestRoleInfo({ guest, roles }: GuestRoleInfoProps) { </TableBody> </Table> </TableContainer> - <Button variant="contained" type="submit"> + <Button variant="contained" color="secondary" type="submit"> {t('button.save')} </Button> </form> diff --git a/frontend/src/routes/sponsor/guest/index.tsx b/frontend/src/routes/sponsor/guest/index.tsx index d3ba9e7e98e8d2b015ed15ff3e48fd97e1cd3e9c..c1a60676bcc078245e2fb5fb713e10badcfd07f3 100644 --- a/frontend/src/routes/sponsor/guest/index.tsx +++ b/frontend/src/routes/sponsor/guest/index.tsx @@ -1,7 +1,6 @@ -import { FetchedRole, Guest, Role } from 'interfaces' -import { useEffect, useState } from 'react' +import useGuest from 'hooks/useGuest' import { Route, useParams } from 'react-router-dom' -import { parseRole, submitJsonOpts } from 'utils' +import { submitJsonOpts } from 'utils' import GuestInfo from './guestInfo' import GuestRoleInfo from './guestRoleInfo' import NewGuestRole from './newGuestRole' @@ -12,45 +11,7 @@ type GuestInfoParams = { function GuestRoutes() { const { pid } = useParams<GuestInfoParams>() - - const [guestInfo, setGuest] = useState<Guest>({ - pid: '', - first: '', - last: '', - email: '', - fnr: '', - mobile: '', - active: false, - registered: false, - verified: false, - roles: [], - }) - const [roles, setRoles] = useState<Role[]>([]) - - const getPerson = async (id: string) => { - try { - const response = await fetch(`/api/ui/v1/person/${id}`) - const rjson = await response.json() - - if (response.ok) { - setGuest({ - pid: rjson.pid, - first: rjson.first, - last: rjson.last, - email: rjson.email, - mobile: rjson.mobile, - fnr: rjson.fnr, - active: rjson.active, - registered: rjson.registered, - verified: rjson.verified, - roles: rjson.roles, - }) - setRoles(rjson.roles.map((role: FetchedRole) => parseRole(role))) - } - } catch (error) { - console.error(error) - } - } + const { guestInfo, reloadGuestInfo } = useGuest(pid) const updateEmail = (validEmail: string) => { fetch( @@ -61,7 +22,7 @@ function GuestRoutes() { if (res.ok) { // Just reload data from the server, it will cause the children // to be rerendered - getPerson(pid) + reloadGuestInfo() } }) .catch((error) => { @@ -88,22 +49,17 @@ function GuestRoutes() { }) } - useEffect(() => { - getPerson(pid) - }, []) - return ( <> <Route path="/sponsor/guest/:pid/roles/:id"> - <GuestRoleInfo guest={guestInfo} roles={roles} /> + <GuestRoleInfo guest={guestInfo} /> </Route> <Route exact path="/sponsor/guest/:pid/newrole"> - <NewGuestRole guest={guestInfo} /> + <NewGuestRole guest={guestInfo} reloadGuestInfo={reloadGuestInfo} /> </Route> <Route exact path="/sponsor/guest/:pid"> <GuestInfo guest={guestInfo} - roles={roles} updateEmail={updateEmail} resend={resend} /> diff --git a/frontend/src/routes/sponsor/guest/newGuestRole/index.tsx b/frontend/src/routes/sponsor/guest/newGuestRole/index.tsx index 4aa06b56bea1ae5c080837abd4f8ce413933da7c..2d7859095ea1513a855d986959550958cd55df8a 100644 --- a/frontend/src/routes/sponsor/guest/newGuestRole/index.tsx +++ b/frontend/src/routes/sponsor/guest/newGuestRole/index.tsx @@ -20,7 +20,7 @@ import { Guest } from 'interfaces' import { useState } from 'react' import { Controller, useForm } from 'react-hook-form' import { useTranslation } from 'react-i18next' -import { Link, useParams } from 'react-router-dom' +import { Link, useHistory, useParams } from 'react-router-dom' import SponsorInfoButtons from 'routes/components/sponsorInfoButtons' import { submitJsonOpts } from 'utils' @@ -50,9 +50,10 @@ type GuestInfoParams = { interface NewGuestRoleProps { guest: Guest + reloadGuestInfo: () => void } -const postRole = (formData: AddRoleFormData, pid: string) => { +const postRole = async (formData: AddRoleFormData, pid: string) => { const payload: AddRolePayload = { orgunit: formData.orgunit, person: pid, @@ -92,7 +93,7 @@ const postRole = (formData: AddRoleFormData, pid: string) => { }) } -function NewGuestRole({ guest }: NewGuestRoleProps) { +function NewGuestRole({ guest, reloadGuestInfo }: NewGuestRoleProps) { const { register, control, @@ -103,8 +104,11 @@ function NewGuestRole({ guest }: NewGuestRoleProps) { } = useForm<AddRoleFormData>() const { pid } = useParams<GuestInfoParams>() - const onSubmit = handleSubmit(() => { - postRole(getValues(), pid) + const history = useHistory() + const onSubmit = handleSubmit(async () => { + await postRole(getValues(), pid) + reloadGuestInfo() + history.push(`/sponsor/guest/${pid}`) }) const ous = useOus() @@ -260,10 +264,14 @@ function NewGuestRole({ guest }: NewGuestRoleProps) { } label={t('input.searchable')} /> - <Button variant="contained" type="submit"> + <Button variant="contained" color="secondary" type="submit"> {t('button.save')} </Button> - <Button component={Link} to={`/sponsor/guest/${pid}`}> + <Button + component={Link} + color="secondary" + to={`/sponsor/guest/${pid}`} + > {t('button.cancel')} </Button> </Stack> diff --git a/frontend/src/routes/sponsor/register/frontPage.tsx b/frontend/src/routes/sponsor/register/frontPage.tsx index 297e6abbba6db139f8d9bb05dd59d08f1840a37f..d53ef156375a9e4bdff4b9ffaebac85544ce6548 100644 --- a/frontend/src/routes/sponsor/register/frontPage.tsx +++ b/frontend/src/routes/sponsor/register/frontPage.tsx @@ -62,7 +62,12 @@ function FrontPage() { ) : ( <></> )} - <Button variant="contained" component={Link} to="register/new"> + <Button + variant="contained" + color="secondary" + component={Link} + to="register/new" + > {t('register.registerButtonText')} </Button> </Page> diff --git a/frontend/src/routes/sponsor/register/index.test.tsx b/frontend/src/routes/sponsor/register/index.test.tsx index 4d699b4f5553db156fb04195321f346c8ec6231a..ad6ed27d7541f48e7a6591de39b7ade8f7efcb6c 100644 --- a/frontend/src/routes/sponsor/register/index.test.tsx +++ b/frontend/src/routes/sponsor/register/index.test.tsx @@ -32,9 +32,14 @@ test('Validation message showing if last name is missing', async () => { screen.queryByText('validation.lastNameRequired') userEvent.click(submitButton) - await waitFor(() => { - expect( - screen.queryByText('validation.lastNameRequired') - ).not.toBeInTheDocument() - }) + await waitFor( + () => { + expect( + screen.queryByText('validation.lastNameRequired') + ).not.toBeInTheDocument() + }, + { + timeout: 5000, + } + ) }) diff --git a/frontend/src/routes/sponsor/register/stepPersonForm.tsx b/frontend/src/routes/sponsor/register/stepPersonForm.tsx index c13e7b5e541a58e145e2c1db3dee6e70cc220e69..c4427e9dfd4a0b0665b0df8e7e89afc5517d44f9 100644 --- a/frontend/src/routes/sponsor/register/stepPersonForm.tsx +++ b/frontend/src/routes/sponsor/register/stepPersonForm.tsx @@ -11,9 +11,10 @@ import { } from '@mui/material' import { Controller, SubmitHandler, useForm } from 'react-hook-form' import { DatePicker } from '@mui/lab' -import { +import React, { forwardRef, Ref, + useContext, useEffect, useImperativeHandle, useState, @@ -24,6 +25,7 @@ import { PersonFormMethods } from './personFormMethods' import useOus, { enSort, nbSort } from '../../../hooks/useOus' import useRoleTypes, { RoleTypeData } from '../../../hooks/useRoleTypes' import { isValidEmail } from '../../../utils' +import { FeatureContext } from '../../../contexts' interface StepPersonFormProperties { nextHandler(formState: RegisterFormData): void @@ -43,6 +45,7 @@ const StepPersonForm = forwardRef( formData.role_type ? formData.role_type : '' ) const roleTypes = useRoleTypes() + const { displayContactAtUnit, displayComment } = useContext(FeatureContext) const roleTypeSort = () => (a: RoleTypeData, b: RoleTypeData) => { if (i18n.language === 'en') { @@ -168,17 +171,14 @@ const StepPersonForm = forwardRef( label={t('common:ou')} onChange={handleOuChange} > - {ous.length > 0 ? ( + {ous.length > 0 && ous .sort(i18n.language === 'en' ? enSort : nbSort) .map((ou) => ( <MenuItem key={ou.id.toString()} value={ou.id}> {i18n.language === 'en' ? ou.en : ou.nb} ({ou.id}) </MenuItem> - )) - ) : ( - <></> - )} + ))} </Select> </FormControl> @@ -239,19 +239,23 @@ const StepPersonForm = forwardRef( )} /> - <TextField - id="contact_person" - label={t('input.contactPersonUnit')} - {...register(`contact_person_unit`)} - /> + {displayContactAtUnit && ( + <TextField + id="contact_person" + label={t('input.contactPersonUnit')} + {...register(`contact_person_unit`)} + /> + )} - <TextField - id="comment" - label={t('input.comment')} - multiline - rows={5} - {...register(`comment`)} - /> + {displayComment && ( + <TextField + id="comment" + label={t('input.comment')} + multiline + rows={5} + {...register(`comment`)} + /> + )} </Stack> </form> </Box> diff --git a/frontend/src/routes/sponsor/register/stepRegistration.tsx b/frontend/src/routes/sponsor/register/stepRegistration.tsx index 36ba38bb127bcd61b14376ad435d4076febd99f3..3d274b468bd51214b7d2d37d47713ff633e3a21d 100644 --- a/frontend/src/routes/sponsor/register/stepRegistration.tsx +++ b/frontend/src/routes/sponsor/register/stepRegistration.tsx @@ -142,7 +142,8 @@ export default function StepRegistration() { {activeStep === Steps.RegisterStep && ( <Button data-testid="button-next" - sx={{ color: 'theme.palette.secondary', mr: 1 }} + color="secondary" + sx={{ mr: 1 }} onClick={handleNext} > {t('button.next')} @@ -153,6 +154,7 @@ export default function StepRegistration() { <> <Button onClick={handleBack} + color="secondary" disabled={submitState === SubmitState.SubmitSuccess} sx={{ mr: 1 }} > @@ -161,6 +163,7 @@ export default function StepRegistration() { <Button onClick={registerGuest} + color="secondary" disabled={submitState === SubmitState.SubmitSuccess} sx={{ mr: 1 }} > @@ -172,6 +175,7 @@ export default function StepRegistration() { {activeStep !== Steps.SuccessStep && ( <Button onClick={handleCancel} + color="secondary" disabled={submitState === SubmitState.SubmitSuccess} > {t('button.cancel')} diff --git a/frontend/src/routes/sponsor/register/stepSubmitSuccess.tsx b/frontend/src/routes/sponsor/register/stepSubmitSuccess.tsx index 428390ae01418aa5b577de81c1dd6b9995ff64d3..b4d12a1cf4183080408f66f06ecc7dc0a0ac8dbb 100644 --- a/frontend/src/routes/sponsor/register/stepSubmitSuccess.tsx +++ b/frontend/src/routes/sponsor/register/stepSubmitSuccess.tsx @@ -26,9 +26,9 @@ const StepSubmitSuccess = () => { </Box> <Button + color="secondary" sx={{ marginTop: '2rem', - color: 'theme.palette.dark', }} onClick={() => { history.push('/') diff --git a/frontend/src/routes/sponsor/register/stepSummary.tsx b/frontend/src/routes/sponsor/register/stepSummary.tsx index f01f865d476b9449e9655d05da2a5a6f82e30d58..9824fc994c9ea3de1646900d16bba1ba4631a312 100644 --- a/frontend/src/routes/sponsor/register/stepSummary.tsx +++ b/frontend/src/routes/sponsor/register/stepSummary.tsx @@ -1,4 +1,3 @@ -import React, { forwardRef } from 'react' import { useTranslation } from 'react-i18next' import { @@ -21,7 +20,7 @@ interface StepSummaryProperties { formData: RegisterFormData } -const StepSummary = forwardRef((props: StepSummaryProperties) => { +function StepSummary(props: StepSummaryProperties) { const { t } = useTranslation(['common']) const { formData } = props const ous = useOus() @@ -70,7 +69,7 @@ const StepSummary = forwardRef((props: StepSummaryProperties) => { typography: 'subtitle2', marginBottom: '0.5rem', paddingLeft: '0.5rem', - bgcolor: 'primary.light', + bgcolor: 'secondary.light', }} > {t('registerWizardText.contactInformation')} @@ -104,7 +103,7 @@ const StepSummary = forwardRef((props: StepSummaryProperties) => { <TableHead sx={{ paddingLeft: '0.5rem', - bgcolor: 'primary.light', + bgcolor: 'secondary.light', }} > <TableRow> @@ -134,6 +133,6 @@ const StepSummary = forwardRef((props: StepSummaryProperties) => { </Box> </> ) -}) +} export default StepSummary diff --git a/frontend/src/test-utils.tsx b/frontend/src/test-utils.tsx index 1ff2080413e979ed801c27c1481406976acb2118..7be8884de2a2feb948ca530b2b2464225e5e5be5 100644 --- a/frontend/src/test-utils.tsx +++ b/frontend/src/test-utils.tsx @@ -24,6 +24,7 @@ jest.mock('react-i18next', () => ({ useTranslation: () => ({ t: (value: string) => value, i18n: { + language: 'en', changeLanguage: () => new Promise(() => {}), }, }), diff --git a/frontend/src/themes/index.test.ts b/frontend/src/themes/index.test.ts index e5f2bf3533202122bcc3417dba2d2dc235d82c1b..fcc10d6d9b4fc9bbc8e1905bfd6d55f390a347a1 100644 --- a/frontend/src/themes/index.test.ts +++ b/frontend/src/themes/index.test.ts @@ -12,28 +12,28 @@ test('Get theme uio', async () => { process.env.REACT_APP_THEME = 'uio' // eslint-disable-next-line global-require const getTheme = require('./index').default - expect(getTheme().palette.primary.main).toEqual('#4977af') + expect(getTheme().palette.primary.main).toEqual('#000000') }) test('Get theme uib', async () => { process.env.REACT_APP_THEME = 'uib' // eslint-disable-next-line global-require const getTheme = require('./index').default - expect(getTheme().palette.primary.main).toEqual('#ba000d') + expect(getTheme().palette.primary.main).toEqual('#cf3c3a') }) test('Get theme default when set', async () => { process.env.REACT_APP_THEME = 'default' // eslint-disable-next-line global-require const getTheme = require('./index').default - expect(getTheme().palette.primary.main).toEqual('#01579B') + expect(getTheme().palette.primary.main).toEqual('#1976d2') }) test('Get theme default when unknown', async () => { process.env.REACT_APP_THEME = 'unknown' // eslint-disable-next-line global-require const getTheme = require('./index').default - expect(getTheme().palette.primary.main).toEqual('#01579B') + expect(getTheme().palette.primary.main).toEqual('#1976d2') }) export {} diff --git a/frontend/src/themes/index.ts b/frontend/src/themes/index.ts index d1cdfcd3867f886fcd06999949d8294dd3ffdef3..05b22f8b7ea8fe26fa9ba421ad7e9e6832d240b6 100644 --- a/frontend/src/themes/index.ts +++ b/frontend/src/themes/index.ts @@ -12,25 +12,18 @@ declare module '@mui/material/styles' { greg: { appMinWidth: string appMaxWidth: string - headerBackgroundColor: string - h1TextColor: string - h2TextColor: string - footerBackgroundColor: string - footerTextColor: string deactivatedColor: string + textWhite: string } } + // allow configuration using `createTheme` interface ThemeOptions { greg?: { appMinWidth?: string appMaxWidth?: string - headerBackgroundColor?: string - h1TextColor?: string - h2TextColor?: string - footerBackgroundColor?: string - footerTextColor?: string, deactivatedColor?: string + textWhite?: string } } } @@ -40,9 +33,9 @@ export const defaultTheme = createTheme(mainTheme) function getTheme() { switch (appTheme) { case 'uib': - return createTheme(deepmerge(defaultTheme, uibTheme)) + return createTheme(deepmerge(mainTheme, uibTheme)) case 'uio': - return createTheme(deepmerge(defaultTheme, uioTheme)) + return createTheme(deepmerge(mainTheme, uioTheme)) case 'default': return defaultTheme default: diff --git a/frontend/src/themes/main.ts b/frontend/src/themes/main.ts index 44bd354d1d06c71c16f9b82c628b40c93381a518..abdc4ed34713a58b4f332bbba17acb557736df07 100644 --- a/frontend/src/themes/main.ts +++ b/frontend/src/themes/main.ts @@ -6,20 +6,10 @@ const mainTheme: ThemeOptions = { greg: { appMinWidth: '60rem', appMaxWidth: '110rem', - headerBackgroundColor: 'black', - h1TextColor: 'white', - h2TextColor: '#373F41', - footerBackgroundColor: 'black', - footerTextColor: 'white', - deactivatedColor: '#C9C9C9' - }, - palette: { - primary: { - main: '#01579B', - dark: '#1565c0', - light: '#A4C8E4', - }, + deactivatedColor: '#C9C9C9', + textWhite: 'white', }, + // No palette section defined here, it is up to the different institutions to define colours that override the default ones from Material UI components: { MuiTextField: { defaultProps: { diff --git a/frontend/src/themes/uib.ts b/frontend/src/themes/uib.ts index a659679ec6cb1c1135c9a915772ce9d5cb16475e..8313b97716a3e06c04446c04c0bc5fa687f2b6cf 100644 --- a/frontend/src/themes/uib.ts +++ b/frontend/src/themes/uib.ts @@ -1,10 +1,26 @@ import { ThemeOptions } from '@mui/material' +/* + Based on guidelines found here: https://manual.uib.no/profilmanual/profilelementer/ + */ const uibTheme: ThemeOptions = { + greg: { + appMinWidth: '60rem', + appMaxWidth: '110rem', + deactivatedColor: '#C9C9C9', + }, + typography: { + fontFamily: ['Open Sans', 'Roboto'].join(','), + }, palette: { primary: { - main: '#ba000d', - dark: '#1565c0' + main: '#cf3c3a', + light: '#ff6c6a', + }, + secondary: { + main: '#63b5cc', + dark: '#4ea0b7', + light: '#7ed0e7', }, }, } diff --git a/frontend/src/themes/uio.ts b/frontend/src/themes/uio.ts index c5f908ec246ee55b957079f81d4559b7b459ec7a..8a5c81570bfbab4c6151816f9e70aa03f2bd42fb 100644 --- a/frontend/src/themes/uio.ts +++ b/frontend/src/themes/uio.ts @@ -1,11 +1,15 @@ -import { ThemeOptions } from "@mui/material" +import { ThemeOptions } from '@mui/material' const uioTheme: ThemeOptions = { palette: { primary: { - main: "#4977af", - dark: '#1565c0' - } + main: '#000000', + }, + secondary: { + main: '#01579B', + dark: '#1565c0', + light: '#A4C8E4', + }, }, } diff --git a/greg/api/serializers/sponsor.py b/greg/api/serializers/sponsor.py index a2c503442a925080364554d4980c8cf1d9774578..4171419e37535b0329af166d40287d92b3b22b24 100644 --- a/greg/api/serializers/sponsor.py +++ b/greg/api/serializers/sponsor.py @@ -5,8 +5,8 @@ from greg.models import Sponsor class SponsorSerializer(serializers.ModelSerializer): - units = OrganizationalUnitSerializer(many=True, read_only=True) + orgunits = OrganizationalUnitSerializer(many=True, read_only=True, source="units") class Meta: model = Sponsor - fields = ["id", "feide_id", "first_name", "last_name", "units"] + fields = ["id", "feide_id", "first_name", "last_name", "orgunits"] diff --git a/greg/api/urls.py b/greg/api/urls.py index 725e195bde80d3798092b99cd7e73e2e83966c82..9f0fb910eddf6ee1e7db3602fbd0dd5ae45f38dd 100644 --- a/greg/api/urls.py +++ b/greg/api/urls.py @@ -22,7 +22,7 @@ router.register(r"persons", PersonViewSet, basename="person") router.register(r"roletypes", RoleTypeViewSet, basename="roletype") router.register(r"consenttypes", ConsentTypeViewSet, basename="consenttype") router.register(r"sponsors", SponsorViewSet, basename="sponsor") -router.register(r"orgunit", OrganizationalUnitViewSet, basename="orgunit") +router.register(r"orgunits", OrganizationalUnitViewSet, basename="orgunit") urlpatterns = router.urls diff --git a/greg/migrations/0015_add_feide_email.py b/greg/migrations/0015_add_feide_email.py new file mode 100644 index 0000000000000000000000000000000000000000..9fcaf49ec97bdf0c310678de7cf1352cd6773db0 --- /dev/null +++ b/greg/migrations/0015_add_feide_email.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.9 on 2021-11-19 10:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('greg', '0014_add_sponsor_ou_source_data'), + ] + + operations = [ + migrations.AddField( + model_name='sponsor', + name='work_email', + field=models.CharField(max_length=256, null=True), + ), + migrations.AlterField( + model_name='identity', + name='type', + field=models.CharField(choices=[('feide_id', 'Feide Id'), ('feide_email', 'Feide Email'), ('passport_number', 'Passport Number'), ('norwegian_national_id_number', 'Norwegian National Id Number'), ('private_email', 'Private Email'), ('private_mobile', 'Private Mobile Number'), ('other', 'Other')], max_length=64), + ), + ] diff --git a/greg/models.py b/greg/models.py index 90d54ca027e484855234163dacd07470e4d285d1..a80b7f17d8a83633f1ae90ac00a949caa47800c9 100644 --- a/greg/models.py +++ b/greg/models.py @@ -91,6 +91,11 @@ class Person(BaseModel): type=Identity.IdentityType.PASSPORT_NUMBER ).first() + @property + def feide_id(self) -> Optional["Identity"]: + """The person's Feide ID if they have one registered.""" + return self.identities.filter(type=Identity.IdentityType.FEIDE_ID).first() + @property def is_registered(self) -> bool: """ @@ -263,6 +268,7 @@ class Notification(BaseModel): class Identity(BaseModel): class IdentityType(models.TextChoices): FEIDE_ID = "feide_id" + FEIDE_EMAIL = "feide_email" PASSPORT_NUMBER = "passport_number" # Norwegian national ID - "fødselsnummer" NORWEGIAN_NATIONAL_ID_NUMBER = "norwegian_national_id_number" @@ -419,6 +425,7 @@ class Sponsor(BaseModel): """ feide_id = models.CharField(max_length=256) + work_email = models.CharField(max_length=256, null=True) first_name = models.CharField(max_length=256) last_name = models.CharField(max_length=256) diff --git a/greg/tests/api/test_sponsor.py b/greg/tests/api/test_sponsor.py index 1b6aac1a838b685a36c898b1ae0f9f19e4627d20..459fd64e8a2dc9073902c51f8d76e85464c5b27e 100644 --- a/greg/tests/api/test_sponsor.py +++ b/greg/tests/api/test_sponsor.py @@ -70,7 +70,7 @@ def test_add_sponsor_with_unit(client, unit_foo: OrganizationalUnit): sponsor_lookup_response_body = sponsor_lookup_response.json() assert len(sponsor_lookup_response_body["results"]) == 1 - assert len(sponsor_lookup_response_body["results"][0]["units"]) == 0 + assert len(sponsor_lookup_response_body["results"][0]["orgunits"]) == 0 data = {"hierarchical_access": "True"} @@ -83,9 +83,9 @@ def test_add_sponsor_with_unit(client, unit_foo: OrganizationalUnit): sponsor_lookup_response = client.get(sponsor_url, kwargs={"id": sponsor_id}) sponsor_lookup_response_body = sponsor_lookup_response.json() - assert len(sponsor_lookup_response_body["results"][0]["units"]) == 1 + assert len(sponsor_lookup_response_body["results"][0]["orgunits"]) == 1 - attached_unit = sponsor_lookup_response_body["results"][0]["units"][0] + attached_unit = sponsor_lookup_response_body["results"][0]["orgunits"][0] assert attached_unit["id"] == unit_foo.id @@ -95,7 +95,7 @@ def test_remove_sponsor_orgunit_link( ): sponsor_detail_url = reverse("v1:sponsor-detail", kwargs={"id": sponsor_guy.id}) response_get = client.get(sponsor_detail_url).json() - assert len(response_get["units"]) == 0 + assert len(response_get["orgunits"]) == 0 data = {"hierarchical_access": "True"} @@ -108,14 +108,14 @@ def test_remove_sponsor_orgunit_link( response_get = client.get(sponsor_detail_url).json() - assert len(response_get["units"]) == 1 - assert response_get["units"][0]["id"] == unit_foo.id + assert len(response_get["orgunits"]) == 1 + assert response_get["orgunits"][0]["id"] == unit_foo.id response_delete = client.delete(sponsor_orgunit_url) assert response_delete.status_code == status.HTTP_204_NO_CONTENT response_get = client.get(sponsor_detail_url).json() - assert len(response_get["units"]) == 0 + assert len(response_get["orgunits"]) == 0 @pytest.mark.django_db @@ -128,7 +128,7 @@ def test_delete_sponsor_connected_to_identity_not_allowed( ): sponsor_detail_url = reverse("v1:sponsor-detail", kwargs={"id": sponsor_guy.id}) response_get = client.get(sponsor_detail_url).json() - assert len(response_get["units"]) == 0 + assert len(response_get["orgunits"]) == 0 response_delete = client.delete(sponsor_detail_url) @@ -177,9 +177,9 @@ def test_add_sponsor_unit_link_with_no_access_parameter( # Check that the unit is attached to the sponsor sponsor_lookup_response = client.get(sponsor_url, kwargs={"id": sponsor_id}) sponsor_lookup_response_body = sponsor_lookup_response.json() - assert len(sponsor_lookup_response_body["results"][0]["units"]) == 1 + assert len(sponsor_lookup_response_body["results"][0]["orgunits"]) == 1 - attached_unit = sponsor_lookup_response_body["results"][0]["units"][0] + attached_unit = sponsor_lookup_response_body["results"][0]["orgunits"][0] assert attached_unit["id"] == unit_foo.id # Check that hierarchical_access is set to False for the link between the sponsor and unit diff --git a/gregsite/settings/base.py b/gregsite/settings/base.py index 4661b7ba0699a48c7151ed0e3f0909bb01e32141..2d9f564218e9de15077db1aa6556a9587d399705 100644 --- a/gregsite/settings/base.py +++ b/gregsite/settings/base.py @@ -64,8 +64,6 @@ MIDDLEWARE = [ "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "django_structlog.middlewares.RequestMiddleware", - # Refresh oicd token - "mozilla_django_oidc.middleware.SessionRefresh", "gregsite.middleware.revision_user_middleware.RevisionUserMiddleware", ] @@ -78,15 +76,10 @@ AUTHENTICATION_BACKENDS = [ SESAME_MAX_AGE = 600 # lifetime of token in seconds SESSION_COOKIE_AGE = 1800 # lifetime of session in seconds - -CSRF_COOKIE_SAMESITE = "Strict" -SESSION_COOKIE_SAMESITE = "Strict" -# CSRF_COOKIE_HTTPONLY = True -# SESSION_COOKIE_HTTPONLY = True - -# Enable these in production -# CSRF_COOKIE_SECURE = True -# SESSION_COOKIE_SECURE = True +CSRF_COOKIE_SAMESITE = "Lax" +SESSION_COOKIE_SAMESITE = "Lax" +CSRF_COOKIE_HTTPONLY = False +SESSION_COOKIE_HTTPONLY = False REST_FRAMEWORK = { "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.NamespaceVersioning", diff --git a/gregsite/settings/dev.py b/gregsite/settings/dev.py index e989299f3e37394bcb514220b71ec4a9ba6d2d1a..514eb8c480064973a139abc6e45aa4d377e2dce5 100644 --- a/gregsite/settings/dev.py +++ b/gregsite/settings/dev.py @@ -44,13 +44,6 @@ AUTHENTICATION_BACKENDS = [ LOGIN_REDIRECT_URL = "http://localhost:3000/" LOGOUT_REDIRECT_URL = "http://localhost:3000/" -CSRF_COOKIE_SAMESITE = "Strict" -SESSION_COOKIE_SAMESITE = "Lax" -# CSRF_COOKIE_HTTPONLY = True -# SESSION_COOKIE_HTTPONLY = True - -SESSION_COOKIE_AGE = 1209600 # two weeks for easy development - LOGGING = { "version": 1, "disable_existing_loggers": False, diff --git a/gregui/api/serializers/guest.py b/gregui/api/serializers/guest.py index 4836baf9fcb3fa16d570b09b909a15531981bfc6..112b200fed9915223488070fa19723484387c3e8 100644 --- a/gregui/api/serializers/guest.py +++ b/gregui/api/serializers/guest.py @@ -1,3 +1,5 @@ +import datetime + from rest_framework import serializers from greg.models import Identity, Person @@ -20,17 +22,17 @@ class GuestRegisterSerializer(serializers.ModelSerializer): required=False, validators=[validate_norwegian_national_id_number] ) passport = serializers.CharField(required=False) + date_of_birth = serializers.DateField(required=False) def update(self, instance, validated_data): - mobile_phone = validated_data.pop("mobile_phone") - if "email" in validated_data: email = validated_data.pop("email") create_identity_or_update( Identity.IdentityType.PRIVATE_EMAIL, email, instance ) - if not instance.private_mobile: + if "mobile_phone" in validated_data: + mobile_phone = validated_data.pop("mobile_phone") create_identity_or_update( Identity.IdentityType.PRIVATE_MOBILE_NUMBER, mobile_phone, instance ) @@ -54,8 +56,24 @@ class GuestRegisterSerializer(serializers.ModelSerializer): if "last_name" in validated_data: instance.last_name = validated_data["last_name"] + if "date_of_birth" in validated_data: + instance.date_of_birth = validated_data["date_of_birth"] + return instance + def validate_date_of_birth(self, date_of_birth): + today = datetime.date.today() + + # Check that the date of birth is between the interval starting about 100 years ago and last year + if ( + not today - datetime.timedelta(weeks=100 * 52) + < date_of_birth + < today - datetime.timedelta(weeks=52) + ): + raise serializers.ValidationError("Invalid date of birth") + + return date_of_birth + class Meta: model = Person fields = ( @@ -66,6 +84,7 @@ class GuestRegisterSerializer(serializers.ModelSerializer): "mobile_phone", "fnr", "passport", + "date_of_birth", ) read_only_fields = ("id",) diff --git a/gregui/api/serializers/role.py b/gregui/api/serializers/role.py index 722c8e8f4a71f8387d525093d766c778263b8b60..0b867f092a1ca0f6eea1d9a1f71cbd9aa703a175 100644 --- a/gregui/api/serializers/role.py +++ b/gregui/api/serializers/role.py @@ -29,6 +29,12 @@ class RoleSerializerUi(serializers.ModelSerializer): ] def validate_start_date(self, start_date): + """Enfore rules for start_date. + + Must be present, can be blank, before today not allowed. + """ + if not start_date: + return start_date today = datetime.date.today() # New start dates cannot be in the past if start_date < today: @@ -54,9 +60,6 @@ class RoleSerializerUi(serializers.ModelSerializer): raise ValidationError( "A sponsor can only make changes to roles at units they are sponsors for." ) - # If we are updating an existing roles, we must be the sponsor of the role - if self.instance and self.instance.sponsor != sponsor: - raise ValidationError("You can only edit your own roles.") return unit def validate(self, attrs): @@ -69,7 +72,7 @@ class RoleSerializerUi(serializers.ModelSerializer): max_days = today + datetime.timedelta(days=attrs["type"].max_days) if attrs["end_date"] > max_days: raise serializers.ValidationError( - f"New end date too far into the future for this type. Must be before {max_days.strftime('%Y-%m-%d')}" + f"New end date too far into the future for this type. Must be before {max_days.strftime('%Y-%m-%d')}." ) # Ensure end date is after start date if start date is set if self.instance: @@ -84,6 +87,11 @@ class RoleSerializerUi(serializers.ModelSerializer): raise serializers.ValidationError( "End date cannot be before start date." ) + # If we are updating an existing roles, we must be the sponsor of the role + sponsor = self.context["sponsor"] + if self.instance and self.instance.sponsor != sponsor: + raise ValidationError("You can only edit your own roles.") + return attrs diff --git a/gregui/api/views/invitation.py b/gregui/api/views/invitation.py index aa2dd0698a66b70d5cd73020ae3f8e19ccf0fdff..bf32e2e7ef00d8a7f4c06a6df20f27126f6e542e 100644 --- a/gregui/api/views/invitation.py +++ b/gregui/api/views/invitation.py @@ -150,6 +150,7 @@ class InvitedGuestView(GenericAPIView): "fnr", "mobile_phone", "passport", + "date_of_birth", ] fields_allowed_to_update_if_feide = ["mobile_phone"] @@ -182,23 +183,16 @@ class InvitedGuestView(GenericAPIView): else SessionType.FEIDE.value ) - fnr = self._get_identity_or_none( - person, Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER - ) - passport = self._get_identity_or_none( - person, Identity.IdentityType.PASSPORT_NUMBER - ) - feide_id = self._get_identity_or_none(person, Identity.IdentityType.FEIDE_ID) - data = { "person": { "first_name": person.first_name, "last_name": person.last_name, "email": person.private_email and person.private_email.value, "mobile_phone": person.private_mobile and person.private_mobile.value, - "fnr": fnr, - "passport": passport, - "feide_id": feide_id, + "date_of_birth": person.date_of_birth, + "fnr": person.fnr and person.fnr.value, + "passport": person.passport and person.passport.value, + "feide_id": person.feide_id and person.feide_id.value, }, "sponsor": { "first_name": sponsor.first_name, diff --git a/gregui/api/views/role.py b/gregui/api/views/role.py index 7424b2858c5d60b845c3d5eb8146491cd41a7e74..f81e83aa57a9af7717157d90a5ace70873c5d7d9 100644 --- a/gregui/api/views/role.py +++ b/gregui/api/views/role.py @@ -1,5 +1,5 @@ from django.db import transaction -from rest_framework import serializers, status +from rest_framework import status from rest_framework.authentication import BasicAuthentication, SessionAuthentication from rest_framework.viewsets import ModelViewSet from rest_framework.permissions import IsAuthenticated @@ -18,7 +18,10 @@ class RoleInfoViewSet(ModelViewSet): serializer_class = RoleSerializerUi def partial_update(self, request, pk): - role = Role.objects.get(pk=pk) + try: + role = Role.objects.get(pk=pk) + except Role.DoesNotExist: + return Response(status=status.HTTP_400_BAD_REQUEST) sponsor = GregUserProfile.objects.get(user=self.request.user).sponsor with transaction.atomic(): serializer = self.serializer_class( diff --git a/gregui/api/views/userinfo.py b/gregui/api/views/userinfo.py index a16fe70caca461454a5b6df79e505d326e6f28a1..b2e17997d1c50815c546f824839438480e9f9425 100644 --- a/gregui/api/views/userinfo.py +++ b/gregui/api/views/userinfo.py @@ -3,13 +3,12 @@ from typing import ( Type, ) -from rest_framework import permissions from rest_framework.authentication import BaseAuthentication, SessionAuthentication from rest_framework.permissions import AllowAny, BasePermission from rest_framework.status import HTTP_403_FORBIDDEN from rest_framework.views import APIView from rest_framework.response import Response -from greg.models import Identity, InvitationLink +from greg.models import InvitationLink from gregui.models import GregUserProfile @@ -27,112 +26,77 @@ class UserInfoView(APIView): def get(self, request, format=None): """ - Get info about the visiting user + Get info about the visiting user. Works for users logged in using Feide, and those relying solely on an - invitation id. - - TODO: Can this be modified into a permission class to reduce clutter? + invitation id. Pure django users, and anonymous users are denied access. """ user = request.user invite_id = request.session.get("invite_id") - # Authenticated user, allow access - if user.is_authenticated: - user_profile = GregUserProfile.objects.get(user=user) - sponsor_id = None - person_id = None - if user_profile.sponsor: - sponsor_id = user_profile.sponsor.id - if user_profile.person: - person_id = user_profile.person.id - content = { - "feide_id": user_profile.userid_feide, - "sponsor_id": sponsor_id, - "person_id": person_id, - "roles": [], - } - person = user_profile.person - if person: - passports = person.identities.filter( - type=Identity.IdentityType.PASSPORT_NUMBER - ).first() + person = None + sponsor = None + content = { + "feide_id": None, + "sponsor_id": None, + "person_id": None, + "roles": [], + } + # Fetch sponsor and/or person object from profile of authenticated user + if user.is_authenticated: + try: + user_profile = GregUserProfile.objects.get(user=user) + sponsor = user_profile.sponsor + person = user_profile.person content.update( { - "first_name": person.first_name, - "last_name": person.last_name, - "email": person.private_email and person.private_email.value, - "mobile_phone": person.private_mobile - and person.private_mobile.value, - "fnr": person.fnr and "".join((person.fnr.value[:-5], "*****")), - "passport": passports and passports.value, - "roles": [], + "feide_id": user_profile.userid_feide, } ) - roles = person.roles - if roles: - content.update( - { - "roles": [ - { - "id": role.id, - "ou_nb": role.orgunit.name_nb, - "ou_en": role.orgunit.name_en, - "name_nb": role.type.name_nb, - "name_en": role.type.name_en, - "start_date": role.start_date, - "end_date": role.end_date, - "sponsor": { - "first_name": role.sponsor.first_name, - "last_name": role.sponsor.last_name, - }, - } - for role in roles.all() - ], - } - ) - return Response(content) + except GregUserProfile.DoesNotExist: + return Response(status=HTTP_403_FORBIDDEN) - # Invitation cookie, allow access + # Or fetch person info for invited guest elif invite_id: link = InvitationLink.objects.get(uuid=invite_id) - invitation = link.invitation - person = invitation.role.person - passports = person.identities.filter( - type=Identity.IdentityType.PASSPORT_NUMBER - ).first() - - content = { - "feide_id": None, - "sponsor_id": None, - "person_id": person.id, - "first_name": person.first_name, - "last_name": person.last_name, - "email": person.private_email and person.private_email.value, - "mobile_phone": person.private_mobile and person.private_mobile.value, - "fnr": person.fnr and "".join((person.fnr.value[:-5], "*****")), - "passport": passports and passports.value, - "roles": [ - { - "id": role.id, - "ou_nb": role.orgunit.name_nb, - "ou_en": role.orgunit.name_en, - "name_nb": role.type.name_nb, - "name_en": role.type.name_en, - "start_date": role.start_date, - "end_date": role.end_date, - "sponsor": { - "first_name": role.sponsor.first_name, - "last_name": role.sponsor.last_name, - }, - } - for role in person.roles.all() - ], - } - - return Response(content) + person = link.invitation.role.person - # Neither, deny access + # Otherwise, deny access else: return Response(status=HTTP_403_FORBIDDEN) + + # Add sponsor fields if sponsor object present + if sponsor: + content.update({"sponsor_id": user_profile.sponsor.id}) + # Add person fields if person object present + if person: + content.update( + { + "person_id": person.id, + "first_name": person.first_name, + "last_name": person.last_name, + "email": person.private_email and person.private_email.value, + "mobile_phone": person.private_mobile + and person.private_mobile.value, + "fnr": person.fnr and "".join((person.fnr.value[:-5], "*****")), + "passport": person.passport and person.passport.value, + "roles": [ + { + "id": role.id, + "ou_nb": role.orgunit.name_nb, + "ou_en": role.orgunit.name_en, + "name_nb": role.type.name_nb, + "name_en": role.type.name_en, + "start_date": role.start_date, + "end_date": role.end_date, + "sponsor": { + "first_name": role.sponsor.first_name, + "last_name": role.sponsor.last_name, + }, + } + for role in person.roles.all() + ], + } + ) + return Response(content) diff --git a/gregui/authentication/auth_backends.py b/gregui/authentication/auth_backends.py index 5240629d54bed79c53507b15f15750602d99923b..ee6f7aac20ac917f17bd0a67dd0a70f8180970c7 100644 --- a/gregui/authentication/auth_backends.py +++ b/gregui/authentication/auth_backends.py @@ -428,12 +428,12 @@ class GregOIDCBackend(ValidatingOIDCBackend): def _update_person_email(self, person: Person, new_email: str, source: str): """Add or update a users email.""" - logger.bind(identity_type=Identity.IdentityType.PRIVATE_EMAIL) + logger.bind(identity_type=Identity.IdentityType.FEIDE_EMAIL) # We only look at emails from the same source. emails: list[Identity] = [ x for x in person.identities.filter( - type=Identity.IdentityType.PRIVATE_EMAIL + type=Identity.IdentityType.FEIDE_EMAIL ).all() if x.source == source ] @@ -469,7 +469,7 @@ class GregOIDCBackend(ValidatingOIDCBackend): email_id = Identity( person=person, source=source, - type=Identity.IdentityType.PRIVATE_EMAIL, + type=Identity.IdentityType.FEIDE_EMAIL, value=new_email, verified=Identity.Verified.AUTOMATIC, verified_at=make_aware(datetime.datetime.now()), @@ -528,6 +528,7 @@ class GregOIDCBackend(ValidatingOIDCBackend): if userinfo["auth_type"] == "feide" and sponsor: sponsor.first_name = userinfo["first_name"] sponsor.last_name = userinfo["last_name"] + sponsor.work_email = userinfo["email"] sponsor.save() def _get_or_create_greg_user_profile(self, userinfo: dict, user: UserModel): diff --git a/gregui/tests/api/serializers/__init__.py b/gregui/tests/api/serializers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/gregui/tests/api/serializers/test_role.py b/gregui/tests/api/serializers/test_role.py new file mode 100644 index 0000000000000000000000000000000000000000..b36c2b7c4e152b7a82851a2612cd2806f0e276ba --- /dev/null +++ b/gregui/tests/api/serializers/test_role.py @@ -0,0 +1,209 @@ +import datetime +import re + +import pytest +from django.utils import timezone +from rest_framework.exceptions import ValidationError + +from gregui.api.serializers.role import RoleSerializerUi + + +@pytest.mark.django_db +def test_minimum_ok(role, sponsor_foo): + """The minimum amount of fields works""" + ser = RoleSerializerUi( + data={ + "person": role.person.id, + "orgunit": role.orgunit.id, + "type": role.type.id, + "start_date": None, + "end_date": (timezone.now() + datetime.timedelta(days=10)).date(), + }, + context={"sponsor": sponsor_foo}, + ) + assert ser.is_valid(raise_exception=True) + + +@pytest.mark.django_db +def test_start_date_past_fail(role, sponsor_foo): + """Should fail because of start_date in the past""" + ser = RoleSerializerUi( + data={ + "person": role.person.id, + "orgunit": role.orgunit.id, + "type": role.type.id, + "start_date": (timezone.now() - datetime.timedelta(days=10)).date(), + "end_date": (timezone.now() + datetime.timedelta(days=10)).date(), + }, + context={"sponsor": sponsor_foo}, + ) + with pytest.raises( + ValidationError, + match=re.escape( + "{'start_date': [ErrorDetail(string='Start date cannot be in the past', code='invalid')]}" + ), + ): + ser.is_valid(raise_exception=True) + + +@pytest.mark.django_db +def test_end_date_past_fail(role, sponsor_foo): + """Should fail because of end_date in the past""" + ser = RoleSerializerUi( + data={ + "person": role.person.id, + "orgunit": role.orgunit.id, + "type": role.type.id, + "start_date": datetime.date.today(), + "end_date": (timezone.now() - datetime.timedelta(days=10)).date(), + }, + context={"sponsor": sponsor_foo}, + ) + with pytest.raises( + ValidationError, + match=re.escape( + "{'end_date': [ErrorDetail(string='End date cannot be in the past', code='invalid')]}" + ), + ): + ser.is_valid(raise_exception=True) + + +@pytest.mark.django_db +def test_end_date_expired_role_fail(role, sponsor_foo): + """New end date fail because role has ended""" + # Expire the role to ensure failure + role.end_date = datetime.date.today() - datetime.timedelta(days=10) + role.save() + # Try to change it + ser = RoleSerializerUi( + instance=role, + data={ + "person": role.person.id, + "orgunit": role.orgunit.id, + "type": role.type.id, + "start_date": datetime.date.today(), + "end_date": (timezone.now() + datetime.timedelta(days=10)).date(), + }, + context={"sponsor": sponsor_foo}, + ) + # Verify that a validation error is raised + with pytest.raises( + ValidationError, + match=re.escape( + "{'end_date': [ErrorDetail(string='Role has ended, cannot change end date', code='invalid')]}" + ), + ): + ser.is_valid(raise_exception=True) + + +@pytest.mark.django_db +def test_wrong_sponsor(role, sponsor_foo, sponsor_bar): + """Touching another sponsor's roles does not work""" + # Try to touch sponsor_foo's guest role as sponsor_bar + ser = RoleSerializerUi( + instance=role, + data={ + "person": role.person.id, + "orgunit": role.orgunit.id, + "type": role.type.id, + "start_date": datetime.date.today(), + "end_date": (timezone.now() + datetime.timedelta(days=10)).date(), + }, + context={"sponsor": sponsor_bar}, + ) + # Verify that a validation error is raised + with pytest.raises( + ValidationError, + match=re.escape( + "{'non_field_errors': [ErrorDetail(string='You can only edit your own roles.', code='invalid')]}" + ), + ): + ser.is_valid(raise_exception=True) + + +@pytest.mark.django_db +def test_too_future_end_date(role, sponsor_foo): + """Setting the end date further than max_days of role_type fails""" + max_future = timezone.now().date() + datetime.timedelta(days=role.type.max_days) + ser = RoleSerializerUi( + instance=role, + data={ + "person": role.person.id, + "orgunit": role.orgunit.id, + "type": role.type.id, + "start_date": datetime.date.today(), + "end_date": max_future + datetime.timedelta(days=1), + }, + context={"sponsor": sponsor_foo}, + ) + # Verify that a validation error is raised + with pytest.raises( + ValidationError, + match=re.escape( + "".join( + [ + "{'non_field_errors': [ErrorDetail(string=", + f"'New end date too far into the future for this type. Must be before {max_future}.'", + ", code='invalid')]}", + ] + ) + ), + ): + ser.is_valid(raise_exception=True) + + +@pytest.mark.django_db +def test_end_before_start(role, sponsor_foo): + """Setting the end date before start date not allowed""" + # Existing instance + ser = RoleSerializerUi( + instance=role, + data={ + "person": role.person.id, + "orgunit": role.orgunit.id, + "type": role.type.id, + "start_date": datetime.date.today() + datetime.timedelta(days=1), + "end_date": datetime.date.today(), + }, + context={"sponsor": sponsor_foo}, + ) + # Verify that a validation error is raised + with pytest.raises( + ValidationError, + match=re.escape( + "".join( + [ + "{'non_field_errors': [ErrorDetail(string=", + "'End date cannot be before start date.'", + ", code='invalid')]}", + ] + ) + ), + ): + ser.is_valid(raise_exception=True) + + # New instance + ser = RoleSerializerUi( + data={ + "person": role.person.id, + "orgunit": role.orgunit.id, + "type": role.type.id, + "start_date": datetime.date.today() + datetime.timedelta(days=1), + "end_date": datetime.date.today(), + }, + context={"sponsor": sponsor_foo}, + ) + # Verify that a validation error is raised + with pytest.raises( + ValidationError, + match=re.escape( + "".join( + [ + "{'non_field_errors': [ErrorDetail(string=", + "'End date cannot be before start date.'", + ", code='invalid')]}", + ] + ) + ), + ): + ser.is_valid(raise_exception=True) diff --git a/gregui/tests/api/views/__init__.py b/gregui/tests/api/views/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/gregui/tests/api/test_invitation.py b/gregui/tests/api/views/test_invitation.py similarity index 90% rename from gregui/tests/api/test_invitation.py rename to gregui/tests/api/views/test_invitation.py index a94f4daf9d98afefbb22e9429ec2e2dd3ddc5f8b..bd1e7d172e1a487c3c2a8e22f45b0c88a53f6e93 100644 --- a/gregui/tests/api/test_invitation.py +++ b/gregui/tests/api/views/test_invitation.py @@ -73,6 +73,7 @@ def test_get_invited_info_session_okay( fnr=None, passport=None, feide_id=None, + date_of_birth=None, ) assert data.get("sponsor") == dict( first_name=sponsor_foo_data["first_name"], @@ -390,3 +391,44 @@ def test_post_info_fail_unknown_field(client, invited_person_verified_nin): # Verify rejection assert response.status_code == status.HTTP_400_BAD_REQUEST + + +@pytest.mark.django_db +def test_date_of_birth_stored(client, invited_person_verified_nin): + _, invitation_link = invited_person_verified_nin + + session = client.session + session["invite_id"] = str(invitation_link.uuid) + session.save() + + date_of_birth = "1995-10-28" + url = reverse("gregui-v1:invited-info") + data = {"person": {"mobile_phone": "+4797543992", "date_of_birth": date_of_birth}} + response = client.post(url, data, format="json") + + assert response.status_code == status.HTTP_200_OK + + person = Person.objects.get() + assert ( + person.date_of_birth + == datetime.datetime.strptime(date_of_birth, "%Y-%m-%d").date() + ) + + +@pytest.mark.django_db +def test_invalid_date_of_birth_rejected(client, invited_person_verified_nin): + _, invitation_link = invited_person_verified_nin + + session = client.session + session["invite_id"] = str(invitation_link.uuid) + session.save() + + date_of_birth = "1900-03-16" + url = reverse("gregui-v1:invited-info") + data = {"person": {"mobile_phone": "+4797543992", "date_of_birth": date_of_birth}} + response = client.post(url, data, format="json") + + assert response.status_code == status.HTTP_400_BAD_REQUEST + + person = Person.objects.get() + assert person.date_of_birth is None diff --git a/gregui/tests/api/test_invite_guest.py b/gregui/tests/api/views/test_invite_guest.py similarity index 100% rename from gregui/tests/api/test_invite_guest.py rename to gregui/tests/api/views/test_invite_guest.py diff --git a/gregui/tests/api/test_person.py b/gregui/tests/api/views/test_person.py similarity index 100% rename from gregui/tests/api/test_person.py rename to gregui/tests/api/views/test_person.py diff --git a/gregui/tests/api/views/test_role.py b/gregui/tests/api/views/test_role.py new file mode 100644 index 0000000000000000000000000000000000000000..3b740f9ec366e315b1dbc661a0d73e80a3119758 --- /dev/null +++ b/gregui/tests/api/views/test_role.py @@ -0,0 +1,139 @@ +import datetime +import pytest +from django.utils import timezone +from rest_framework.reverse import reverse +from rest_framework import status + +from greg.models import OrganizationalUnit + + +@pytest.mark.django_db +def test_role_anon_post(client): + """Should get 403 forbidden since we are not a sponsor""" + resp = client.post(reverse("gregui-v1:role-list"), data={}) + assert resp.status_code == status.HTTP_403_FORBIDDEN + + +@pytest.mark.django_db +def test_role_anon_patch(client): + """Should get 403 forbidden since we are not a sponsor""" + resp = client.patch(reverse("gregui-v1:role-detail", kwargs={"pk": 1}), data={}) + assert resp.status_code == status.HTTP_403_FORBIDDEN + + +@pytest.mark.django_db +def test_role_sponsor_post_ok(client, log_in, user_sponsor, role): + """Should work since we are a sponsor at this unit""" + log_in(user_sponsor) + resp = client.post( + reverse("gregui-v1:role-list"), + data={ + "person": role.person.id, + "type": role.type.id, + "orgunit": role.orgunit.id, + "start_date": "", + "end_date": (timezone.now() + datetime.timedelta(days=10)).strftime( + "%Y-%m-%d" + ), + }, + ) + assert resp.content == b"" + assert resp.status_code == status.HTTP_201_CREATED + + +@pytest.mark.django_db +def test_role_sponsor_post_no_data_fail(client, log_in, user_sponsor): + """Should fail since we did not provide any role data""" + log_in(user_sponsor) + resp = client.post(reverse("gregui-v1:role-list"), data={}) + assert resp.status_code == status.HTTP_400_BAD_REQUEST + + +@pytest.mark.django_db +def test_role_sponsor_post_fail(client, log_in, user_sponsor, role): + """Should fail since we are not a sponsor at this unit.""" + # Unit the sponsor is not connected to so that we fail + ou = OrganizationalUnit.objects.create(name_nb="foo", name_en="foo_en") + + log_in(user_sponsor) + resp = client.post( + reverse("gregui-v1:role-list"), + data={ + "person": role.person.id, + "type": role.type.id, + "orgunit": ou.id, + "start_date": "", + "end_date": (timezone.now() + datetime.timedelta(days=10)).strftime( + "%Y-%m-%d" + ), + }, + ) + assert ( + resp.content + == b'{"orgunit":["A sponsor can only make changes to roles at units they are sponsors for."]}' + ) + assert resp.status_code == status.HTTP_400_BAD_REQUEST + + +@pytest.mark.django_db +def test_role_sponsor_patch_ok( + client, + log_in, + user_sponsor, + role, +): + """Should work since we are the sponsor owning the role.""" + log_in(user_sponsor) + new_date = (timezone.now() + datetime.timedelta(days=10)).date() + + resp = client.patch( + reverse("gregui-v1:role-detail", kwargs={"pk": role.id}), + data={ + "end_date": new_date.strftime("%Y-%m-%d"), + }, + ) + assert resp.status_code == status.HTTP_200_OK + # Verify the new date was set + role.refresh_from_db() + assert role.end_date == new_date + + +@pytest.mark.django_db +def test_role_sponsor_patch_fail(client, log_in, user_sponsor, role): + """Should fail since we are not a sponsor at this unit.""" + + # Unit the sponsor is not connected to so that we fail + ou = OrganizationalUnit.objects.create(name_nb="foo", name_en="foo_en") + + log_in(user_sponsor) + resp = client.patch( + reverse("gregui-v1:role-detail", kwargs={"pk": role.id}), + data={ + "orgunit": ou.id, + }, + ) + assert ( + resp.content + == b'{"orgunit":["A sponsor can only make changes to roles at units they are sponsors for."]}' + ) + assert resp.status_code == status.HTTP_400_BAD_REQUEST + + +@pytest.mark.django_db +def test_role_sponsor_patch_fail_unknown_role( + client, + log_in, + user_sponsor, +): + """Should fail since the role does not exist""" + log_in(user_sponsor) + new_date = (timezone.now() + datetime.timedelta(days=10)).date() + + resp = client.patch( + reverse("gregui-v1:role-detail", kwargs={"pk": 1}), + data={ + "end_date": new_date.strftime("%Y-%m-%d"), + }, + ) + assert resp.content == b"" + assert resp.status_code == status.HTTP_400_BAD_REQUEST diff --git a/gregui/tests/api/views/test_userinfo.py b/gregui/tests/api/views/test_userinfo.py new file mode 100644 index 0000000000000000000000000000000000000000..c5caaa302600e3a60d26b4e2fd2fede220749e06 --- /dev/null +++ b/gregui/tests/api/views/test_userinfo.py @@ -0,0 +1,78 @@ +import pytest +from rest_framework.reverse import reverse +from rest_framework import status + + +@pytest.mark.django_db +def test_userinfo_anon_get(client): + """Anonymous people should be forbidden.""" + response = client.get(reverse("api-userinfo")) + assert response.status_code == status.HTTP_403_FORBIDDEN + + +@pytest.mark.django_db +def test_userinfo_invited_get(client, invitation_link): + """Invited guests should get info about themself and the role.""" + session = client.session + session["invite_id"] = str(invitation_link.uuid) + session.save() + response = client.get(reverse("api-userinfo")) + assert response.status_code == status.HTTP_200_OK + assert response.json() == { + "feide_id": None, + "sponsor_id": None, + "person_id": 1, + "first_name": "Foo", + "last_name": "Bar", + "email": "foo@example.org", + "mobile_phone": None, + "fnr": None, + "passport": None, + "roles": [ + { + "id": 1, + "ou_nb": "Foo NB", + "ou_en": "Foo EN", + "name_nb": "Role Foo NB", + "name_en": "Role Foo EN", + "start_date": None, + "end_date": "2050-10-15", + "sponsor": {"first_name": "Sponsor", "last_name": "Bar"}, + } + ], + } + + +@pytest.mark.django_db +def test_userinfo_sponsor_get(client, log_in, user_sponsor): + """Sponsors should get info about themselves""" + log_in(user_sponsor) + + response = client.get(reverse("api-userinfo")) + assert response.status_code == status.HTTP_200_OK + assert response.json() == { + "feide_id": "", + "person_id": None, + "roles": [], + "sponsor_id": 1, + } + + +@pytest.mark.django_db +def test_userinfo_guest_get(client, log_in, user_person): + """Logged in guests should get info about themself""" + log_in(user_person) + response = client.get(reverse("api-userinfo")) + assert response.status_code == status.HTTP_200_OK + assert response.json() == { + "feide_id": "", + "sponsor_id": None, + "person_id": 1, + "roles": [], + "first_name": "Foo", + "last_name": "Bar", + "email": "foo@bar.com", + "mobile_phone": None, + "fnr": "123456*****", + "passport": None, + } diff --git a/gregui/tests/authentication/test_user_profile.py b/gregui/tests/authentication/test_user_profile.py index 0ea99b399a26eb6e45c829d1d24efc4abf672d46..a5d60c956db1babd51cab8cfeb72da917169c313 100644 --- a/gregui/tests/authentication/test_user_profile.py +++ b/gregui/tests/authentication/test_user_profile.py @@ -37,7 +37,7 @@ def test_sponsor_first_login(sponsor_foo): @pytest.mark.django_db -def test_sponsor_update_name(sponsor_foo): +def test_sponsor_update(sponsor_foo): auth_request = RequestFactory().get("/foo", {"code": "foo", "state": "bar"}) auth_request.session = {} @@ -47,12 +47,15 @@ def test_sponsor_update_name(sponsor_foo): with pytest.raises(GregUserProfile.DoesNotExist): GregUserProfile.objects.get(sponsor=sponsor_foo) + assert sponsor_foo.first_name == "Sponsor" + assert sponsor_foo.work_email == "foo@example.org" + claims = { "sub": "subsub", "connect-userid_sec": [f"feide:{sponsor_foo.feide_id}"], "dataporten-userid_sec": [f"feide:{sponsor_foo.feide_id}", "nin:12345612345"], "name": f"Baz {sponsor_foo.last_name}", - "email": "foo@example.org", + "email": "baz@example.org", "email_verified": True, "picture": "https://foo.org/p:2192dff7-6989-4244-83cc-ae5e78875bdd", } @@ -63,6 +66,7 @@ def test_sponsor_update_name(sponsor_foo): assert user_profile.sponsor == sponsor_foo assert user_profile.sponsor.first_name == "Baz" + assert user_profile.sponsor.work_email == "baz@example.org" @pytest.mark.django_db @@ -158,7 +162,7 @@ def test_invited_user(invited_person): "connect-userid_sec": [f"feide:{feide_id}"], "dataporten-userid_sec": [f"feide:{feide_id}", f"nin:{nin}"], "name": f"{person.first_name} {person.last_name}", - "email": f"{person.private_email.value}", + "email": f"{feide_id}", "email_verified": True, "picture": "https://foo.org/p:2192dff7-6989-4244-83cc-ae5e78875bdd", } @@ -172,18 +176,25 @@ def test_invited_user(invited_person): person_nins = person.identities.filter( type=Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER, - verified=Identity.Verified.AUTOMATIC, - ).all() - person_feide_ids = person.identities.filter( - type=Identity.IdentityType.FEIDE_ID, verified=Identity.Verified.AUTOMATIC ).all() assert len(person_nins) == 1 assert person_nins[0].verified == Identity.Verified.AUTOMATIC assert person_nins[0].value == nin + + person_feide_ids = person.identities.filter( + type=Identity.IdentityType.FEIDE_ID, + ).all() assert len(person_feide_ids) == 1 assert person_feide_ids[0].verified == Identity.Verified.AUTOMATIC assert person_feide_ids[0].value == feide_id + person_feide_email = person.identities.filter( + type=Identity.IdentityType.FEIDE_EMAIL + ).all() + assert len(person_feide_email) == 1 + assert person_feide_email[0].value == feide_id + assert person_feide_email[0].verified == Identity.Verified.AUTOMATIC + @pytest.mark.django_db def test_invited_user_no_id(invited_person_no_ids): @@ -224,7 +235,7 @@ def test_invited_user_no_id(invited_person_no_ids): "connect-userid_sec": ["feide:{feide_id}"], "dataporten-userid_sec": [f"feide:{feide_id}", f"nin:{nin}"], "name": f"{person.first_name} {person.last_name}", - "email": f"{person.private_email.value}", + "email": f"{feide_id}", "email_verified": True, "picture": "https://foo.org/p:2192dff7-6989-4244-83cc-ae5e78875bdd", } @@ -236,18 +247,21 @@ def test_invited_user_no_id(invited_person_no_ids): person_nins = person.identities.filter( type=Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER, - verified=Identity.Verified.AUTOMATIC, - ).all() - person_feide_ids = person.identities.filter( - type=Identity.IdentityType.FEIDE_ID, verified=Identity.Verified.AUTOMATIC ).all() assert len(person_nins) == 1 assert person_nins[0].value == nin assert person_nins[0].verified == Identity.Verified.AUTOMATIC + + person_feide_ids = person.identities.filter( + type=Identity.IdentityType.FEIDE_ID + ).all() assert len(person_feide_ids) == 1 assert person_feide_ids[0].value == feide_id assert person_feide_ids[0].verified == Identity.Verified.AUTOMATIC - -def test_nin_feide(): - pass + person_feide_email = person.identities.filter( + type=Identity.IdentityType.FEIDE_EMAIL + ).all() + assert len(person_feide_email) == 1 + assert person_feide_email[0].value == feide_id + assert person_feide_email[0].verified == Identity.Verified.AUTOMATIC diff --git a/gregui/tests/conftest.py b/gregui/tests/conftest.py index b7f6e8f6c8ce4d793ae5789361df4c7f3d49c3aa..797760461eb0c73c363961cff2ebecbc697d8801 100644 --- a/gregui/tests/conftest.py +++ b/gregui/tests/conftest.py @@ -82,11 +82,12 @@ def role_type_foo() -> RoleType: @pytest.fixture def create_sponsor() -> Callable[[str, str, str, OrganizationalUnit], Sponsor]: - def create_sponsor(feide_id, first_name, last_name, unit): + def create_sponsor(feide_id, first_name, last_name, unit, work_email=None): sponsor = Sponsor( feide_id=feide_id, first_name=first_name, last_name=last_name, + work_email=work_email, ) sponsor.save() @@ -99,7 +100,12 @@ def create_sponsor() -> Callable[[str, str, str, OrganizationalUnit], Sponsor]: @pytest.fixture def sponsor_foo_data() -> dict: - return dict(feide_id="foo@example.org", first_name="Sponsor", last_name="Bar") + return dict( + feide_id="foo@example.org", + first_name="Sponsor", + last_name="Bar", + work_email="foo@example.org", + ) @pytest.fixture @@ -109,6 +115,13 @@ def sponsor_foo( return create_sponsor(**sponsor_foo_data, unit=unit_foo) +@pytest.fixture +def sponsor_bar(unit_foo: OrganizationalUnit, create_sponsor) -> Sponsor: + return create_sponsor( + feide_id="bar@example.com", first_name="Bar", last_name="Baz", unit=unit_foo + ) + + @pytest.fixture def create_user() -> Callable[[str, str, str, str], UserModel]: user_model = get_user_model() @@ -144,6 +157,23 @@ def user_sponsor(sponsor_foo: Sponsor, create_user) -> User: return user_model.objects.get(id=user.id) +@pytest.fixture +def user_person(person_foo: Sponsor, create_user) -> User: + user_model = get_user_model() + + # Create a user and link him to a sponsor + user = create_user( + username="test_person", + email="person@example.org", + first_name="Test", + last_name="Person", + ) + GregUserProfile.objects.create(user=user, person=person_foo) + + # This user is a sponsor for unit_foo + return user_model.objects.get(id=user.id) + + @pytest.fixture def create_greg_user_profile() -> Callable[ [UserModel, Optional[Person], Optional[Sponsor]], GregUserProfile diff --git a/gregui/urls.py b/gregui/urls.py index cc6fa884e2da3bc3a1884dcb83b4382a0f0ac9f9..c8a47cbfd83d1644e146a099de86790e6898a16b 100644 --- a/gregui/urls.py +++ b/gregui/urls.py @@ -19,7 +19,7 @@ urlpatterns: List[URLResolver] = [ path("api/ui/v1/session/", views.SessionView.as_view(), name="api-session"), path("api/ui/v1/testmail/", views.send_test_email, name="api-testmail"), path("api/ui/v1/whoami/", views.WhoAmIView.as_view(), name="api-whoami"), - path("api/ui/v1/userinfo/", UserInfoView.as_view()), # type: ignore + path("api/ui/v1/userinfo/", UserInfoView.as_view(), name="api-userinfo"), # type: ignore path("api/ui/v1/ous/", OusView.as_view()), path("api/ui/v1/guests/", GuestInfoView.as_view()), ]