diff --git a/app/client/models/AppModel.ts b/app/client/models/AppModel.ts index 06799a1d..76885753 100644 --- a/app/client/models/AppModel.ts +++ b/app/client/models/AppModel.ts @@ -7,7 +7,9 @@ import {Features} from 'app/common/Features'; import {GristLoadConfig} from 'app/common/gristUrls'; import {FullUser} from 'app/common/LoginSessionAPI'; import {LocalPlugin} from 'app/common/plugin'; +import {UserPrefs} from 'app/common/Prefs'; import {getOrgName, Organization, OrgError, UserAPI, UserAPIImpl} from 'app/common/UserAPI'; +import {getUserPrefsObs} from 'app/client/models/UserPrefs'; import {bundleChanges, Computed, Disposable, Observable, subscribe} from 'grainjs'; export {reportError} from 'app/client/models/errors'; @@ -58,6 +60,7 @@ export interface AppModel { orgError?: OrgError; // If currentOrg is null, the error that caused it. currentFeatures: Features; // features of the current org's product. + userPrefsObs: Observable; pageType: Observable; @@ -177,6 +180,8 @@ export class AppModelImpl extends Disposable implements AppModel { public readonly currentFeatures = (this.currentOrg && this.currentOrg.billingAccount) ? this.currentOrg.billingAccount.product.features : {}; + public readonly userPrefsObs = getUserPrefsObs(this); + // Get the current PageType from the URL. public readonly pageType: Observable = Computed.create(this, urlState().state, (use, state) => (state.doc ? "doc" : (state.billing ? "billing" : (state.welcome ? "welcome" : "home")))); diff --git a/app/client/models/UserPrefs.ts b/app/client/models/UserPrefs.ts index c853fdd2..625152c8 100644 --- a/app/client/models/UserPrefs.ts +++ b/app/client/models/UserPrefs.ts @@ -1,40 +1,60 @@ import {localStorageObs} from 'app/client/lib/localStorageObs'; import {AppModel} from 'app/client/models/AppModel'; -import {UserOrgPrefs} from 'app/common/Prefs'; +import {UserOrgPrefs, UserPrefs} from 'app/common/Prefs'; import {Computed, Observable} from 'grainjs'; -/** - * Creates an observable that returns UserOrgPrefs, and which stores them when set. - * - * For anon user, the prefs live in localStorage. Note that the observable isn't actually watching - * for changes on the server, it will only change when set. - */ -export function getUserOrgPrefsObs(appModel: AppModel): Observable { - const savedPrefs = appModel.currentValidUser ? appModel.currentOrg?.userOrgPrefs : undefined; - if (savedPrefs) { - const prefsObs = Observable.create(null, savedPrefs); - return Computed.create(null, (use) => use(prefsObs)) - .onWrite(userOrgPrefs => { - prefsObs.set(userOrgPrefs); - return appModel.api.updateOrg('current', {userOrgPrefs}); - }); - } else { - const userId = appModel.currentUser?.id || 0; - const jsonPrefsObs = localStorageObs(`userOrgPrefs:u=${userId}`); - return Computed.create(null, jsonPrefsObs, (use, p) => (p && JSON.parse(p) || {}) as UserOrgPrefs) - .onWrite(userOrgPrefs => { - jsonPrefsObs.set(JSON.stringify(userOrgPrefs)); - }); - } +interface PrefsTypes { + userOrgPrefs: UserOrgPrefs; + userPrefs: UserPrefs; } -/** - * Creates an observable that returns a particular preference value from `prefsObs`, and which - * stores it when set. - */ -export function getUserOrgPrefObs( - prefsObs: Observable, prefName: Name -): Observable { - return Computed.create(null, (use) => use(prefsObs)[prefName]) - .onWrite(value => prefsObs.set({...prefsObs.get(), [prefName]: value})); +function makePrefFunctions

(prefsTypeName: P) { + type PrefsType = PrefsTypes[P]; + + /** + * Creates an observable that returns UserOrgPrefs, and which stores them when set. + * + * For anon user, the prefs live in localStorage. Note that the observable isn't actually watching + * for changes on the server, it will only change when set. + */ + function getPrefsObs(appModel: AppModel): Observable { + const savedPrefs = appModel.currentValidUser ? appModel.currentOrg?.[prefsTypeName] : undefined; + if (savedPrefs) { + const prefsObs = Observable.create(null, savedPrefs!); + return Computed.create(null, (use) => use(prefsObs)) + .onWrite(prefs => { + prefsObs.set(prefs); + return appModel.api.updateOrg('current', {[prefsTypeName]: prefs}); + }); + } else { + const userId = appModel.currentUser?.id || 0; + const jsonPrefsObs = localStorageObs(`${prefsTypeName}:u=${userId}`); + return Computed.create(null, jsonPrefsObs, (use, p) => (p && JSON.parse(p) || {}) as PrefsType) + .onWrite(prefs => { + jsonPrefsObs.set(JSON.stringify(prefs)); + }); + } + } + + /** + * Creates an observable that returns a particular preference value from `prefsObs`, and which + * stores it when set. + */ + function getPrefObs( + prefsObs: Observable, prefName: Name + ): Observable { + return Computed.create(null, (use) => use(prefsObs)[prefName]) + .onWrite(value => prefsObs.set({...prefsObs.get(), [prefName]: value})); + } + + return {getPrefsObs, getPrefObs}; } + +// Functions actually exported are: +// - getUserOrgPrefsObs(appModel): Observsble +// - getUserOrgPrefObs(userOrgPrefsObs, prefName): Observsble +// - getUserPrefsObs(appModel): Observsble +// - getUserPrefObs(userPrefsObs, prefName): Observsble + +export const {getPrefsObs: getUserOrgPrefsObs, getPrefObs: getUserOrgPrefObs} = makePrefFunctions('userOrgPrefs'); +export const {getPrefsObs: getUserPrefsObs, getPrefObs: getUserPrefObs} = makePrefFunctions('userPrefs'); diff --git a/app/client/ui/DocMenu.ts b/app/client/ui/DocMenu.ts index 073cdcfb..58acb3d0 100644 --- a/app/client/ui/DocMenu.ts +++ b/app/client/ui/DocMenu.ts @@ -13,6 +13,7 @@ import {buildHomeIntro} from 'app/client/ui/HomeIntro'; import {buildPinnedDoc, createPinnedDocs} from 'app/client/ui/PinnedDocs'; import {shadowScroll} from 'app/client/ui/shadowScroll'; import {transition} from 'app/client/ui/transitions'; +import {showWelcomeQuestions} from 'app/client/ui/WelcomeQuestions'; import {buttonSelect, cssButtonSelect} from 'app/client/ui2018/buttonSelect'; import {colors} from 'app/client/ui2018/cssVars'; import {icon} from 'app/client/ui2018/icons'; @@ -48,6 +49,7 @@ export function createDocMenu(home: HomeModel) { function createLoadedDocMenu(home: HomeModel) { const flashDocId = observable(null); return css.docList( + showWelcomeQuestions(home.app.userPrefsObs), dom.maybe(!home.app.currentFeatures.workspaces, () => [ css.docListHeader('This service is not available right now'), dom('span', '(The organization needs a paid plan)') diff --git a/app/client/ui/WelcomeQuestions.ts b/app/client/ui/WelcomeQuestions.ts new file mode 100644 index 00000000..5db8c0a8 --- /dev/null +++ b/app/client/ui/WelcomeQuestions.ts @@ -0,0 +1,161 @@ +import {getUserPrefObs} from 'app/client/models/UserPrefs'; +import {colors, testId} from 'app/client/ui2018/cssVars'; +import {icon} from 'app/client/ui2018/icons'; +import {IconName} from 'app/client/ui2018/IconList'; +import {ISaveModalOptions, saveModal} from 'app/client/ui2018/modals'; +import {BaseAPI} from 'app/common/BaseAPI'; +import {UserPrefs} from 'app/common/Prefs'; +import {dom, input, Observable, styled, subscribeElem} from 'grainjs'; + +export function showWelcomeQuestions(userPrefsObs: Observable) { + if (!userPrefsObs.get()?.showNewUserQuestions) { + return null; + } + + return saveModal((ctl, owner): ISaveModalOptions => { + const selection = choices.map(c => Observable.create(owner, false)); + const otherText = Observable.create(owner, ''); + const showQuestions = getUserPrefObs(userPrefsObs, 'showNewUserQuestions'); + + async function onConfirm() { + const selected = choices.filter((c, i) => selection[i].get()).map(c => c.text); + const use_cases = ['L', ...selected]; // Format to populate a ChoiceList column + const use_other = selected.includes('Other') ? otherText.get() : ''; + + const submitUrl = new URL(window.location.href); + submitUrl.pathname = '/welcome/info'; + return BaseAPI.requestJson(submitUrl.href, + {method: 'POST', body: JSON.stringify({use_cases, use_other})}); + } + + // Whichever way the modal is closed, don't show the questions again. (We set the value to + // undefined to remove it from the JSON prefs object entirely; it's never used again.) + owner.onDispose(() => showQuestions.set(undefined)); + + return { + title: [cssLogo(), dom('div', 'Welcome to Grist!')], + body: buildInfoForm(selection, otherText), + saveLabel: 'Start using Grist', + saveFunc: onConfirm, + hideCancel: true, + width: 'fixed-wide', + modalArgs: cssModalCentered.cls(''), + }; + }); +} + +const choices: Array<{icon: IconName, color: string, text: string}> = [ + {icon: 'UseProduct', color: `${colors.lightGreen}`, text: 'Product Development' }, + {icon: 'UseFinance', color: '#0075A2', text: 'Finance & Accounting'}, + {icon: 'UseMedia', color: '#F7B32B', text: 'Media Production' }, + {icon: 'UseMonitor', color: '#F2545B', text: 'IT & Technology' }, + {icon: 'UseChart', color: '#7141F9', text: 'Marketing' }, + {icon: 'UseScience', color: '#231942', text: 'Research' }, + {icon: 'UseSales', color: '#885A5A', text: 'Sales' }, + {icon: 'UseEducate', color: '#4A5899', text: 'Education' }, + {icon: 'UseHr', color: '#688047', text: 'HR & Management' }, + {icon: 'UseOther', color: '#929299', text: 'Other' }, +]; + +function buildInfoForm(selection: Observable[], otherText: Observable) { + return [ + dom('span', 'What brings you to Grist? Please help us serve you better.'), + cssChoices( + choices.map((item, i) => cssChoice( + cssIcon(icon(item.icon), {style: `--icon-color: ${item.color}`}), + cssChoice.cls('-selected', selection[i]), + dom.on('click', () => selection[i].set(!selection[i].get())), + (item.icon !== 'UseOther' ? + item.text : + [ + cssOtherLabel(item.text), + cssOtherInput(otherText, {}, {type: 'text', placeholder: 'Type here'}, + // The following subscribes to changes to selection observable, and focuses the input when + // this item is selected. + (elem) => subscribeElem(elem, selection[i], val => val && setTimeout(() => elem.focus(), 0)), + // It's annoying if clicking into the input toggles selection; better to turn that + // off (user can click icon to deselect). + dom.on('click', ev => ev.stopPropagation()), + // Similarly, ignore Enter/Escape in "Other" textbox, so that they don't submit/close the form. + dom.onKeyDown({ + Enter: (ev, elem) => elem.blur(), + Escape: (ev, elem) => elem.blur(), + }), + ) + ] + ) + )), + testId('welcome-questions'), + ), + ]; +} + +const cssModalCentered = styled('div', ` + text-align: center; +`); + +const cssLogo = styled('div', ` + display: inline-block; + height: 48px; + width: 48px; + background-image: var(--icon-GristLogo); + background-size: 32px 32px; + background-repeat: no-repeat; + background-position: center; +`); + +const cssChoices = styled('div', ` + display: flex; + flex-wrap: wrap; + align-items: center; + margin-top: 24px; +`); + +const cssChoice = styled('div', ` + flex: 1 0 40%; + min-width: 0px; + margin: 8px 4px 0 4px; + height: 40px; + border: 1px solid ${colors.darkGrey}; + border-radius: 3px; + display: flex; + align-items: center; + text-align: left; + cursor: pointer; + + &:hover { + border-color: ${colors.lightGreen}; + } + &-selected { + background-color: ${colors.mediumGrey}; + } + &-selected:hover { + border-color: ${colors.darkGreen}; + } + &-selected:focus-within { + box-shadow: 0 0 2px 0px var(--grist-color-cursor); + border-color: ${colors.lightGreen}; + } +`); + +const cssIcon = styled('div', ` + margin: 0 16px; +`); + +const cssOtherLabel = styled('div', ` + display: block; + .${cssChoice.className}-selected & { + display: none; + } +`); + +const cssOtherInput = styled(input, ` + display: none; + border: none; + background: none; + outline: none; + padding: 0px; + .${cssChoice.className}-selected & { + display: block; + } +`); diff --git a/app/client/ui2018/IconList.ts b/app/client/ui2018/IconList.ts index cc29296f..6cad31e2 100644 --- a/app/client/ui2018/IconList.ts +++ b/app/client/ui2018/IconList.ts @@ -97,7 +97,17 @@ export type IconName = "ChartArea" | "Warning" | "Widget" | "Wrap" | - "Zoom"; + "Zoom" | + "UseChart" | + "UseEducate" | + "UseFinance" | + "UseHr" | + "UseMedia" | + "UseMonitor" | + "UseOther" | + "UseProduct" | + "UseSales" | + "UseScience"; export const IconList: IconName[] = ["ChartArea", "ChartBar", @@ -198,4 +208,14 @@ export const IconList: IconName[] = ["ChartArea", "Warning", "Widget", "Wrap", - "Zoom"]; + "Zoom", + "UseChart", + "UseEducate", + "UseFinance", + "UseHr", + "UseMedia", + "UseMonitor", + "UseOther", + "UseProduct", + "UseSales", + "UseScience"]; diff --git a/app/client/ui2018/modals.ts b/app/client/ui2018/modals.ts index d37d53ba..6e80428d 100644 --- a/app/client/ui2018/modals.ts +++ b/app/client/ui2018/modals.ts @@ -2,7 +2,7 @@ import {FocusLayer} from 'app/client/lib/FocusLayer'; import * as Mousetrap from 'app/client/lib/Mousetrap'; import {reportError} from 'app/client/models/errors'; import {bigBasicButton, bigPrimaryButton, cssButton} from 'app/client/ui2018/buttons'; -import {colors, testId, vars} from 'app/client/ui2018/cssVars'; +import {colors, mediaSmall, testId, vars} from 'app/client/ui2018/cssVars'; import {loadingSpinner} from 'app/client/ui2018/loaders'; import {waitGrainObs} from 'app/common/gutil'; import {Computed, Disposable, dom, DomContents, DomElementArg, MultiHolder, Observable, styled} from 'grainjs'; @@ -347,6 +347,13 @@ const cssModalDialog = styled('div', ` &-fixed-wide { width: 600px; } + @media ${mediaSmall} { + & { + width: unset; + min-width: unset; + padding: 24px 16px; + } + } `); export const cssModalTitle = styled('div', ` @@ -381,6 +388,7 @@ const cssModalBacker = styled('div', ` height: 100%; top: 0; left: 0; + padding: 16px; z-index: 999; background-color: ${colors.backdrop}; overflow-y: auto; diff --git a/app/common/Prefs.ts b/app/common/Prefs.ts index 31789959..a035916b 100644 --- a/app/common/Prefs.ts +++ b/app/common/Prefs.ts @@ -6,14 +6,18 @@ export type SortPref = typeof SortPref.type; export const ViewPref = StringUnion("list", "icons"); export type ViewPref = typeof ViewPref.type; - // A collection of preferences related to a user or org (or combination). export interface Prefs { - // TODO replace this with real preferences. + // A dummy field used only in tests. placeholder?: string; } -export type UserPrefs = Prefs; +// A collection of preferences related to a user or org (or combination). +export interface UserPrefs extends Prefs { + // Whether to ask the user to fill out a form about their use-case, on opening the DocMenu page. + // Set to true on first login, then reset when the form is closed, so that it only shows once. + showNewUserQuestions?: boolean; +} export interface UserOrgPrefs extends Prefs { docMenuSort?: SortPref; diff --git a/app/server/lib/FlexServer.ts b/app/server/lib/FlexServer.ts index 15b2644a..7d526d56 100644 --- a/app/server/lib/FlexServer.ts +++ b/app/server/lib/FlexServer.ts @@ -1095,10 +1095,20 @@ export class FlexServer implements GristServer { if (req.params.page === 'user') { const name: string|undefined = req.body && req.body.username || undefined; + + // Reset isFirstTimeUser flag, used to redirect a new user to the /welcome/user page. await this._dbManager.updateUser(userId, {name, isFirstTimeUser: false}); - redirectPath = '/welcome/info'; + + // This is a good time to set another flag (showNewUserQuestions), to show a popup with + // welcome question(s) to this new user. Both flags are scoped to the user, but + // isFirstTimeUser has a dedicated DB field because it predates userPrefs. Note that the + // updateOrg() method handles all levels of prefs (for user, user+org, or org). + await this._dbManager.updateOrg(getScope(req), 0, {userPrefs: {showNewUserQuestions: true}}); } else if (req.params.page === 'info') { + // The /welcome/info page is no longer part of any flow, but if visited, will still submit + // here and redirect. The new form with new-user questions appears in a modal popup. It + // also posts here to save answers, but ignores the response. const user = getUser(req); const row = {...req.body, UserID: userId, Name: user.name, Email: user.loginEmail}; this._recordNewUserInfo(row) @@ -1106,14 +1116,14 @@ export class FlexServer implements GristServer { // If we failed to record, at least log the data, so we could potentially recover it. log.rawWarn(`Failed to record new user info: ${e.message}`, {newUserQuestions: row}); }); + } - // redirect to teams page if users has access to more than one org. Otherwise redirect to - // personal org. - const result = await this._dbManager.getMergedOrgs(userId, userId, domain || null); - const orgs = (result.status === 200) ? result.data : null; - if (orgs && orgs.length > 1) { - redirectPath = '/welcome/teams'; - } + // redirect to teams page if users has access to more than one org. Otherwise redirect to + // personal org. + const result = await this._dbManager.getMergedOrgs(userId, userId, domain || null); + const orgs = (result.status === 200) ? result.data : null; + if (orgs && orgs.length > 1) { + redirectPath = '/welcome/teams'; } const mergedOrgDomain = this._dbManager.mergedOrgDomain(); diff --git a/static/icons/icons.css b/static/icons/icons.css index 9cc60e64..19fd3cce 100644 --- a/static/icons/icons.css +++ b/static/icons/icons.css @@ -99,4 +99,14 @@ --icon-Widget: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEuNSwxIEMxLjIyMzg1NzYzLDEgMSwxLjIyMzg1NzYzIDEsMS41IEwxLDUuNSBDMSw1Ljc3NjE0MjM3IDEuMjIzODU3NjMsNiAxLjUsNiBMNS41LDYgQzUuNzc2MTQyMzcsNiA2LDUuNzc2MTQyMzcgNiw1LjUgTDYsMS41IEM2LDEuMjIzODU3NjMgNS43NzYxNDIzNywxIDUuNSwxIEwxLjUsMSBaIE0xLjUsMCBMNS41LDAgQzYuMzI4NDI3MTIsLTEuNjY1MzM0NTRlLTE2IDcsMC42NzE1NzI4NzUgNywxLjUgTDcsNS41IEM3LDYuMzI4NDI3MTIgNi4zMjg0MjcxMiw3IDUuNSw3IEwxLjUsNyBDMC42NzE1NzI4NzUsNyAxLjY2NTMzNDU0ZS0xNiw2LjMyODQyNzEyIDAsNS41IEwwLDEuNSBDLTguMzI2NjcyNjhlLTE3LDAuNjcxNTcyODc1IDAuNjcxNTcyODc1LDEuNjY1MzM0NTRlLTE2IDEuNSwwIFogTTEyLjY5NDQxNTQsMS4xMTE4MDg5IEMxMi41ODcwMjEyLDEuMDA0NDE0NzIgMTIuNDEyOTAwOCwxLjAwNDQxNDcyIDEyLjMwNTUwNjcsMS4xMTE4MDg5IEwxMC4xMTIwNjE0LDMuMzA1MjU0MTMgQzEwLjAwNDY2NzMsMy40MTI2NDgzMSAxMC4wMDQ2NjczLDMuNTg2NzY4NjggMTAuMTEyMDYxNCwzLjY5NDE2Mjg2IEwxMi4zMDU1MDY3LDUuODg3NjA4MSBDMTIuNDEyOTAwOCw1Ljk5NTAwMjI4IDEyLjU4NzAyMTIsNS45OTUwMDIyOCAxMi42OTQ0MTU0LDUuODg3NjA4MSBMMTQuODg3ODYwNiwzLjY5NDE2Mjg2IEMxNC45OTUyNTQ4LDMuNTg2NzY4NjggMTQuOTk1MjU0OCwzLjQxMjY0ODMxIDE0Ljg4Nzg2MDYsMy4zMDUyNTQxMyBMMTIuNjk0NDE1NCwxLjExMTgwODkgWiBNMTMuNDAxNTIyMiwwLjQwNDcwMjExOCBMMTUuNTk0OTY3NCwyLjU5ODE0NzM1IEMxNi4wOTI4ODU5LDMuMDk2MDY1ODIgMTYuMDkyODg1OSwzLjkwMzM1MTE3IDE1LjU5NDk2NzQsNC40MDEyNjk2NCBMMTMuNDAxNTIyMiw2LjU5NDcxNDg4IEMxMi45MDM2MDM3LDcuMDkyNjMzMzUgMTIuMDk2MzE4NCw3LjA5MjYzMzM1IDExLjU5ODM5OTksNi41OTQ3MTQ4OCBMOS40MDQ5NTQ2NSw0LjQwMTI2OTY0IEM4LjkwNzAzNjE4LDMuOTAzMzUxMTcgOC45MDcwMzYxOCwzLjA5NjA2NTgyIDkuNDA0OTU0NjUsMi41OTgxNDczNSBMMTEuNTk4Mzk5OSwwLjQwNDcwMjExOCBDMTIuMDk2MzE4NCwtMC4wOTMyMTYzNTQzIDEyLjkwMzYwMzcsLTAuMDkzMjE2MzU0MyAxMy40MDE1MjIyLDAuNDA0NzAyMTE4IFogTTEuNSwxMCBDMS4yMjM4NTc2MywxMCAxLDEwLjIyMzg1NzYgMSwxMC41IEwxLDE0LjUgQzEsMTQuNzc2MTQyNCAxLjIyMzg1NzYzLDE1IDEuNSwxNSBMNS41LDE1IEM1Ljc3NjE0MjM3LDE1IDYsMTQuNzc2MTQyNCA2LDE0LjUgTDYsMTAuNSBDNiwxMC4yMjM4NTc2IDUuNzc2MTQyMzcsMTAgNS41LDEwIEwxLjUsMTAgWiBNMS41LDkgTDUuNSw5IEM2LjMyODQyNzEyLDkgNyw5LjY3MTU3Mjg4IDcsMTAuNSBMNywxNC41IEM3LDE1LjMyODQyNzEgNi4zMjg0MjcxMiwxNiA1LjUsMTYgTDEuNSwxNiBDMC42NzE1NzI4NzUsMTYgMS42NjUzMzQ1NGUtMTYsMTUuMzI4NDI3MSAwLDE0LjUgTDAsMTAuNSBDLTguMzI2NjcyNjhlLTE3LDkuNjcxNTcyODggMC42NzE1NzI4NzUsOSAxLjUsOSBaIE0xMC41LDEwIEMxMC4yMjM4NTc2LDEwIDEwLDEwLjIyMzg1NzYgMTAsMTAuNSBMMTAsMTQuNSBDMTAsMTQuNzc2MTQyNCAxMC4yMjM4NTc2LDE1IDEwLjUsMTUgTDE0LjUsMTUgQzE0Ljc3NjE0MjQsMTUgMTUsMTQuNzc2MTQyNCAxNSwxNC41IEwxNSwxMC41IEMxNSwxMC4yMjM4NTc2IDE0Ljc3NjE0MjQsMTAgMTQuNSwxMCBMMTAuNSwxMCBaIE0xMC41LDkgTDE0LjUsOSBDMTUuMzI4NDI3MSw5IDE2LDkuNjcxNTcyODggMTYsMTAuNSBMMTYsMTQuNSBDMTYsMTUuMzI4NDI3MSAxNS4zMjg0MjcxLDE2IDE0LjUsMTYgTDEwLjUsMTYgQzkuNjcxNTcyODgsMTYgOSwxNS4zMjg0MjcxIDksMTQuNSBMOSwxMC41IEM5LDkuNjcxNTcyODggOS42NzE1NzI4OCw5IDEwLjUsOSBaIiBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48L3N2Zz4='); --icon-Wrap: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTksMTIgTDksMTMgTDguMzA3ODIzNjYsMTEuOTYxNzM1NSBDOC4xMjcwNjQ4MywxMS44ODY0MTQ4IDgsMTEuNzA4MDQ2MiA4LDExLjUgQzgsMTEuMjkxOTUzOCA4LjEyNzA2NDgzLDExLjExMzU4NTIgOC4zMDc4MjI3NCwxMS4wMzgyNjU5IEw5LDEwIEw5LDExIEwxMS4zMjYwODcsMTEgQzEyLjI0NjY0MTUsMTEgMTMsMTAuMjIwMjczOSAxMyw5LjI1IEMxMyw4LjI3OTcyNjA1IDEyLjI0NjY0MTUsNy41IDExLjMyNjA4Nyw3LjUgTDIuNSw3LjUgQzIuMjIzODU3NjMsNy41IDIsNy4yNzYxNDIzNyAyLDcgQzIsNi43MjM4NTc2MyAyLjIyMzg1NzYzLDYuNSAyLjUsNi41IEwxMS4zMjYwODcsNi41IEMxMi44MDY3NzA1LDYuNSAxNCw3LjczNDk5MjU3IDE0LDkuMjUgQzE0LDEwLjc2NTAwNzQgMTIuODA2NzcwNSwxMiAxMS4zMjYwODcsMTIgTDksMTIgWiBNMi41LDIgTDEzLjUsMiBDMTMuNzc2MTQyNCwyIDE0LDIuMjIzODU3NjMgMTQsMi41IEMxNCwyLjc3NjE0MjM3IDEzLjc3NjE0MjQsMyAxMy41LDMgTDIuNSwzIEMyLjIyMzg1NzYzLDMgMiwyLjc3NjE0MjM3IDIsMi41IEMyLDIuMjIzODU3NjMgMi4yMjM4NTc2MywyIDIuNSwyIFogTTIuNSwxMSBMNS41LDExIEM1Ljc3NjE0MjM3LDExIDYsMTEuMjIzODU3NiA2LDExLjUgQzYsMTEuNzc2MTQyNCA1Ljc3NjE0MjM3LDEyIDUuNSwxMiBMMi41LDEyIEMyLjIyMzg1NzYzLDEyIDIsMTEuNzc2MTQyNCAyLDExLjUgQzIsMTEuMjIzODU3NiAyLjIyMzg1NzYzLDExIDIuNSwxMSBaIiBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48L3N2Zz4='); --icon-Zoom: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEyLDQgTDcuNSw0IEM3LjIyMzg1NzYzLDQgNywzLjc3NjE0MjM3IDcsMy41IEM3LDMuMjIzODU3NjMgNy4yMjM4NTc2MywzIDcuNSwzIEwxMi41LDMgQzEyLjc3NjE0MjQsMyAxMywzLjIyMzg1NzYzIDEzLDMuNSBMMTMsOC41IEMxMyw4Ljc3NjE0MjM3IDEyLjc3NjE0MjQsOSAxMi41LDkgQzEyLjIyMzg1NzYsOSAxMiw4Ljc3NjE0MjM3IDEyLDguNSBMMTIsNCBaIE00LDEyIEw4LjUsMTIgQzguNzc2MTQyMzcsMTIgOSwxMi4yMjM4NTc2IDksMTIuNSBDOSwxMi43NzYxNDI0IDguNzc2MTQyMzcsMTMgOC41LDEzIEwzLjUsMTMgQzMuMjIzODU3NjMsMTMgMywxMi43NzYxNDI0IDMsMTIuNSBMMyw3LjUgQzMsNy4yMjM4NTc2MyAzLjIyMzg1NzYzLDcgMy41LDcgQzMuNzc2MTQyMzcsNyA0LDcuMjIzODU3NjMgNCw3LjUgTDQsMTIgWiIgZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJub256ZXJvIi8+PC9zdmc+'); + --icon-UseChart: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEzIDNDMTMgMi40NDc3MiAxMy40NDc3IDIgMTQgMiAxNC41NTIzIDIgMTUgMi40NDc3MiAxNSAzVjE0QzE1IDE0LjU1MjMgMTQuNTUyMyAxNSAxNCAxNSAxMy40NDc3IDE1IDEzIDE0LjU1MjMgMTMgMTRWM3pNOSA4QzkgNy40NDc3MiA5LjQ0NzcyIDcgMTAgNyAxMC41NTIzIDcgMTEgNy40NDc3MiAxMSA4VjE0QzExIDE0LjU1MjMgMTAuNTUyMyAxNSAxMCAxNSA5LjQ0NzcyIDE1IDkgMTQuNTUyMyA5IDE0Vjh6TTUgNkM1IDUuNDQ3NzIgNS40NDc3MiA1IDYgNSA2LjU1MjI4IDUgNyA1LjQ0NzcyIDcgNlYxNEM3IDE0LjU1MjMgNi41NTIyOCAxNSA2IDE1IDUuNDQ3NzIgMTUgNSAxNC41NTIzIDUgMTRWNnpNMSAxMUMxIDEwLjQ0NzcgMS40NDc3MiAxMCAyIDEwIDIuNTUyMjggMTAgMyAxMC40NDc3IDMgMTFWMTRDMyAxNC41NTIzIDIuNTUyMjggMTUgMiAxNSAxLjQ0NzcyIDE1IDEgMTQuNTUyMyAxIDE0VjExeiIgZmlsbD0iIzcxNDFGOSIvPjwvc3ZnPg=='); + --icon-UseEducate: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzQzOV84NDUxKSIgZmlsbD0iIzRBNTg5OSI+PHBhdGggZD0iTTE1LjUwMDEgNC4xMDAzOUw4LjUwMDEgMC4xMDAzOTFDOC4yMDAxIDAuMDAwMzkwNjI2IDcuODAwMSAwLjAwMDM5MDYyNiA3LjUwMDEgMC4xMDAzOTFMMC41MDAwOTggNC4xMDAzOUMtMC4xOTk5MDIgNC41MDAzOSAtMC4xOTk5MDIgNS41MDAzOSAwLjUwMDA5OCA1LjgwMDM5TDcuNTAwMSA5LjgwMDM5QzcuODAwMSAxMC4wMDA0IDguMjAwMSAxMC4wMDA0IDguNTAwMSA5LjgwMDM5TDE1LjUwMDEgNS44MDAzOUMxNi4yMDAxIDUuNTAwMzkgMTYuMjAwMSA0LjUwMDM5IDE1LjUwMDEgNC4xMDAzOVoiLz48cGF0aCBkPSJNOS41IDExLjZDOSAxMS45IDguNSAxMiA4IDEyQzcuNSAxMiA3IDExLjkgNi41IDExLjZMMiA5VjEzQzIgMTUuMSA1LjEgMTYgOCAxNkMxMC45IDE2IDE0IDE1LjEgMTQgMTNWOUw5LjUgMTEuNloiLz48L2c+PGRlZnM+PGNsaXBQYXRoIGlkPSJjbGlwMF80MzlfODQ1MSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTAgMEgxNlYxNkgweiIvPjwvY2xpcFBhdGg+PC9kZWZzPjwvc3ZnPg=='); + --icon-UseFinance: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTguMzY3MTkgOS42ODE2NFYxMC45NzgzQzguODM5MTkgMTAuODk4MyA5LjA3NTE5IDEwLjY5MzYgOS4wNzUxOSAxMC4zNjM2IDkuMDc1MTkgMTAuMDEyMyA4LjY4ODUyIDkuODI4OTcgOC4zNjcxOSA5LjY4MTY0ek02Ljk4MTkzIDcuMjAzMTNDNi45ODE5MyA3LjU3MTEzIDcuMzE0NiA3LjczNTggNy42NTM5MyA3Ljg4NTEzVjYuNjYxMTNDNy4yMDU5MyA2LjcyNzEzIDYuOTgxOTMgNi45MDc4IDYuOTgxOTMgNy4yMDMxM3oiIGZpbGw9IiMwMDc1QTIiLz48cGF0aCBkPSJNMTEuOTk5OSAyTDkuOTk5OTIgMEw3Ljk5OTkyIDJMNS45OTk5MiAwTDMuOTk5OTIgMkwxLjMzMzI1IDBWMTUuMzMzM0MxLjMzMzI1IDE1LjcwMiAxLjYzMTkyIDE2IDEuOTk5OTIgMTZIMTMuOTk5OUMxNC4zNjc5IDE2IDE0LjY2NjYgMTUuNzAyIDE0LjY2NjYgMTUuMzMzM1YwTDExLjk5OTkgMlpNOC4zNjcyNSAxMi4yMTg3VjEzLjI4NjdINy42NTM5MlYxMi4yNEM2LjgwNjU5IDEyLjIyMjcgNi4wNjMyNSAxMi4wNzMzIDUuNDI0NTkgMTEuNzkyVjEwLjQxNzNDNi4wMjQ1OSAxMC43MTQgNi45NzY1OSAxMC45NzQgNy42NTM5MiAxMS4wMTZWOS40MDEzM0M2LjQ2MTI1IDguOTM4NjcgNS40MTQ1OSA4LjQ5IDUuNDE0NTkgNy4yMDMzM0M1LjQxNDU5IDYuMDM0NjcgNi40ODY1OSA1LjQ4NTMzIDcuNjUzOTIgNS4zN1Y0LjU3MjY3SDguMzY3MjVWNS4zNDg2N0M5LjE2MTkyIDUuMzgzMzMgOS44ODEyNSA1LjU0MzMzIDEwLjUyMzMgNS44MjhMMTAuMDMzOSA3LjA0NjY3QzkuNDkyNTkgNi44MjQ2NyA4LjkzNjU5IDYuNjg5MzMgOC4zNjcyNSA2LjY0MDY3VjguMTc3MzNDOS42MzI1OSA4LjY2NCAxMC42NDMzIDkuMTA3MzMgMTAuNjQzMyAxMC4yODY3QzEwLjY0MzMgMTEuNTMgOS42MTA1OSAxMi4xMDQ3IDguMzY3MjUgMTIuMjE4N1oiIGZpbGw9IiMwMDc1QTIiLz48L3N2Zz4='); + --icon-UseHr: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTE1LjI3NTEgMTAuMjkzNEwxMy4wODcxIDkuNjY4MzlDMTIuOTEwMiA5LjYxNzgzIDEyLjc1MDggOS41MTk0OCAxMi42MjYyIDkuMzg0MTZDMTIuNTAxNyA5LjI0ODg0IDEyLjQxNjggOS4wODE3OSAxMi4zODExIDguOTAxMzlMMTIuMjQ3MSA4LjIyNjM5QzEyLjc2OTYgNy45ODc1NyAxMy4yMTI2IDcuNjAzNzMgMTMuNTIzNCA3LjEyMDQ4QzEzLjgzNDEgNi42MzcyNCAxMy45OTk2IDYuMDc0OTMgMTQuMDAwMSA1LjUwMDM5VjQuMTI2MzlDMTQuMDEyMiAzLjMzMDgzIDEzLjcxNjQgMi41NjEzOCAxMy4xNzQ1IDEuOTc4ODJDMTIuNjMyNSAxLjM5NjI3IDExLjg4NjQgMS4wNDU3IDExLjA5MjEgMS4wMDAzOUMxMC40OTkxIDAuOTgyNDk2IDkuOTE0MTIgMS4xNDA4MiA5LjQxMTExIDEuNDU1MzNDOC45MDgwOSAxLjc2OTg1IDguNTA5NjIgMi4yMjY0NCA4LjI2NjA3IDIuNzY3MzlDOC43NDMxMiAzLjQ2MTY3IDguOTk4OTkgNC4yODQwMSA5LjAwMDA3IDUuMTI2MzlWNi41MDAzOUM4Ljk5ODI4IDYuODY0MTYgOC45NDYxMSA3LjIyNTkzIDguODQ1MDcgNy41NzUzOUM5LjEwNDMgNy44NDczMyA5LjQxMjMxIDguMDY4MTYgOS43NTMwNyA4LjIyNjM5TDkuNjE5MDcgOC45MDAzOUM5LjU4MzMgOS4wODA3OSA5LjQ5ODQ4IDkuMjQ3ODQgOS4zNzM5MiA5LjM4MzE2QzkuMjQ5MzYgOS41MTg0OCA5LjA4OTkgOS42MTY4MyA4LjkxMzA3IDkuNjY3MzlMOC4wNzAwNyA5LjkwODM5TDkuNTUwMDcgMTAuMzMxNEM5Ljk2NzI3IDEwLjQ1MTkgMTAuMzM0MSAxMC43MDQ1IDEwLjU5NTYgMTEuMDUxMkMxMC44NTcgMTEuMzk4IDEwLjk5OSAxMS44MjAxIDExLjAwMDEgMTIuMjU0NFYxNC41MDA0QzEwLjk5ODQgMTQuNjcxMSAxMC45NjczIDE0Ljg0MDMgMTAuOTA4MSAxNS4wMDA0SDE1LjUwMDFDMTUuNjMyNyAxNS4wMDA0IDE1Ljc1OTkgMTQuOTQ3NyAxNS44NTM2IDE0Ljg1MzlDMTUuOTQ3NCAxNC43NjAyIDE2LjAwMDEgMTQuNjMzIDE2LjAwMDEgMTQuNTAwNFYxMS4yNTQ0QzE2IDExLjAzNzIgMTUuOTI5MiAxMC44MjYgMTUuNzk4NCAxMC42NTI2QzE1LjY2NzYgMTAuNDc5MiAxNS40ODM5IDEwLjM1MzEgMTUuMjc1MSAxMC4yOTM0WiIgZmlsbD0iIzY4ODA0NyIvPjxwYXRoIGQ9Ik05LjI3NSAxMS4yOTM0TDcuMDg3IDEwLjY2ODRDNi45MTAwNCAxMC42MTc4IDYuNzUwNDkgMTAuNTE5MyA2LjYyNTkyIDEwLjM4MzhDNi41MDEzNSAxMC4yNDgzIDYuNDE2NiAxMC4wODEgNi4zODEgOS45MDA0M0w2LjI0NyA5LjIyNTQzQzYuNzY5NCA4Ljk4NjY5IDcuMjEyMjggOC42MDMgNy41MjMwMyA4LjExOTk1QzcuODMzNzcgNy42MzY5IDcuOTk5MzIgNy4wNzQ4IDggNi41MDA0M1Y1LjEyNjQzQzguMDEyMTMgNC4zMzA4OCA3LjcxNjMyIDMuNTYxNDIgNy4xNzQzOSAyLjk3ODg3QzYuNjMyNDYgMi4zOTYzMSA1Ljg4NjM2IDIuMDQ1NzUgNS4wOTIgMi4wMDA0M0M0LjY5MDM2IDEuOTg4MTEgNC4yOTAzNCAyLjA1NjYgMy45MTU2OCAyLjIwMTg0QzMuNTQxMDEgMi4zNDcwOCAzLjE5OTM1IDIuNTY2MSAyLjkxMDk1IDIuODQ1OTFDMi42MjI1NiAzLjEyNTczIDIuMzkzMzIgMy40NjA2MiAyLjIzNjgzIDMuODMwNzNDMi4wODAzNSA0LjIwMDg0IDEuOTk5ODEgNC41OTg2MSAyIDUuMDAwNDNWNi41MDA0M0MyLjAwMDQ5IDcuMDc0OTcgMi4xNjU5NSA3LjYzNzI5IDIuNDc2NyA4LjEyMDUzQzIuNzg3NDYgOC42MDM3NyAzLjIzMDQ1IDguOTg3NjIgMy43NTMgOS4yMjY0M0wzLjYxOSA5LjkwMDQzQzMuNTgzMjMgMTAuMDgwOCAzLjQ5ODQxIDEwLjI0NzkgMy4zNzM4NSAxMC4zODMyQzMuMjQ5MjkgMTAuNTE4NSAzLjA4OTgzIDEwLjYxNjkgMi45MTMgMTAuNjY3NEwwLjcyNSAxMS4yOTI0QzAuNTE2MDI1IDExLjM1MjIgMC4zMzIyMTQgMTEuNDc4NCAwLjIwMTM5NyAxMS42NTJDMC4wNzA1Nzk2IDExLjgyNTYgLTAuMDAwMTIwNjM2IDEyLjAzNzEgMS41NDUyMWUtMDcgMTIuMjU0NFYxNC41MDA0QzEuNTQ1MjFlLTA3IDE0LjYzMyAwLjA1MjY3ODYgMTQuNzYwMiAwLjE0NjQ0NyAxNC44NTRDMC4yNDAyMTUgMTQuOTQ3OCAwLjM2NzM5MiAxNS4wMDA0IDAuNSAxNS4wMDA0SDkuNUM5LjYzMjYxIDE1LjAwMDQgOS43NTk3OSAxNC45NDc4IDkuODUzNTUgMTQuODU0QzkuOTQ3MzIgMTQuNzYwMiAxMCAxNC42MzMgMTAgMTQuNTAwNFYxMi4yNTQ0QzkuOTk5OSAxMi4wMzczIDkuOTI5MSAxMS44MjYgOS43OTgzIDExLjY1MjZDOS42Njc1IDExLjQ3OTIgOS40ODM4MSAxMS4zNTMyIDkuMjc1IDExLjI5MzRWMTEuMjkzNFoiIGZpbGw9IiM2ODgwNDciLz48L3N2Zz4='); + --icon-UseMedia: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIgMTBWNkgxQzAuNzM0Nzg0IDYgMC40ODA0MyA2LjEwNTM2IDAuMjkyODkzIDYuMjkyODlDMC4xMDUzNTcgNi40ODA0MyAwIDYuNzM0NzggMCA3TDAgMTRDMCAxNC4yNjUyIDAuMTA1MzU3IDE0LjUxOTYgMC4yOTI4OTMgMTQuNzA3MUMwLjQ4MDQzIDE0Ljg5NDYgMC43MzQ3ODQgMTUgMSAxNUgxMUMxMS4yNjUyIDE1IDExLjUxOTYgMTQuODk0NiAxMS43MDcxIDE0LjcwNzFDMTEuODk0NiAxNC41MTk2IDEyIDE0LjI2NTIgMTIgMTRWMTNINUM0LjIwNDM1IDEzIDMuNDQxMjkgMTIuNjgzOSAyLjg3ODY4IDEyLjEyMTNDMi4zMTYwNyAxMS41NTg3IDIgMTAuNzk1NiAyIDEwWiIgZmlsbD0iI0Y3QjMyQiIvPjxwYXRoIGQ9Ik0xNSAxSDVDNC43MzQ3OCAxIDQuNDgwNDMgMS4xMDUzNiA0LjI5Mjg5IDEuMjkyODlDNC4xMDUzNiAxLjQ4MDQzIDQgMS43MzQ3OCA0IDJWMTBDNCAxMC4yNjUyIDQuMTA1MzYgMTAuNTE5NiA0LjI5Mjg5IDEwLjcwNzFDNC40ODA0MyAxMC44OTQ2IDQuNzM0NzggMTEgNSAxMUgxNUMxNS4yNjUyIDExIDE1LjUxOTYgMTAuODk0NiAxNS43MDcxIDEwLjcwNzFDMTUuODk0NiAxMC41MTk2IDE2IDEwLjI2NTIgMTYgMTBWMkMxNiAxLjczNDc4IDE1Ljg5NDYgMS40ODA0MyAxNS43MDcxIDEuMjkyODlDMTUuNTE5NiAxLjEwNTM2IDE1LjI2NTIgMSAxNSAxWk0xMS43MjQgNi40NDdMOC43MjQgNy45NDdDOC42NDc3NyA3Ljk4NTIgOC41NjMwNCA4LjAwMzI3IDguNDc3ODYgNy45OTk0OUM4LjM5MjY4IDcuOTk1NzIgOC4zMDk4OCA3Ljk3MDIyIDguMjM3MzMgNy45MjU0M0M4LjE2NDc4IDcuODgwNjQgOC4xMDQ4OSA3LjgxODAzIDguMDYzMzUgNy43NDM1N0M4LjAyMTgxIDcuNjY5MTEgOCA3LjU4NTI2IDggNy41VjQuNUM4IDQuNDE0NzQgOC4wMjE4MSA0LjMzMDg5IDguMDYzMzUgNC4yNTY0M0M4LjEwNDg5IDQuMTgxOTcgOC4xNjQ3OCA0LjExOTM2IDguMjM3MzMgNC4wNzQ1N0M4LjMwOTg4IDQuMDI5NzggOC4zOTI2OCA0LjAwNDI4IDguNDc3ODYgNC4wMDA1MUM4LjU2MzA0IDMuOTk2NzMgOC42NDc3NyA0LjAxNDggOC43MjQgNC4wNTNMMTEuNzI0IDUuNTUzQzExLjgwNjkgNS41OTQ1NyAxMS44NzY3IDUuNjU4NCAxMS45MjU0IDUuNzM3MzRDMTEuOTc0MiA1LjgxNjI4IDEyIDUuOTA3MjMgMTIgNkMxMiA2LjA5Mjc3IDExLjk3NDIgNi4xODM3MiAxMS45MjU0IDYuMjYyNjZDMTEuODc2NyA2LjM0MTYgMTEuODA2OSA2LjQwNTQzIDExLjcyNCA2LjQ0N1oiIGZpbGw9IiNGN0IzMkIiLz48L3N2Zz4='); + --icon-UseMonitor: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTE1IDBIMUMwLjQgMCAwIDAuNCAwIDFWMTJDMCAxMi42IDAuNCAxMyAxIDEzSDZWMTRIM1YxNkgxM1YxNEgxMFYxM0gxNUMxNS42IDEzIDE2IDEyLjYgMTYgMTJWMUMxNiAwLjQgMTUuNiAwIDE1IDBaTTE0IDJWOUgyVjJIMTRaIiBmaWxsPSIjRjI1NDVCIi8+PC9zdmc+'); + --icon-UseOther: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTE1IDBIMUMwLjQgMCAwIDAuNCAwIDFWMTVDMCAxNS42IDAuNCAxNiAxIDE2SDE1QzE1LjYgMTYgMTYgMTUuNiAxNiAxNVYxQzE2IDAuNCAxNS42IDAgMTUgMFpNOCAxM0M3LjQgMTMgNyAxMi42IDcgMTJDNyAxMS40IDcuNCAxMSA4IDExQzguNiAxMSA5IDExLjQgOSAxMkM5IDEyLjYgOC42IDEzIDggMTNaTTkuNSA4LjRDOSA4LjcgOSA4LjggOSA5VjEwSDdWOUM3IDcuNyA3LjggNy4xIDguNCA2LjdDOC45IDYuNCA5IDYuMyA5IDZDOSA1LjQgOC42IDUgOCA1QzcuNiA1IDcuMyA1LjIgNy4xIDUuNUw2LjYgNi40TDQuOSA1LjRMNS40IDQuNUM1LjkgMy42IDYuOSAzIDggM0M5LjcgMyAxMSA0LjMgMTEgNkMxMSA3LjQgMTAuMSA4IDkuNSA4LjRaIiBmaWxsPSIjOTI5Mjk5Ii8+PC9zdmc+'); + --icon-UseProduct: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTE1LjMzMzMuNjY2OTkySC42NjY2NjdDLjI5ODY2Ny42NjY5OTIgMCAuOTY0OTkyIDAgMS4zMzM2NlYzLjMzMzY2QzAgMy43MDIzMy4yOTg2NjcgNC4wMDAzMy42NjY2NjcgNC4wMDAzM0gxNS4zMzMzQzE1LjcwMTMgNC4wMDAzMyAxNiAzLjcwMjMzIDE2IDMuMzMzNjZWMS4zMzM2NkMxNiAuOTY0OTkyIDE1LjcwMTMuNjY2OTkyIDE1LjMzMzMuNjY2OTkyek0xNC42NjY2IDUuMzMzOThIOS45OTk5MlYxMC42NjczTDcuOTk5OTIgOS4zMzM5OCA1Ljk5OTkyIDEwLjY2NzNWNS4zMzM5OEgxLjMzMzI1VjE0LjY2NzNDMS4zMzMyNSAxNS4wMzUzIDEuNjMxOTIgMTUuMzM0IDEuOTk5OTIgMTUuMzM0SDEzLjk5OTlDMTQuMzY3OSAxNS4zMzQgMTQuNjY2NiAxNS4wMzUzIDE0LjY2NjYgMTQuNjY3M1Y1LjMzMzk4eiIgZmlsbD0iIzE2QjM3OCIvPjwvc3ZnPg=='); + --icon-UseSales: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTE2LjAwMDEgMS4wMDAwMkMxNi4wMDAxIDAuNzM0ODAxIDE1Ljg5NDcgMC40ODA0NDcgMTUuNzA3MiAwLjI5MjkxMUMxNS41MTk2IDAuMTA1Mzc0IDE1LjI2NTMgMS43NDAxOWUtMDUgMTUuMDAwMSAxLjc0MDE5ZS0wNUgxMC40NTAxQzkuODU4ODYgLTAuMDAxNjMyMTcgOS4yNzMyMSAwLjExNDAwOSA4LjcyNzAxIDAuMzQwMjQ2QzguMTgwODIgMC41NjY0ODMgNy42ODQ5MyAwLjg5ODgyIDcuMjY4MDUgMS4zMTgwMkwzLjI5MzA1IDUuMjkzMDJDMy4xMDU1OCA1LjQ4MDU1IDMuMDAwMjcgNS43MzQ4NSAzLjAwMDI3IDYuMDAwMDJDMy4wMDAyNyA2LjI2NTE4IDMuMTA1NTggNi41MTk0OSAzLjI5MzA1IDYuNzA3MDJDMy43NDEyNiA3LjE1NTc2IDQuMzM4MDMgNy40MjUxOSA0Ljk3MTA0IDcuNDY0NkM1LjYwNDA1IDcuNTA0MDIgNi4yMjk2NCA3LjMxMDY5IDYuNzMwMDUgNi45MjEwMkw5LjQxNzA1IDQuODMxMDJMMTMuNjEwMSA5LjAyNDAyQzEzLjcyNzEgOS4xNDEwNCAxMy44MTg3IDkuMjgxMDIgMTMuODc5IDkuNDM1MTVDMTMuOTM5NCA5LjU4OTI3IDEzLjk2NzIgOS43NTQyMiAxMy45NjA3IDkuOTE5NjFDMTMuOTU0MiAxMC4wODUgMTMuOTEzNiAxMC4yNDczIDEzLjg0MTQgMTAuMzk2MkMxMy43NjkxIDEwLjU0NTEgMTMuNjY2OSAxMC42Nzc1IDEzLjU0MTEgMTAuNzg1TDEyLjk3NTEgMTEuMjY4TDExLjM1NDEgOS42NDYwMkMxMS4zMDc2IDkuNTk5NTMgMTEuMjUyNCA5LjU2MjY1IDExLjE5MTYgOS41Mzc0OUMxMS4xMzA5IDkuNTEyMzMgMTEuMDY1OCA5LjQ5OTM5IDExLjAwMDEgOS40OTkzOUMxMC45MzQzIDkuNDk5MzkgMTAuODY5MiA5LjUxMjMzIDEwLjgwODUgOS41Mzc0OUMxMC43NDc3IDkuNTYyNjUgMTAuNjkyNSA5LjU5OTUzIDEwLjY0NjEgOS42NDYwMkMxMC41OTk2IDkuNjkyNSAxMC41NjI3IDkuNzQ3NjkgMTAuNTM3NSA5LjgwODQzQzEwLjUxMjQgOS44NjkxNyAxMC40OTk0IDkuOTM0MjcgMTAuNDk5NCAxMEMxMC40OTk0IDEwLjA2NTggMTAuNTEyNCAxMC4xMzA5IDEwLjUzNzUgMTAuMTkxNkMxMC41NjI3IDEwLjI1MjMgMTAuNTk5NiAxMC4zMDc1IDEwLjY0NjEgMTAuMzU0TDEyLjIxMjEgMTEuOTE5TDExLjM1NzEgMTIuNjVMOS44NTcwNSAxMS4xNUM5Ljc2MzE3IDExLjA1NjEgOS42MzU4MyAxMS4wMDM0IDkuNTAzMDUgMTEuMDAzNEM5LjM3MDI4IDExLjAwMzQgOS4yNDI5NCAxMS4wNTYxIDkuMTQ5MDUgMTEuMTVDOS4wNTUxNiAxMS4yNDM5IDkuMDAyNDIgMTEuMzcxMiA5LjAwMjQyIDExLjUwNEM5LjAwMjQyIDExLjYzNjggOS4wNTUxNiAxMS43NjQxIDkuMTQ5MDUgMTEuODU4TDEwLjU5NDEgMTMuM0wxMC40NTYxIDEzLjQxOEMxMC4yMDg3IDEzLjYzMDIgOS45MTI5MyAxMy43NzgyIDkuNTk0ODYgMTMuODQ5MkM5LjI3Njc5IDEzLjkyMDIgOC45NDYxNSAxMy45MTE5IDguNjMyMDUgMTMuODI1QzguNTk0OTIgMTMuMzU3MiA4LjM5MjkyIDEyLjkxNzggOC4wNjIwNSAxMi41ODVMNC40NzcwNSA5LjAwMDAyQzQuMjkxMzYgOC44MTQyNiA0LjA3MDkgOC42NjY5IDMuODI4MjYgOC41NjYzNUMzLjU4NTYzIDguNDY1NzkgMy4zMjU1NiA4LjQxNDAxIDMuMDYyOTEgOC40MTM5N0MyLjgwMDI1IDguNDEzOTIgMi41NDAxNyA4LjQ2NTYxIDIuMjk3NDkgOC41NjYwOEMyLjA1NDgyIDguNjY2NTQgMS44MzQzMSA4LjgxMzgzIDEuNjQ4NTUgOC45OTk1MkMxLjQ2MjggOS4xODUyMSAxLjMxNTQ0IDkuNDA1NjYgMS4yMTQ4OCA5LjY0ODNDMS4xMTQzMyA5Ljg5MDk0IDEuMDYyNTUgMTAuMTUxIDEuMDYyNSAxMC40MTM3QzEuMDYyNDEgMTAuOTQ0MSAxLjI3MzA0IDExLjQ1MjkgMS42NDgwNSAxMS44MjhMNS4yMzQwNSAxNS40MTRDNS41NjQxMSAxNS43NDMxIDUuOTk4NzQgMTUuOTQ2NiA2LjQ2Mjg2IDE1Ljk4OTNDNi45MjY5OSAxNi4wMzIgNy4zOTE0NiAxNS45MTEzIDcuNzc2MDUgMTUuNjQ4QzguMjE2MzkgMTUuODEyMiA4LjY4MjEyIDE1Ljg5NzggOS4xNTIwNSAxNS45MDFDMTAuMTA5MiAxNS45MDM3IDExLjAzNTIgMTUuNTYxIDExLjc2MDEgMTQuOTM2TDE0Ljg0MDEgMTIuMzA2QzE1LjE4NjYgMTIuMDI3OSAxNS40Njk0IDExLjY3ODYgMTUuNjY5NiAxMS4yODE5QzE1Ljg2OTcgMTAuODg1MSAxNS45ODI0IDEwLjQ1IDE2LjAwMDEgMTAuMDA2VjEuMDAwMDJaIiBmaWxsPSIjODg1QTVBIi8+PHBhdGggZD0iTTIgN1YySDVDNS4yNjUyMiAyIDUuNTE5NTcgMS44OTQ2NCA1LjcwNzExIDEuNzA3MTFDNS44OTQ2NCAxLjUxOTU3IDYgMS4yNjUyMiA2IDFDNiAwLjczNDc4NCA1Ljg5NDY0IDAuNDgwNDMgNS43MDcxMSAwLjI5Mjg5M0M1LjUxOTU3IDAuMTA1MzU3IDUuMjY1MjIgMCA1IDBMMSAwQzAuNzM0Nzg0IDAgMC40ODA0MyAwLjEwNTM1NyAwLjI5Mjg5MyAwLjI5Mjg5M0MwLjEwNTM1NyAwLjQ4MDQzIDAgMC43MzQ3ODQgMCAxTDAgN0MwIDcuMjY1MjIgMC4xMDUzNTcgNy41MTk1NyAwLjI5Mjg5MyA3LjcwNzExQzAuNDgwNDMgNy44OTQ2NCAwLjczNDc4NCA4IDEgOEMxLjI2NTIyIDggMS41MTk1NyA3Ljg5NDY0IDEuNzA3MTEgNy43MDcxMUMxLjg5NDY0IDcuNTE5NTcgMiA3LjI2NTIyIDIgN1oiIGZpbGw9IiM4ODVBNUEiLz48L3N2Zz4='); + --icon-UseScience: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTggMTMuMDAwNEM4IDEyLjIwNDggNy42ODM5MyAxMS40NDE3IDcuMTIxMzIgMTAuODc5MUM2LjU1ODcxIDEwLjMxNjUgNS43OTU2NSAxMC4wMDA0IDUgMTAuMDAwNEM0LjY1Mzk1IDEwLjAwMzUgNC4zMTExMSAxMC4wNjcxIDMuOTg3IDEwLjE4ODRDMy41ODAxNyA5LjgxMzA5IDMuMjg1NTYgOS4zMzIxNyAzLjEzNTk4IDguNzk5MjZDMi45ODY0IDguMjY2MzQgMi45ODc3NCA3LjcwMjM2IDMuMTM5ODQgNy4xNzAxNkMzLjI5MTk0IDYuNjM3OTYgMy41ODg4NCA2LjE1ODQ1IDMuOTk3NDMgNS43ODUwNkM0LjQwNjAzIDUuNDExNjcgNC45MTAyOCA1LjE1OTA3IDUuNDU0IDUuMDU1NDFMNi42NTQgNy4xMjk0MUM2LjcyMDMgNy4yNDQyNSA2LjgyOTUxIDcuMzI4MDQgNi45NTc2IDcuMzYyMzZDNy4wODU2OSA3LjM5NjY4IDcuMjIyMTYgNy4zNzg3MSA3LjMzNyA3LjMxMjQxTDkuMDcxIDYuMzEyNDFDOS4xODU4MyA2LjI0NjEgOS4yNjk2MyA2LjEzNjg5IDkuMzAzOTUgNi4wMDg4MUM5LjMzODI3IDUuODgwNzIgOS4zMjAzIDUuNzQ0MjUgOS4yNTQgNS42Mjk0MUw2LjI1NCAwLjQyOTQwOEM2LjIyMDgzIDAuMzcyMzQ4IDYuMTc2NyAwLjMyMjQxOCA2LjEyNDE0IDAuMjgyNDk4QzYuMDcxNTkgMC4yNDI1NzggNi4wMTE2NSAwLjIxMzQ1OSA1Ljk0Nzc4IDAuMTk2ODE4QzUuODgzOTEgMC4xODAxNzggNS44MTczOSAwLjE3NjM0NiA1Ljc1MjAzIDAuMTg1NTQzQzUuNjg2NjggMC4xOTQ3NDEgNS42MjM3OSAwLjIxNjc4NiA1LjU2NyAwLjI1MDQwOEwzLjgzMyAxLjI1MDQxQzMuNzE4MzMgMS4zMTY4OCAzLjYzNDc1IDEuNDI2MTYgMy42MDA2MiAxLjU1NDI0QzMuNTY2NDkgMS42ODIzMSAzLjU4NDYxIDEuODE4NjkgMy42NTEgMS45MzM0MUw0LjQyOCAzLjI3ODQxQzMuNjIzNDkgMy41NDEzIDIuODk5MzYgNC4wMDUwOSAyLjMyNDEgNC42MjU5MUMxLjc0ODgzIDUuMjQ2NzMgMS4zNDE0NyA2LjAwNDA0IDEuMTQwNTMgNi44MjYyMUMwLjkzOTU5MyA3LjY0ODM4IDAuOTUxNzMgOC41MDgyMiAxLjE3NTc5IDkuMzI0MzlDMS4zOTk4NiAxMC4xNDA2IDEuODI4NDQgMTAuODg2MSAyLjQyMSAxMS40OTA0QzIuMTQ4MSAxMS45NDcgMi4wMDI3MiAxMi40Njg1IDIgMTMuMDAwNFYxNi4wMDA0SDE0VjE0LjAwMDRIOFYxMy4wMDA0WiIgZmlsbD0iIzIzMTk0MiIvPjxwYXRoIGQ9Ik04LjgzMDA1IDExLjkxMTVMMTMuMjg3MSA5LjMzODQ3TDEyLjI4NzEgNy42MDU0N0w3LjgzMTA1IDEwLjE3ODVDOC4zMDYxMiAxMC42NjE3IDguNjQ5OTggMTEuMjU4MiA4LjgzMDA1IDExLjkxMTVaIiBmaWxsPSIjMjMxOTQyIi8+PC9zdmc+'); } diff --git a/static/ui-icons/use-cases/UseChart.svg b/static/ui-icons/use-cases/UseChart.svg new file mode 100644 index 00000000..5f2e72fd --- /dev/null +++ b/static/ui-icons/use-cases/UseChart.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/static/ui-icons/use-cases/UseEducate.svg b/static/ui-icons/use-cases/UseEducate.svg new file mode 100644 index 00000000..5cba5b2a --- /dev/null +++ b/static/ui-icons/use-cases/UseEducate.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/static/ui-icons/use-cases/UseFinance.svg b/static/ui-icons/use-cases/UseFinance.svg new file mode 100644 index 00000000..0cf32784 --- /dev/null +++ b/static/ui-icons/use-cases/UseFinance.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/static/ui-icons/use-cases/UseHr.svg b/static/ui-icons/use-cases/UseHr.svg new file mode 100644 index 00000000..98939f9d --- /dev/null +++ b/static/ui-icons/use-cases/UseHr.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/ui-icons/use-cases/UseMedia.svg b/static/ui-icons/use-cases/UseMedia.svg new file mode 100644 index 00000000..6bfff615 --- /dev/null +++ b/static/ui-icons/use-cases/UseMedia.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/ui-icons/use-cases/UseMonitor.svg b/static/ui-icons/use-cases/UseMonitor.svg new file mode 100644 index 00000000..b99fa174 --- /dev/null +++ b/static/ui-icons/use-cases/UseMonitor.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/ui-icons/use-cases/UseOther.svg b/static/ui-icons/use-cases/UseOther.svg new file mode 100644 index 00000000..ed26d998 --- /dev/null +++ b/static/ui-icons/use-cases/UseOther.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/ui-icons/use-cases/UseProduct.svg b/static/ui-icons/use-cases/UseProduct.svg new file mode 100644 index 00000000..c8f00660 --- /dev/null +++ b/static/ui-icons/use-cases/UseProduct.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/ui-icons/use-cases/UseSales.svg b/static/ui-icons/use-cases/UseSales.svg new file mode 100644 index 00000000..a34397de --- /dev/null +++ b/static/ui-icons/use-cases/UseSales.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/ui-icons/use-cases/UseScience.svg b/static/ui-icons/use-cases/UseScience.svg new file mode 100644 index 00000000..a32f1643 --- /dev/null +++ b/static/ui-icons/use-cases/UseScience.svg @@ -0,0 +1,4 @@ + + + +