diff --git a/app/client/package.json b/app/client/package.json index cd4705a6ad..f65a0cc762 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -13,6 +13,7 @@ "@blueprintjs/table": "^3.4.0", "@sentry/browser": "^5.6.3", "@types/axios": "^0.14.0", + "@types/fontfaceobserver": "^0.0.6", "@types/jest": "^24.0.18", "@types/lodash": "^4.14.120", "@types/moment-timezone": "^0.5.10", @@ -26,6 +27,7 @@ "@types/styled-components": "^4.1.8", "axios": "^0.18.0", "flow-bin": "^0.91.0", + "fontfaceobserver": "^2.1.0", "husky": "^1.3.1", "lint-staged": "^8.1.0", "lodash": "^4.17.11", diff --git a/app/client/public/appsmith-widget-font/fonts/appsmith-widget-font.eot b/app/client/public/appsmith-widget-font/fonts/appsmith-widget-font.eot new file mode 100644 index 0000000000..88ed660d1e Binary files /dev/null and b/app/client/public/appsmith-widget-font/fonts/appsmith-widget-font.eot differ diff --git a/app/client/public/appsmith-widget-font/fonts/appsmith-widget-font.svg b/app/client/public/appsmith-widget-font/fonts/appsmith-widget-font.svg new file mode 100644 index 0000000000..c946036eff --- /dev/null +++ b/app/client/public/appsmith-widget-font/fonts/appsmith-widget-font.svg @@ -0,0 +1,27 @@ + + + +Generated by Fontastic.me + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/client/public/appsmith-widget-font/fonts/appsmith-widget-font.ttf b/app/client/public/appsmith-widget-font/fonts/appsmith-widget-font.ttf new file mode 100644 index 0000000000..14f9ce9efb Binary files /dev/null and b/app/client/public/appsmith-widget-font/fonts/appsmith-widget-font.ttf differ diff --git a/app/client/public/appsmith-widget-font/fonts/appsmith-widget-font.woff b/app/client/public/appsmith-widget-font/fonts/appsmith-widget-font.woff new file mode 100644 index 0000000000..96865fd148 Binary files /dev/null and b/app/client/public/appsmith-widget-font/fonts/appsmith-widget-font.woff differ diff --git a/app/client/public/appsmith-widget-font/icons-reference.html b/app/client/public/appsmith-widget-font/icons-reference.html new file mode 100644 index 0000000000..e7c6122796 --- /dev/null +++ b/app/client/public/appsmith-widget-font/icons-reference.html @@ -0,0 +1,176 @@ + + + + + + + Font Reference - appsmith-widget-font + + + + + +
+

appsmith-widget-font

+

This font was created withFontastic

+

CSS mapping

+ +

Character mapping

