brainly-style-guide
Advanced tools
Comparing version 182.1.0 to 182.2.0
@@ -38,8 +38,4 @@ "use strict"; | ||
var AccordionContext = /*#__PURE__*/(0, _react.createContext)({ | ||
opened: {}, | ||
onChange: function onChange() { | ||
return undefined; | ||
} | ||
}); | ||
// $FlowFixMe context doesn't need to be defined here | ||
var AccordionContext = /*#__PURE__*/(0, _react.createContext)(); | ||
exports.AccordionContext = AccordionContext; | ||
@@ -68,28 +64,37 @@ var spaceClasses = { | ||
var _useState = (0, _react.useState)({}), | ||
_useState2 = _slicedToArray(_useState, 2), | ||
opened = _useState2[0], | ||
setOpened = _useState2[1]; | ||
var _useReducer = (0, _react.useReducer)(reducer, { | ||
opened: {} | ||
}), | ||
_useReducer2 = _slicedToArray(_useReducer, 2), | ||
state = _useReducer2[0], | ||
dispatch = _useReducer2[1]; | ||
var handleChange = (0, _react.useCallback)(function (item, value) { | ||
if (allowMultiple) { | ||
setOpened(_objectSpread(_objectSpread({}, opened), {}, _defineProperty({}, item, value))); | ||
} else { | ||
var newOpened = _objectSpread({}, opened); | ||
function reducer(state, action) { | ||
switch (action.type) { | ||
case 'accordion/SET_OPENED': | ||
{ | ||
var opened = state.opened; | ||
var _action$payload = action.payload, | ||
id = _action$payload.id, | ||
value = _action$payload.value; | ||
return _objectSpread(_objectSpread({}, state), {}, { | ||
opened: allowMultiple ? _objectSpread(_objectSpread({}, opened), {}, _defineProperty({}, id, value)) : _defineProperty({}, id, value) | ||
}); | ||
} | ||
Object.keys(newOpened).forEach(function (i) { | ||
return newOpened[i] = false; | ||
}); | ||
setOpened(_objectSpread(_objectSpread({}, newOpened), {}, _defineProperty({}, item, value))); | ||
default: | ||
return state; | ||
} | ||
}, [opened, allowMultiple]); | ||
var context = { | ||
onChange: handleChange, | ||
opened: opened | ||
}; | ||
var classes = (0, _classnames.default)(_defineProperty({}, "".concat(spaceClasses[spacing]), spaceClasses[spacing]), className); | ||
} | ||
var noGapBetweenElements = spacing === 'none'; | ||
var spaceClass = spacing === 'none' ? undefined : spaceClasses[spacing]; | ||
return /*#__PURE__*/_react.default.createElement(AccordionContext.Provider, { | ||
value: context | ||
value: { | ||
noGapBetweenElements: noGapBetweenElements, | ||
opened: state.opened, | ||
dispatch: dispatch | ||
} | ||
}, /*#__PURE__*/_react.default.createElement("div", { | ||
className: classes | ||
className: (0, _classnames.default)(spaceClass, className) | ||
}, children)); | ||
@@ -96,0 +101,0 @@ }; |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.Default = exports.default = void 0; | ||
exports.NoGaps = exports.Default = exports.default = void 0; | ||
@@ -75,2 +75,33 @@ var _react = _interopRequireDefault(require("react")); | ||
exports.Default = Default; | ||
exports.Default = Default; | ||
var NoGaps = function NoGaps() { | ||
return /*#__PURE__*/_react.default.createElement(_Accordion.default, { | ||
spacing: "none", | ||
allowMultiple: true | ||
}, /*#__PURE__*/_react.default.createElement(_AccordionItem.default, { | ||
title: copy.title, | ||
defaultOpened: true | ||
}, copy.description, " ", /*#__PURE__*/_react.default.createElement(CallToAction, { | ||
url: copy.url, | ||
cta: copy.cta | ||
})), /*#__PURE__*/_react.default.createElement(_AccordionItem.default, { | ||
title: copy.title, | ||
defaultOpened: true | ||
}, copy.description, " ", /*#__PURE__*/_react.default.createElement(CallToAction, { | ||
url: copy.url, | ||
cta: copy.cta | ||
})), /*#__PURE__*/_react.default.createElement(_AccordionItem.default, { | ||
title: copy.title | ||
}, copy.description, " ", /*#__PURE__*/_react.default.createElement(CallToAction, { | ||
url: copy.url, | ||
cta: copy.cta | ||
})), /*#__PURE__*/_react.default.createElement(_AccordionItem.default, { | ||
title: copy.title | ||
}, copy.description, " ", /*#__PURE__*/_react.default.createElement(CallToAction, { | ||
url: copy.url, | ||
cta: copy.cta | ||
}))); | ||
}; | ||
exports.NoGaps = NoGaps; |
@@ -54,6 +54,10 @@ "use strict"; | ||
_ref$className = _ref.className, | ||
className = _ref$className === void 0 ? '' : _ref$className; | ||
className = _ref$className === void 0 ? '' : _ref$className, | ||
_ref$defaultOpened = _ref.defaultOpened, | ||
defaultOpened = _ref$defaultOpened === void 0 ? false : _ref$defaultOpened; | ||
var contentRef = (0, _react.useRef)(null); | ||
var id = (0, _react.useRef)("AccordionItem_".concat(generateId())); | ||
var _useRef = (0, _react.useRef)("AccordionItem_".concat(generateId())), | ||
id = _useRef.current; | ||
var _useState = (0, _react.useState)(false), | ||
@@ -64,9 +68,8 @@ _useState2 = _slicedToArray(_useState, 2), | ||
var item = id.current; | ||
var _useContext = (0, _react.useContext)(_Accordion.AccordionContext), | ||
noGapBetweenElements = _useContext.noGapBetweenElements, | ||
opened = _useContext.opened, | ||
onChange = _useContext.onChange; | ||
dispatch = _useContext.dispatch; | ||
var isHidden = !opened[item]; | ||
var isHidden = !opened[id]; | ||
@@ -78,3 +81,3 @@ var handleClickOnBody = function handleClickOnBody() { | ||
onChange(item, true); | ||
handleOpen(true); | ||
setIsHover(false); | ||
@@ -88,5 +91,21 @@ }; | ||
onChange(item, false); | ||
handleOpen(false); | ||
}; | ||
function handleOpen(value) { | ||
dispatch({ | ||
type: 'accordion/SET_OPENED', | ||
payload: { | ||
id: id, | ||
value: value | ||
} | ||
}); | ||
} | ||
(0, _react.useEffect)(function () { | ||
if (defaultOpened) { | ||
handleOpen(true); | ||
} //eslint-disable-next-line | ||
}, []); | ||
(0, _react.useLayoutEffect)(function () { | ||
@@ -150,8 +169,10 @@ var content = contentRef.current; | ||
}, [isHidden]); | ||
var isBorderHighlighted = isHover && !noGapBetweenElements; | ||
return /*#__PURE__*/_react.default.createElement(_Box.default, { | ||
color: "light", | ||
border: true, | ||
borderColor: isHover ? 'dark' : 'gray-secondary-lightest', | ||
borderColor: isBorderHighlighted ? 'dark' : 'gray-secondary-lightest', | ||
onClick: handleClickOnBody, | ||
className: (0, _classnames.default)('sg-accordion-item__pointer', { | ||
className: (0, _classnames.default)('sg-accordion-item', 'sg-accordion-item__pointer', { | ||
'sg-accordion-item--no-gap': noGapBetweenElements, | ||
'sg-accordion-item__pointer': !isHidden | ||
@@ -181,3 +202,2 @@ }, className), | ||
}, /*#__PURE__*/_react.default.createElement(_Link.default, { | ||
type: "h1", | ||
size: titleSize, | ||
@@ -184,0 +204,0 @@ color: "black", |
@@ -8,10 +8,6 @@ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
import React, { createContext, useCallback, useState } from 'react'; | ||
import React, { createContext, useReducer } from 'react'; | ||
import cx from 'classnames'; | ||
export var AccordionContext = /*#__PURE__*/createContext({ | ||
opened: {}, | ||
onChange: function onChange() { | ||
return undefined; | ||
} | ||
}); | ||
// $FlowFixMe context doesn't need to be defined here | ||
export var AccordionContext = /*#__PURE__*/createContext(); | ||
export var spaceClasses = { | ||
@@ -38,28 +34,37 @@ xxs: 'sg-space-y-xxs', | ||
var _useState = useState({}), | ||
_useState2 = _slicedToArray(_useState, 2), | ||
opened = _useState2[0], | ||
setOpened = _useState2[1]; | ||
var _useReducer = useReducer(reducer, { | ||
opened: {} | ||
}), | ||
_useReducer2 = _slicedToArray(_useReducer, 2), | ||
state = _useReducer2[0], | ||
dispatch = _useReducer2[1]; | ||
var handleChange = useCallback(function (item, value) { | ||
if (allowMultiple) { | ||
setOpened(_objectSpread(_objectSpread({}, opened), {}, _defineProperty({}, item, value))); | ||
} else { | ||
var newOpened = _objectSpread({}, opened); | ||
function reducer(state, action) { | ||
switch (action.type) { | ||
case 'accordion/SET_OPENED': | ||
{ | ||
var opened = state.opened; | ||
var _action$payload = action.payload, | ||
id = _action$payload.id, | ||
value = _action$payload.value; | ||
return _objectSpread(_objectSpread({}, state), {}, { | ||
opened: allowMultiple ? _objectSpread(_objectSpread({}, opened), {}, _defineProperty({}, id, value)) : _defineProperty({}, id, value) | ||
}); | ||
} | ||
Object.keys(newOpened).forEach(function (i) { | ||
return newOpened[i] = false; | ||
}); | ||
setOpened(_objectSpread(_objectSpread({}, newOpened), {}, _defineProperty({}, item, value))); | ||
default: | ||
return state; | ||
} | ||
}, [opened, allowMultiple]); | ||
var context = { | ||
onChange: handleChange, | ||
opened: opened | ||
}; | ||
var classes = cx(_defineProperty({}, "".concat(spaceClasses[spacing]), spaceClasses[spacing]), className); | ||
} | ||
var noGapBetweenElements = spacing === 'none'; | ||
var spaceClass = spacing === 'none' ? undefined : spaceClasses[spacing]; | ||
return /*#__PURE__*/React.createElement(AccordionContext.Provider, { | ||
value: context | ||
value: { | ||
noGapBetweenElements: noGapBetweenElements, | ||
opened: state.opened, | ||
dispatch: dispatch | ||
} | ||
}, /*#__PURE__*/React.createElement("div", { | ||
className: classes | ||
className: cx(spaceClass, className) | ||
}, children)); | ||
@@ -66,0 +71,0 @@ }; |
@@ -58,2 +58,30 @@ import React from 'react'; | ||
}))); | ||
}; | ||
export var NoGaps = function NoGaps() { | ||
return /*#__PURE__*/React.createElement(Accordion, { | ||
spacing: "none", | ||
allowMultiple: true | ||
}, /*#__PURE__*/React.createElement(AccordionItem, { | ||
title: copy.title, | ||
defaultOpened: true | ||
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, { | ||
url: copy.url, | ||
cta: copy.cta | ||
})), /*#__PURE__*/React.createElement(AccordionItem, { | ||
title: copy.title, | ||
defaultOpened: true | ||
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, { | ||
url: copy.url, | ||
cta: copy.cta | ||
})), /*#__PURE__*/React.createElement(AccordionItem, { | ||
title: copy.title | ||
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, { | ||
url: copy.url, | ||
cta: copy.cta | ||
})), /*#__PURE__*/React.createElement(AccordionItem, { | ||
title: copy.title | ||
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, { | ||
url: copy.url, | ||
cta: copy.cta | ||
}))); | ||
}; |
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; | ||
import React, { useContext, useLayoutEffect, useRef, useState } from 'react'; | ||
import React, { useContext, useLayoutEffect, useEffect, useRef, useState } from 'react'; | ||
import cx from 'classnames'; | ||
@@ -21,6 +21,10 @@ import Box from '../box/Box'; | ||
_ref$className = _ref.className, | ||
className = _ref$className === void 0 ? '' : _ref$className; | ||
className = _ref$className === void 0 ? '' : _ref$className, | ||
_ref$defaultOpened = _ref.defaultOpened, | ||
defaultOpened = _ref$defaultOpened === void 0 ? false : _ref$defaultOpened; | ||
var contentRef = useRef(null); | ||
var id = useRef("AccordionItem_".concat(generateId())); | ||
var _useRef = useRef("AccordionItem_".concat(generateId())), | ||
id = _useRef.current; | ||
var _useState = useState(false), | ||
@@ -31,9 +35,8 @@ _useState2 = _slicedToArray(_useState, 2), | ||
var item = id.current; | ||
var _useContext = useContext(AccordionContext), | ||
noGapBetweenElements = _useContext.noGapBetweenElements, | ||
opened = _useContext.opened, | ||
onChange = _useContext.onChange; | ||
dispatch = _useContext.dispatch; | ||
var isHidden = !opened[item]; | ||
var isHidden = !opened[id]; | ||
@@ -45,3 +48,3 @@ var handleClickOnBody = function handleClickOnBody() { | ||
onChange(item, true); | ||
handleOpen(true); | ||
setIsHover(false); | ||
@@ -55,5 +58,21 @@ }; | ||
onChange(item, false); | ||
handleOpen(false); | ||
}; | ||
function handleOpen(value) { | ||
dispatch({ | ||
type: 'accordion/SET_OPENED', | ||
payload: { | ||
id: id, | ||
value: value | ||
} | ||
}); | ||
} | ||
useEffect(function () { | ||
if (defaultOpened) { | ||
handleOpen(true); | ||
} //eslint-disable-next-line | ||
}, []); | ||
useLayoutEffect(function () { | ||
@@ -117,8 +136,10 @@ var content = contentRef.current; | ||
}, [isHidden]); | ||
var isBorderHighlighted = isHover && !noGapBetweenElements; | ||
return /*#__PURE__*/React.createElement(Box, { | ||
color: "light", | ||
border: true, | ||
borderColor: isHover ? 'dark' : 'gray-secondary-lightest', | ||
borderColor: isBorderHighlighted ? 'dark' : 'gray-secondary-lightest', | ||
onClick: handleClickOnBody, | ||
className: cx('sg-accordion-item__pointer', { | ||
className: cx('sg-accordion-item', 'sg-accordion-item__pointer', { | ||
'sg-accordion-item--no-gap': noGapBetweenElements, | ||
'sg-accordion-item__pointer': !isHidden | ||
@@ -148,3 +169,2 @@ }, className), | ||
}, /*#__PURE__*/React.createElement(Link, { | ||
type: "h1", | ||
size: titleSize, | ||
@@ -151,0 +171,0 @@ color: "black", |
{ | ||
"name": "brainly-style-guide", | ||
"version": "182.1.0", | ||
"version": "182.2.0", | ||
"description": "Brainly Front-End Style Guide", | ||
@@ -5,0 +5,0 @@ "repository": "https://github.com/brainly/style-guide.git", |
//@flow strict | ||
import React, {createContext, useCallback, useState} from 'react'; | ||
import React, {createContext, useReducer} from 'react'; | ||
import cx from 'classnames'; | ||
type StateType = $ReadOnly<{ | ||
opened: { | ||
[key: string]: boolean, | ||
}, | ||
}>; | ||
type ActionType = { | ||
type: 'accordion/SET_OPENED', | ||
payload: {id: string, value: boolean}, | ||
}; | ||
type PropType = $ReadOnly<{ | ||
@@ -10,20 +21,18 @@ allowMultiple?: boolean, | ||
className?: string, | ||
spacing?: 'xxs' | 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl' | 'xxxl' | 'xxxxl', | ||
spacing?: | ||
| 'xxs' | ||
| 'xs' | ||
| 's' | ||
| 'm' | ||
| 'l' | ||
| 'xl' | ||
| 'xxl' | ||
| 'xxxl' | ||
| 'xxxxl' | ||
| 'none', | ||
}>; | ||
type OpenedMapType = { | ||
[key: string]: boolean, | ||
..., | ||
}; | ||
// $FlowFixMe context doesn't need to be defined here | ||
export const AccordionContext = createContext(); | ||
type AccordionContextType = { | ||
opened: OpenedMapType, | ||
onChange: (item: string, value: boolean) => void, | ||
}; | ||
export const AccordionContext = createContext<AccordionContextType>({ | ||
opened: {}, | ||
onChange: () => undefined, | ||
}); | ||
export const spaceClasses = { | ||
@@ -47,30 +56,30 @@ xxs: 'sg-space-y-xxs', | ||
}: PropType) => { | ||
const [opened, setOpened] = useState({}); | ||
const [state, dispatch] = useReducer<StateType, ActionType>(reducer, { | ||
opened: {}, | ||
}); | ||
const handleChange = useCallback( | ||
(item: string, value: boolean) => { | ||
if (allowMultiple) { | ||
setOpened({...opened, [item]: value}); | ||
} else { | ||
const newOpened = {...opened}; | ||
function reducer(state: StateType, action: ActionType): StateType { | ||
switch (action.type) { | ||
case 'accordion/SET_OPENED': { | ||
const {opened} = state; | ||
const {id, value} = action.payload; | ||
Object.keys(newOpened).forEach(i => (newOpened[i] = false)); | ||
setOpened({...newOpened, [item]: value}); | ||
return { | ||
...state, | ||
opened: allowMultiple ? {...opened, [id]: value} : {[id]: value}, | ||
}; | ||
} | ||
}, | ||
[opened, allowMultiple] | ||
); | ||
default: | ||
return state; | ||
} | ||
} | ||
const context = {onChange: handleChange, opened}; | ||
const noGapBetweenElements = spacing === 'none'; | ||
const spaceClass = spacing === 'none' ? undefined : spaceClasses[spacing]; | ||
const classes = cx( | ||
{ | ||
[`${spaceClasses[spacing]}`]: spaceClasses[spacing], | ||
}, | ||
className | ||
); | ||
return ( | ||
<AccordionContext.Provider value={context}> | ||
<div className={classes}>{children}</div> | ||
<AccordionContext.Provider | ||
value={{noGapBetweenElements, opened: state.opened, dispatch}} | ||
> | ||
<div className={cx(spaceClass, className)}>{children}</div> | ||
</AccordionContext.Provider> | ||
@@ -77,0 +86,0 @@ ); |
@@ -89,2 +89,45 @@ import React from 'react'; | ||
}); | ||
it('displays no gaps between elements when spacing is set to "none"', () => { | ||
const accordion = mount( | ||
<Accordion spacing="none"> | ||
<AccordionItem title="Item 1">Accordion Item Description</AccordionItem> | ||
</Accordion> | ||
); | ||
expect(accordion.find('Box').hasClass('sg-accordion-item--no-gap')).toBe( | ||
true | ||
); | ||
}); | ||
it('does not change border on hover when spacing is set to "none"', () => { | ||
const accordion = mount( | ||
<Accordion spacing="none"> | ||
<AccordionItem title="Item 1">Accordion Item Description</AccordionItem> | ||
</Accordion> | ||
); | ||
accordion.find({title: 'Item 1'}).simulate('mouseenter'); | ||
expect(accordion.find('Box').prop('borderColor')).toEqual( | ||
'gray-secondary-lightest' | ||
); | ||
}); | ||
it('by default expands items that have "defaultOpened" prop', () => { | ||
const accordion = mount( | ||
<Accordion allowMultiple> | ||
<AccordionItem title="Item 1" defaultOpened> | ||
Accordion Item Description | ||
</AccordionItem> | ||
<AccordionItem title="Item 2" defaultOpened> | ||
Accordion Item Description | ||
</AccordionItem> | ||
<AccordionItem title="Item 3">Accordion Item Description</AccordionItem> | ||
</Accordion> | ||
); | ||
// hostNodes returns html elements and skip react components | ||
expect(accordion.find('[aria-expanded=true]').hostNodes()).toHaveLength(2); | ||
}); | ||
}); |
@@ -55,1 +55,18 @@ //@flow | ||
); | ||
export const NoGaps = () => ( | ||
<Accordion spacing="none" allowMultiple> | ||
<AccordionItem title={copy.title} defaultOpened> | ||
{copy.description} <CallToAction url={copy.url} cta={copy.cta} /> | ||
</AccordionItem> | ||
<AccordionItem title={copy.title} defaultOpened> | ||
{copy.description} <CallToAction url={copy.url} cta={copy.cta} /> | ||
</AccordionItem> | ||
<AccordionItem title={copy.title}> | ||
{copy.description} <CallToAction url={copy.url} cta={copy.cta} /> | ||
</AccordionItem> | ||
<AccordionItem title={copy.title}> | ||
{copy.description} <CallToAction url={copy.url} cta={copy.cta} /> | ||
</AccordionItem> | ||
</Accordion> | ||
); |
//@flow strict | ||
import React, {useContext, useLayoutEffect, useRef, useState} from 'react'; | ||
import React, { | ||
useContext, | ||
useLayoutEffect, | ||
useEffect, | ||
useRef, | ||
useState, | ||
} from 'react'; | ||
import type {Node} from 'react'; | ||
@@ -18,2 +24,3 @@ import cx from 'classnames'; | ||
className?: string, | ||
defaultOpened?: boolean, | ||
}>; | ||
@@ -32,11 +39,12 @@ | ||
className = '', | ||
defaultOpened = false, | ||
}: PropType) => { | ||
const contentRef = useRef<HTMLDivElement | null>(null); | ||
const id = useRef<string>(`AccordionItem_${generateId()}`); | ||
const {current: id} = useRef<string>(`AccordionItem_${generateId()}`); | ||
const [isHover, setIsHover] = useState(false); | ||
const item = id.current; | ||
const {opened, onChange} = useContext(AccordionContext); | ||
const isHidden = !opened[item]; | ||
const {noGapBetweenElements, opened, dispatch} = useContext(AccordionContext); | ||
const isHidden = !opened[id]; | ||
const handleClickOnBody = () => { | ||
@@ -46,3 +54,3 @@ if (!isHidden) { | ||
} | ||
onChange(item, true); | ||
handleOpen(true); | ||
setIsHover(false); | ||
@@ -55,5 +63,19 @@ }; | ||
} | ||
onChange(item, false); | ||
handleOpen(false); | ||
}; | ||
function handleOpen(value: boolean) { | ||
dispatch({ | ||
type: 'accordion/SET_OPENED', | ||
payload: {id, value}, | ||
}); | ||
} | ||
useEffect(() => { | ||
if (defaultOpened) { | ||
handleOpen(true); | ||
} | ||
//eslint-disable-next-line | ||
}, []); | ||
useLayoutEffect(() => { | ||
@@ -116,2 +138,4 @@ const content = contentRef.current; | ||
const isBorderHighlighted = isHover && !noGapBetweenElements; | ||
return ( | ||
@@ -121,7 +145,9 @@ <Box | ||
border | ||
borderColor={isHover ? 'dark' : 'gray-secondary-lightest'} | ||
borderColor={isBorderHighlighted ? 'dark' : 'gray-secondary-lightest'} | ||
onClick={handleClickOnBody} | ||
className={cx( | ||
'sg-accordion-item', | ||
'sg-accordion-item__pointer', | ||
{ | ||
'sg-accordion-item--no-gap': noGapBetweenElements, | ||
'sg-accordion-item__pointer': !isHidden, | ||
@@ -154,9 +180,3 @@ }, | ||
> | ||
<Link | ||
type="h1" | ||
size={titleSize} | ||
color="black" | ||
weight="bold" | ||
underlined={isHover} | ||
> | ||
<Link size={titleSize} color="black" weight="bold" underlined={isHover}> | ||
{title} | ||
@@ -163,0 +183,0 @@ </Link> |
@@ -45,3 +45,3 @@ import React from 'react'; | ||
}), | ||
{} | ||
{none: 'none'} | ||
), | ||
@@ -48,0 +48,0 @@ }, |
import React from 'react'; | ||
import DocsBlock from 'components/DocsBlock'; | ||
import {Default} from '../Accordion.stories'; | ||
import {Default, NoGaps} from '../Accordion.stories'; | ||
@@ -13,2 +13,5 @@ const accordion = () => ( | ||
</DocsBlock> | ||
<DocsBlock info="No gap between elements with first 2 elements opened by default"> | ||
<NoGaps /> | ||
</DocsBlock> | ||
</div> | ||
@@ -15,0 +18,0 @@ ); |
Sorry, the diff of this file is not supported yet
2316234
30431