+ +
+ + + \ No newline at end of file diff --git a/app/client/public/appsmith-widget-font/styles.css b/app/client/public/appsmith-widget-font/styles.css new file mode 100644 index 0000000000..0808537b3b --- /dev/null +++ b/app/client/public/appsmith-widget-font/styles.css @@ -0,0 +1,91 @@ +@charset "UTF-8"; + +@font-face { + font-family: "appsmith-widget-font"; + src:url("fonts/appsmith-widget-font.eot"); + src:url("fonts/appsmith-widget-font.eot?#iefix") format("embedded-opentype"), + url("fonts/appsmith-widget-font.woff") format("woff"), + url("fonts/appsmith-widget-font.ttf") format("truetype"), + url("fonts/appsmith-widget-font.svg#appsmith-widget-font") format("svg"); + font-weight: normal; + font-style: normal; + +} + +[data-icon]:before { + font-family: "appsmith-widget-font" !important; + content: attr(data-icon); + font-style: normal !important; + font-weight: normal !important; + font-variant: normal !important; + text-transform: none !important; + speak: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +[class^="appsmith-widget-"]:before, +[class*=" appsmith-widget-"]:before { + font-family: "appsmith-widget-font" !important; + font-style: normal !important; + font-weight: normal !important; + font-variant: normal !important; + text-transform: none !important; + speak: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.appsmith-widget-alert:before { + content: "\61"; +} +.appsmith-widget-button:before { + content: "\62"; +} +.appsmith-widget-checkbox:before { + content: "\63"; +} +.appsmith-widget-collapse:before { + content: "\64"; +} +.appsmith-widget-datepicker:before { + content: "\65"; +} +.appsmith-widget-dropdown:before { + content: "\66"; +} +.appsmith-widget-file-upload:before { + content: "\67"; +} +.appsmith-widget-image:before { + content: "\68"; +} +.appsmith-widget-input:before { + content: "\69"; +} +.appsmith-widget-location-picker:before { + content: "\6a"; +} +.appsmith-widget-modal:before { + content: "\6b"; +} +.appsmith-widget-radio:before { + content: "\6c"; +} +.appsmith-widget-rich-text:before { + content: "\6d"; +} +.appsmith-widget-switch:before { + content: "\6e"; +} +.appsmith-widget-table:before { + content: "\6f"; +} +.appsmith-widget-tabs:before { + content: "\70"; +} +.appsmith-widget-text:before { + content: "\71"; +} diff --git a/app/client/public/index.html b/app/client/public/index.html index e9d789c8ce..51264d4795 100755 --- a/app/client/public/index.html +++ b/app/client/public/index.html @@ -15,6 +15,9 @@ rel="stylesheet" /> + + + { return { @@ -16,7 +16,7 @@ export const errorFetchingWidgetCards = (error: any) => { } } -export const successFetchingWidgetCards = (cards: { [id: string]: IWidgetCardProps[] }) => { +export const successFetchingWidgetCards = (cards: { [id: string]: WidgetCardProps[] }) => { return { type: ActionTypes.SUCCESS_FETCHING_WIDGET_CARDS, cards diff --git a/app/client/src/api/WidgetCardsPaneApi.tsx b/app/client/src/api/WidgetCardsPaneApi.tsx index 45e7b56be5..75a1c17b7b 100644 --- a/app/client/src/api/WidgetCardsPaneApi.tsx +++ b/app/client/src/api/WidgetCardsPaneApi.tsx @@ -1,13 +1,13 @@ import Api from "./Api" -import { IWidgetCardProps } from "../widgets/BaseWidget" +import { WidgetCardProps } from "../widgets/BaseWidget" export interface WidgetCardsPaneResponse { - cards : { [id: string]: IWidgetCardProps[]} + cards: { [id: string]: WidgetCardProps[]} } export interface WidgetCardsPaneRequest {} class WidgetCardsPaneApi extends Api { - static url: string = "/widgetCards" + static url = "/widgetCards" static fetchWidgetCards(): Promise { return Api.get(WidgetCardsPaneApi.url, {}) } diff --git a/app/client/src/constants/ActionConstants.tsx b/app/client/src/constants/ActionConstants.tsx index 8d8f43caeb..b2ed304c9c 100644 --- a/app/client/src/constants/ActionConstants.tsx +++ b/app/client/src/constants/ActionConstants.tsx @@ -1,5 +1,5 @@ // import ContainerWidget from "../widgets/ContainerWidget" -import { IWidgetProps, IWidgetCardProps } from "../widgets/BaseWidget" +import { IWidgetProps, WidgetCardProps } from "../widgets/BaseWidget" export type ActionType = | "UPDATE_CANVAS" @@ -41,19 +41,19 @@ export const ActionTypes: { [id: string]: ActionType } = { } export interface ReduxAction { - type: ActionType - payload: T + type: ActionType; + payload: T; } export interface LoadCanvasPayload { - pageWidgetId: string - widgets: { [widgetId: string]: IWidgetProps } + pageWidgetId: string; + widgets: { [widgetId: string]: IWidgetProps }; } export interface LoadWidgetPanePayload { - widgets: IWidgetProps[] + widgets: IWidgetProps[]; } export interface LoadWidgetCardsPanePayload { - cards: { [id: string] : IWidgetCardProps[] } + cards: { [id: string]: WidgetCardProps[] } } diff --git a/app/client/src/constants/Colors.tsx b/app/client/src/constants/Colors.tsx index 3be2cc3cf4..b5fe36a9d6 100644 --- a/app/client/src/constants/Colors.tsx +++ b/app/client/src/constants/Colors.tsx @@ -1,10 +1,14 @@ export const WHITE = "#FFFFFF"; export const WHITE_1 = "#E9FAF3"; export const WHITE_2 = "#D0D7DD"; + export const BLACK = "#000000"; export const BLACK_1 = "#040627"; +export const BLACK_2 = "#21282C"; +export const BLACK_3 = "#272E32"; +export const BLACK_4 = "#363E44"; + export const GREEN = "#29CCA3"; export const RED = "#CE4257"; export const PURPLE = "#6871EF"; -export const BLACK_3 = "#363E44"; -export const BLACK_2 = "#272E32"; + diff --git a/app/client/src/constants/DefaultTheme.tsx b/app/client/src/constants/DefaultTheme.tsx index 6ced70d0dd..d41031a9a8 100644 --- a/app/client/src/constants/DefaultTheme.tsx +++ b/app/client/src/constants/DefaultTheme.tsx @@ -13,7 +13,6 @@ const { ThemeProvider, } = styledComponents as styledComponents.ThemedStyledComponentsModule; - export type Theme = { radii: Array; fontSizes: Array; @@ -25,8 +24,8 @@ export type Theme = { }; export const theme: Theme = { - radii: [], - fontSizes: [0, 10, 12, 14, 16, 18, 24, 32, 48, 64], + radii: [0, 4, 8, 10, 20], + fontSizes: [0, 10, 12, 14, 16, 18, 24, 28, 32, 48, 64], spaces: [0, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24], fontWeights: [0, 400, 500, 700], colors: { @@ -34,13 +33,14 @@ export const theme: Theme = { error: Colors.RED, hover: Colors.WHITE_1, textDefault: Colors.BLACK_1, + textOnDarkBG: Colors.WHITE, textAnchor: Colors.PURPLE , border: Colors.WHITE_2 , - paneCard: Colors.BLACK_3, - paneBG: Colors.BLACK_2, + paneCard: Colors.BLACK_2, + paneBG: Colors.BLACK_4, }, lineHeights: [0, 14, 18, 22, 24, 28, 36, 48, 64, 80], - fonts: [FontFamilies.DMSans as FontFamily], + fonts: [FontFamilies.DMSans, FontFamilies.AppsmithWidget], }; export { css, createGlobalStyle, keyframes, ThemeProvider }; diff --git a/app/client/src/constants/Fonts.tsx b/app/client/src/constants/Fonts.tsx index 551db8d79e..4671d73bc0 100644 --- a/app/client/src/constants/Fonts.tsx +++ b/app/client/src/constants/Fonts.tsx @@ -1,2 +1,3 @@ export const DMSans = "DM Sans"; +export const AppsmithWidget = "appsmith-widget-font"; export const OpenSans = "Open Sans"; \ No newline at end of file diff --git a/app/client/src/index.css b/app/client/src/index.css index 0773dc6c88..997add21cd 100755 --- a/app/client/src/index.css +++ b/app/client/src/index.css @@ -9,6 +9,10 @@ body { background: #efefef; } +body.fontLoaded { + font-family: "DM Sans, sans-serif"; +} + code { font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace; diff --git a/app/client/src/index.tsx b/app/client/src/index.tsx index 1547cfe697..eef0767308 100755 --- a/app/client/src/index.tsx +++ b/app/client/src/index.tsx @@ -14,11 +14,21 @@ import WidgetBuilderRegistry from "./utils/WidgetRegistry"; import { ThemeProvider, theme } from "./constants/DefaultTheme"; import createSagaMiddleware from 'redux-saga' import { rootSaga } from "./sagas" - +import FontFaceObserver from "fontfaceobserver"; import { DndProvider } from "react-dnd" import HTML5Backend from "react-dnd-html5-backend" import { appInitializer } from "./utils/AppsmithUtils"; +// font face observer +const textFont = new FontFaceObserver("DM Sans"); +const widgetIconFont = new FontFaceObserver("appmith-widget-font"); +Promise.all([textFont.load(), widgetIconFont.load()]).then(()=>{ + document.body.className += "fontLoaded"; +}).catch(err => { + console.log(err); +}); + + appInitializer(); WidgetBuilderRegistry.registerWidgetBuilders(); const sagaMiddleware = createSagaMiddleware() diff --git a/app/client/src/mockResponses/WidgetCardsPaneResponse.tsx b/app/client/src/mockResponses/WidgetCardsPaneResponse.tsx index 93bea8c9fc..6ff551266f 100644 --- a/app/client/src/mockResponses/WidgetCardsPaneResponse.tsx +++ b/app/client/src/mockResponses/WidgetCardsPaneResponse.tsx @@ -5,74 +5,31 @@ const WidgetCardsPaneResponse: WidgetCardsPaneReduxState = { common: [ { widgetType: "BUTTON_WIDGET", - icon: "\f243", + icon: "appsmith-widget-button", label: "Button", - groups: ["common", "form"] }, - { - widgetType: "INPUT_WIDGET", - icon: "\f243", - label: "Input", - groups: ["common", "form"] - }, - { - widgetType: "TOGGLE_WIDGET", - icon: "\f205", - label: "Toggle", - groups: ["common", "view"] - } ], form: [ { widgetType: "BUTTON_WIDGET", - icon: "\f243", + icon: "appsmith-widget-button", label: "Button", - groups: ["common", "form"] }, { - widgetType: "INPUT_WIDGET", - icon: "\f243", - label: "Input", - groups: ["common", "form"] + widgetType: "CALLOUT_WIDGET", + icon: "appsmith-widget-alert", + label: "Callout", } ], view: [ { - widgetType: "TOGGLE_WIDGET", - icon: "\f205", - label: "Toggle", - groups: ["common", "view"] + widgetType: "BUTTON_WIDGET", + icon: "appsmith-widget-button", + label: "Button", } ] } }; -// const WidgetPaneResponse: WidgetPaneReduxState = { -// widgets: [ -// { -// widgetType: "BUTTON_WIDGET", -// text: "Lorem Ipsum", -// renderMode: RenderModes.COMPONENT_PANE, -// bottomRow: 50, -// widgetId: "wp1", -// rightColumn: 200 -// }, -// { -// widgetType: "TEXT_WIDGET", -// text: "Lorem Ipsum", -// renderMode: RenderModes.COMPONENT_PANE, -// bottomRow: 50, -// widgetId: "wp2", -// rightColumn: 200 -// }, -// { -// widgetType: "SPINNER_WIDGET", -// renderMode: RenderModes.COMPONENT_PANE, -// backgroundColor: "#434343", -// bottomRow: 50, -// widgetId: "wp3", -// rightColumn: 200 -// } -// ] -// } + export default WidgetCardsPaneResponse; diff --git a/app/client/src/pages/Editor/WidgetCard.tsx b/app/client/src/pages/Editor/WidgetCard.tsx index b2f42095d8..63a8d12c4f 100644 --- a/app/client/src/pages/Editor/WidgetCard.tsx +++ b/app/client/src/pages/Editor/WidgetCard.tsx @@ -1,15 +1,13 @@ import React, { useState, useLayoutEffect, MutableRefObject } from 'react'; import { useDrag, DragSourceMonitor, DragPreviewImage } from 'react-dnd' import blankImage from "../../assets/images/blank.png" -import { IWidgetCardProps } from '../../widgets/BaseWidget' +import { WidgetCardProps } from '../../widgets/BaseWidget' import styled from 'styled-components'; -import { Icon } from '@blueprintjs/core' -import { IconNames } from '@blueprintjs/icons' import { generateReactKey } from "../../utils/generators" -type WidgetCardProps = { - details: IWidgetCardProps; +type CardProps = { + details: WidgetCardProps; } export const Wrapper = styled.div` @@ -19,27 +17,38 @@ export const Wrapper = styled.div` align-items: center; flex: 1; padding: 10px 5px 10px 5px; - margin: 0px 10px 0 0; - border-radius: 5px; + border-radius: ${props => props.theme.radii[1]}px; background: ${props => props.theme.colors.paneCard}; border: 1px solid ${props=> props.theme.colors.paneCard}; + color: ${props => props.theme.colors.textOnDarkBG}; + & > div { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } &:hover{ background: #fff; cursor: grab; + color: ${props => props.theme.colors.textDefault} + } + & i { + font-family: ${props => props.theme.fonts[2]}; + font-size: ${props => props.theme.fontSizes[7]}px; } `; + export const IconLabel = styled.h5` text-align: center; - padding: 10px 0; margin: 0; text-transform: uppercase; - font-weight: normal; + font-weight: ${props => props.theme.fontWeights[1]}; flex-shrink: 1; - font-size: 0.5rem; + font-size: ${props => props.theme.fontSizes[1]}px; `; /* eslint-disable @typescript-eslint/no-unused-vars */ -const WidgetCard = (props: WidgetCardProps) => { +const WidgetCard = (props: CardProps) => { const [initialOffset, setInitialOffset] = useState({ x: 0, y: 0}) const [{ isDragging }, drag, preview] = useDrag({ @@ -58,16 +67,16 @@ const WidgetCard = (props: WidgetCardProps) => { y: Math.ceil(rect.top) }) } - }, [setInitialOffset]) + }, [setInitialOffset]); return ( - -
- - {props.details.label} -
-
+ +
+ + {props.details.label} +
+
) } diff --git a/app/client/src/pages/Editor/WidgetCardsPane.tsx b/app/client/src/pages/Editor/WidgetCardsPane.tsx index b62f580eae..7672bbf07f 100644 --- a/app/client/src/pages/Editor/WidgetCardsPane.tsx +++ b/app/client/src/pages/Editor/WidgetCardsPane.tsx @@ -1,24 +1,26 @@ import React from "react" import WidgetCard from "./WidgetCard" import styled from "styled-components" -import { IWidgetCardProps } from "../../widgets/BaseWidget" +import { WidgetCardProps } from "../../widgets/BaseWidget" type WidgetCardPaneProps = { - cards: { [id: string]: IWidgetCardProps[]}; + cards: { [id: string]: WidgetCardProps[]}; } const CardsPaneWrapper = styled.div` - width: 300px; + width: 256px; background-color: ${props => props.theme.colors.paneBG}; - border-radius: 5px; + border-radius: ${props => props.theme.radii[2]}px; box-shadow: 0px 0px 3px ${props => props.theme.colors.paneBG}; padding: 5px 10px; + color: ${props => props.theme.colors.textOnDarkBG}; + text-transform: capitalize; `; const CardsWrapper = styled.div` - display: flex; - flex-flow: row wrap; - justify-content: flex-start; + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-gap: ${props => props.theme.spaces[2]}px; `; const WidgetCardsPane: React.SFC = (props: WidgetCardPaneProps) => { @@ -30,7 +32,7 @@ const WidgetCardsPane: React.SFC = (props: WidgetCardPanePr
{group}
- { props.cards[group].map((card: IWidgetCardProps) => ) } + { props.cards[group].map((card: WidgetCardProps) => ) }
) diff --git a/app/client/src/pages/Editor/index.tsx b/app/client/src/pages/Editor/index.tsx index 4a57fe8573..8a44f88789 100644 --- a/app/client/src/pages/Editor/index.tsx +++ b/app/client/src/pages/Editor/index.tsx @@ -2,7 +2,7 @@ import React, { Component } from "react" import { connect } from "react-redux" import styled from "styled-components" import Canvas from "./Canvas" -import { IWidgetCardProps, IWidgetProps } from '../../widgets/BaseWidget' +import { WidgetCardProps, IWidgetProps } from '../../widgets/BaseWidget' import { AppState } from "../../reducers" import { EditorReduxState } from "../../reducers/uiReducers/editorReducer" import WidgetCardsPane from "./WidgetCardsPane" @@ -43,7 +43,7 @@ const EditorWrapper = styled.div` type EditorProps = { pageWidget: ContainerWidgetProps | any; fetchCanvasWidgets: Function; - cards: { [id: string]: IWidgetCardProps[] } | any; + cards: { [id: string]: WidgetCardProps[] } | any; addPageWidget: Function; page: string; } diff --git a/app/client/src/reducers/uiReducers/editorReducer.tsx b/app/client/src/reducers/uiReducers/editorReducer.tsx index 366b2a9972..7ab9805a6c 100644 --- a/app/client/src/reducers/uiReducers/editorReducer.tsx +++ b/app/client/src/reducers/uiReducers/editorReducer.tsx @@ -5,7 +5,7 @@ import { LoadCanvasPayload, LoadWidgetCardsPanePayload } from "../../constants/ActionConstants" -import { IWidgetCardProps, IWidgetProps } from "../../widgets/BaseWidget" +import { WidgetCardProps, IWidgetProps } from "../../widgets/BaseWidget" import { ContainerWidgetProps } from "../../widgets/ContainerWidget" const initialState: EditorReduxState = {} @@ -34,7 +34,7 @@ const editorReducer = createReducer(initialState, { export interface EditorReduxState { pageWidget?: ContainerWidgetProps; cards?: { - [id: string]: IWidgetCardProps[]; + [id: string]: WidgetCardProps[]; }; } diff --git a/app/client/src/reducers/uiReducers/widgetCardsPaneReducer.tsx b/app/client/src/reducers/uiReducers/widgetCardsPaneReducer.tsx index 5ada95d5cb..f41b65c3ef 100644 --- a/app/client/src/reducers/uiReducers/widgetCardsPaneReducer.tsx +++ b/app/client/src/reducers/uiReducers/widgetCardsPaneReducer.tsx @@ -4,7 +4,7 @@ import { ReduxAction, LoadWidgetCardsPanePayload } from "../../constants/ActionConstants" -import { IWidgetCardProps } from "../../widgets/BaseWidget"; +import { WidgetCardProps } from "../../widgets/BaseWidget"; import WidgetCardsPaneResponse from "../../mockResponses/WidgetCardsPaneResponse" const initialState: WidgetCardsPaneReduxState = WidgetCardsPaneResponse @@ -20,8 +20,8 @@ const widgetCardsPaneReducer = createReducer(initialState, { export interface WidgetCardsPaneReduxState { cards: { - [id: string]: IWidgetCardProps[] - } + [id: string]: WidgetCardProps[]; + }; } export default widgetCardsPaneReducer diff --git a/app/client/src/widgets/BaseWidget.tsx b/app/client/src/widgets/BaseWidget.tsx index 9c8b3efe8b..4ad822b9c8 100644 --- a/app/client/src/widgets/BaseWidget.tsx +++ b/app/client/src/widgets/BaseWidget.tsx @@ -163,12 +163,11 @@ export interface IWidgetProps { renderMode: RenderMode; } -export interface IWidgetCardProps { +export interface WidgetCardProps { widgetType: WidgetType; key?: string; label: string; icon: string; - groups: string[]; } export default BaseWidget diff --git a/app/client/yarn.lock b/app/client/yarn.lock index e65a55412b..0eace71721 100644 --- a/app/client/yarn.lock +++ b/app/client/yarn.lock @@ -1342,6 +1342,11 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== +"@types/fontfaceobserver@^0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@types/fontfaceobserver/-/fontfaceobserver-0.0.6.tgz#14a4a02b77e66e6a1070622981d431c885a174ed" + integrity sha512-QJ1znjr9CDax2L17rgBnDOfNHsC1XtVAMswu+lRWvWb+kANhHA0slUNSSBsG8FVNvM4I4yXlN9doJRot3A2hkQ== + "@types/history@*": version "4.7.3" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.3.tgz#856c99cdc1551d22c22b18b5402719affec9839a" @@ -4720,6 +4725,11 @@ follow-redirects@^1.0.0: dependencies: debug "^3.0.0" +fontfaceobserver@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fontfaceobserver/-/fontfaceobserver-2.1.0.tgz#e2705d293e2c585a6531c2a722905657317a2991" + integrity sha512-ReOsO2F66jUa0jmv2nlM/s1MiutJx/srhAe2+TE8dJCMi02ZZOcCTxTCQFr3Yet+uODUtnr4Mewg+tNQ+4V1Ng== + for-in@^0.1.3: version "0.1.8" resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"