Yoga Docs: Rename website-next
to website
(#1613)
Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1613 So that GitHub links to edit a page point to the right place. This will fail in OSS build until I switch the directory used by Vercel instance, but I am waiting to do that until ready to land, since that would cause other in progress changes to fail when exported. Reviewed By: joevilches Differential Revision: D54837857 fbshipit-source-id: 9bec90232dbe3ec8638568685671185d597fcf2d
26
website/.eslintrc.cjs
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
root: false,
|
||||
extends: [
|
||||
'plugin:react/recommended',
|
||||
'plugin:react/jsx-runtime',
|
||||
'plugin:react-hooks/recommended',
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'react/prop-types': 'off',
|
||||
'react/no-unstable-nested-components': 'error',
|
||||
},
|
||||
};
|
17
website/.gitignore
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Production
|
||||
/build
|
||||
|
||||
# Generated files
|
||||
.docusaurus
|
||||
.cache-loader
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
41
website/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Website
|
||||
|
||||
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
|
||||
|
||||
### Installation
|
||||
|
||||
```
|
||||
$ yarn
|
||||
```
|
||||
|
||||
### Local Development
|
||||
|
||||
```
|
||||
$ yarn start
|
||||
```
|
||||
|
||||
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
|
||||
|
||||
### Build
|
||||
|
||||
```
|
||||
$ yarn build
|
||||
```
|
||||
|
||||
This command generates static content into the `build` directory and can be served using any static contents hosting service.
|
||||
|
||||
### Deployment
|
||||
|
||||
Using SSH:
|
||||
|
||||
```
|
||||
$ USE_SSH=true yarn deploy
|
||||
```
|
||||
|
||||
Not using SSH:
|
||||
|
||||
```
|
||||
$ GIT_USER=<Your GitHub username> yarn deploy
|
||||
```
|
||||
|
||||
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
|
10
website/babel.config.cjs
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
||||
};
|
185
website/blog/2023-06-30-announcing-yoga-2.0.md
Normal file
@@ -0,0 +1,185 @@
|
||||
---
|
||||
slug: announcing-yoga-2.0
|
||||
title: Announcing Yoga 2.0
|
||||
authors:
|
||||
- NickGerleman
|
||||
---
|
||||
|
||||
We are excited to announce a new major (breaking) version of Yoga. This release contains 198 new commits from 64 contributors, and includes the first significant changes to Yoga in open-source since 2018.
|
||||
|
||||
While there has been a [long gap in development](https://github.com/facebook/yoga/issues/1151), the React Native team believes Yoga is a critical tool in delivering the future of React, and we have resumed development of the engine. This release of Yoga is focused on:
|
||||
1. Delivering the features we have shipped to React Native to standalone Yoga users
|
||||
2. Updating toolchains, packaging, and build systems to make Yoga easier to consume
|
||||
3. API changes to allow us to evolve the engine towards conformance
|
||||
|
||||
Yoga continuously ships to thousands of surfaces across multiple frameworks at Meta. This version of Yoga corresponds to the version which will be included in React Native 0.73 shipping this fall.
|
||||
|
||||
|
||||
## Flexbox gap
|
||||
|
||||
The most significant new feature for users on an older stable release of Yoga is the addition of Flexbox gap support. This powers `gap`, `rowGap`, and `columnGap` in React Native 0.71.
|
||||
|
||||
```cpp
|
||||
// Example.cpp
|
||||
YGNodeStyleSetGap(node, YGGutterRow, 2.0f);
|
||||
```
|
||||
|
||||
```java
|
||||
// Example.java
|
||||
node.setGap(YogaGutter.ROW, 2.0f);
|
||||
```
|
||||
|
||||
```ts
|
||||
// Example.ts
|
||||
node.setGap(Gutter.Row, 2);
|
||||
```
|
||||
|
||||
|
||||
## Toolchain
|
||||
|
||||
Meta uses [Buck](https://buck.build/) across its monorepo, but we recognize that Buck has acted as a barrier to be able to use Yoga outside of Meta. Yoga no longer ships build logic for Buck to open-source. We have instead added over 20 new validation jobs to GitHub Actions to continually validate that Yoga builds correctly in common systems and scenarios where Yoga is used in OSS.
|
||||
|
||||
New toolchain support includes:
|
||||
1. A reference CMake build for Yoga and its unit tests
|
||||
1. A modern Gradle build and published AARs
|
||||
1. Compatibility with XCode 14.3+
|
||||
1. Compatibility with Node 16+
|
||||
1. Support for WebAssembly in both Node and browsers
|
||||
1. Support for MSVC, higher warning levels, and building without exceptions
|
||||
|
||||
## Aiming for Conformance
|
||||
|
||||
Our team wants to enable engineers to be able to create a single style which renders faithfully across Yoga and web. Conformance is a moving target, with browsers like Chromium regularly making behavior changes to better achieve it. This requires making behavior changes to Yoga which break existing behaviors, for better consistency with the web.
|
||||
|
||||
In Yoga 2.0, we’ve generalized `UseLegacyStretchBehaviour` to a new [Errata API](https://github.com/facebook/yoga/issues/1247), to allow different parts of a Yoga tree to target different conformance levels. This allows rendering part of the tree to be compatible with styles written for web, with other parts compatible with styles written for older versions of Yoga.
|
||||
|
||||
Yoga's default behavior going forward is W3C compliance. We recommend users sensitive to the change to set `YGErrataClassic,` or `YGErrataAll` if you were already setting `UseLegacyStretchBehaviour`.
|
||||
|
||||
```cpp
|
||||
// Example.cpp
|
||||
YGConfigRef config = YGConfigNew();
|
||||
YGConfigSetErrata(config, YGErrataClassic);
|
||||
|
||||
YGNodeRef node = YGNodeNewWithConfig(config);
|
||||
```
|
||||
|
||||
```java
|
||||
// Example.java
|
||||
YogaConfig config = YogaConfigFactory.create();
|
||||
config.setErrata(YogaErrata.CLASSIC);
|
||||
|
||||
YogaNode node = YogaNodeFactory.create(config);
|
||||
```
|
||||
|
||||
```ts
|
||||
// Example.ts
|
||||
const config = Config.create();
|
||||
config.setErrata(Errata.Classic);
|
||||
|
||||
const node = Node.create(config);
|
||||
```
|
||||
|
||||
## Yoga for JavaScript
|
||||
|
||||
Yoga’s previous JavaScript bindings are not installable when using Node 12+, making them effectively unusable in today’s JavaScript ecosystem. We now ship a new package with prebuilt binaries and first-class support for TypeScript and modern bundlers.
|
||||
|
||||
Two variants are shipped:
|
||||
|
||||
1. An asmjs variant for compatibility
|
||||
1. A JS module with embedded WebAssembly (~50% faster)
|
||||
|
||||
Both are about 45KB when gzipped.
|
||||
|
||||
|
||||
WebAssembly binaries must be asynchronously compiled and loaded in Chrome. In the absence of universal support for top-level await, we have made the breaking change to require explicitly asynchronously loading Yoga before using it.
|
||||
|
||||
```ts
|
||||
import {loadYoga, Align} from 'yoga-layout';
|
||||
|
||||
const Yoga = await loadYoga();
|
||||
const node = Yoga.Node.create();
|
||||
node.setAlignContent(Align.Center);
|
||||
```
|
||||
|
||||
|
||||
The previous behavior of blocking to load the binary can be replicated by importing from the `yoga-layout/sync` entrypoint, but this is not recommended for new usages, and does not allow using WebAssembly on browsers.
|
||||
|
||||
```ts
|
||||
import Yoga, {ALIGN_CENTER} from 'yoga-layout/sync';
|
||||
|
||||
const node = Yoga.Node.create();
|
||||
node.setAlignContent(ALIGN_CENTER);
|
||||
```
|
||||
|
||||
`yoga-layout` and `yoga-layout/sync` try to pick between `asmjs` and `WebAssembly` automatically based on the [target environment](https://webpack.js.org/guides/package-exports/#target-environment) set by your bundler, but you can choose this explicitly as well.
|
||||
|
||||
```ts
|
||||
import {loadYoga} from 'yoga-layout/wasm-async';
|
||||
```
|
||||
|
||||
> Note: the `yoga-layout` package requires your bundler and typechecker to configured to be able to follow the package `exports `field.
|
||||
|
||||
|
||||
## Deprecations and removals
|
||||
|
||||
### YogaKit and YogaLayout ViewGroup
|
||||
We are deprecating, `YogaKit` and the `YogaLayout` ViewGroup. These libraries allow initegrating Yoga directly with UIKit and the Android view system, but are not widely used by Meta in production. We are instead focusing on higher-level libraries using Yoga like [Litho](https://fblitho.com/) and [React Native](https://reactnative.dev/). Because we aren’t in a place to continue development, or validate contributions, we are discontinuing development. These libraries will not receive future updates beyond the Yoga `release-v2.0` branch.
|
||||
|
||||
### UseLegacyStretchBehaviour
|
||||
The functions to manipulate `UseLegacyStretchBehaviour` have been deprecated. Previous users of the API should now set an appropriate errata level, like `YGErrataAll` to opt-out of all future conformance fixes.
|
||||
|
||||
### C# bindings
|
||||
C# bindings were contributed to the Yoga repo but have since degraded. The bindings have not had working build validation, or a consistent contributor. We have removed them from the Yoga repo, but we will continue to provide a public C ABI for others to build bindings on top of.
|
||||
|
||||
### Private C++ APIs
|
||||
Yoga’s header structure has historically allowed the inclusion of concrete internal structures like `YGStyle` or `YGNode`. We will begin to enforce that users instead rely on the public C APIs provided by `#include <yoga/Yoga.h>`. Other C++ APIs may change without notice.
|
||||
|
||||
```cpp
|
||||
// Public API (GOOD)
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
YGConfigRef config = YGConfigNew();
|
||||
YGConfigSetPointScaleFactor(config, 1.0f);
|
||||
```
|
||||
|
||||
```cpp
|
||||
// Private API (BAD)
|
||||
#include <yoga/YGConfig.h>
|
||||
|
||||
YGConfig config{yogaLogger_};
|
||||
config.pointScaleFactor = 1.0f;
|
||||
```
|
||||
|
||||
|
||||
### C++ 11 Support
|
||||
|
||||
Yoga now requires a compiler which supports C++ 14. This will likely be bumped to C++ 17 in a future minor release.
|
||||
|
||||
|
||||
## How do I get it?
|
||||
|
||||
For users who don’t want to build from source, new Yoga packages have been published to the npmjs registry, Maven Central, and CocoaPods.
|
||||
|
||||
```json5
|
||||
// package.json
|
||||
dependencies: {
|
||||
"yoga-layout": "^2.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
```gradle
|
||||
// build.gradle
|
||||
dependencies {
|
||||
implementation("com.facebook.yoga:yoga:2.0.0")
|
||||
}
|
||||
```
|
||||
|
||||
```rb
|
||||
# Podfile
|
||||
pod 'Yoga', '~> 2.0.0'
|
||||
```
|
||||
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Yoga 2.0 contains major external contributions from [@intergalacticspacehighway](https://github.com/intergalacticspacehighway), [@jacobp100](https://github.com/jacobp100), [@jeetiss](https://github.com/jeetiss) and [@nicoburns](https://github.com/nicoburns).
|
10
website/blog/authors.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
NickGerleman:
|
||||
name: Nick Gerleman
|
||||
title: Yoga Maintainer
|
||||
url: https://github.com/NickGerleman
|
||||
image_url: https://github.com/NickGerleman.png
|
||||
joevilches:
|
||||
name: Joe Vilches
|
||||
title: Yoga Maintainer
|
||||
url: https://github.com/joevilches
|
||||
image_url: https://github.com/joevilches.png
|
613
website/blog/yoga-3-release/2024-05-11-announcing-yoga-3.0.md
Normal file
@@ -0,0 +1,613 @@
|
||||
---
|
||||
slug: announcing-yoga-3.0
|
||||
title: Announcing Yoga 3.0
|
||||
authors:
|
||||
- NickGerleman
|
||||
- joevilches
|
||||
---
|
||||
|
||||
Yoga 3.0 is a new major (breaking) release of Yoga. This version of Yoga spans [242 commits](https://github.com/facebook/yoga/compare/release-v2.0...release-v3.0) across 16 contributors and is included in React Native 0.74.
|
||||
|
||||
|
||||
## Highlights
|
||||
|
||||
1. Support for `position: static`
|
||||
2. Support for `align-content: space-evenly`
|
||||
3. Improvements to layout correctness
|
||||
4. Yoga’s JavaScript bindings are now distributed as an ES Module
|
||||
5. Some existing Yoga APIs have been removed
|
||||
|
||||
|
||||
## position: static
|
||||
|
||||
We added full support for the `static` position type which has existed in an incomplete state for some time now. With this release `static` is now web-compliant in the context of flexbox. Some things that were added/changed:
|
||||
|
||||
* The default position type is now `relative` [again](https://github.com/facebook/yoga/commit/fc88b2f774f0ab9090d7ca15de6680f26d7285ad) and not `static`. This should not have any effect on layout as the previously introduced `YGPostitionTypeStatic` was not being used within Yoga, so it behaved just like `relative`.
|
||||
* `static` nodes ignore insets (`left`, `right`, `top`, `bottom`, etc.)
|
||||
* The idea of a[ containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block) was introduced. For `absolute` nodes this is usually the nearest non-`static` ancestor. For every other position type this is just the parent since Yoga is a flexbox implementation.
|
||||
* A new public API `YGNodeSetAlwaysFormsContainingBlock` which takes a boolean indicating if the node should always form a containing block for any descendant. This is useful for properly supporting things like [transforms](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_transforms), which will force the node to form a containing block but is outside the scope of Yoga.
|
||||
|
||||
|
||||
`position: static` affects some concerns outside of layout, like stacking context. The full set of behaviors is enabled in the React Native New Architecture.
|
||||
|
||||
|
||||
## Better support for absolute positioning
|
||||
|
||||
There were a variety of bugs with how `absolute` nodes were positioned under various `Justify` and `Align` values. Most of these bugs only ever manifested themselves with certain paddings, margins, and borders so the following examples mix those up to illustrate the differences. Additionally, the following positioning examples all share this core style:
|
||||
|
||||
```js
|
||||
parent: {
|
||||
backgroundColor: 'green',
|
||||
height: 200,
|
||||
width: 200,
|
||||
},
|
||||
child: {
|
||||
position: 'absolute',
|
||||
backgroundColor: 'blue',
|
||||
height: 50,
|
||||
width: 50,
|
||||
},
|
||||
```
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td>Style</td><td>Before</td><td>After</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
||||
```js
|
||||
parent: {
|
||||
// core styles
|
||||
paddingLeft: 10,
|
||||
paddingRight: 20,
|
||||
borderLeftWidth: 10,
|
||||
borderRightWidth: 20,
|
||||
alignItems: 'flex-start',
|
||||
},
|
||||
child: {
|
||||
// core styles
|
||||
paddingLeft: 10,
|
||||
paddingRight: 20,
|
||||
marginLeft: 10,
|
||||
marginRight: 20,
|
||||
borderLeftWidth: 10,
|
||||
borderRightWidth: 20,
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
||||
```js
|
||||
parent: {
|
||||
// core styles
|
||||
paddingTop: 10,
|
||||
paddingBottom: 20,
|
||||
borderTopWidth: 10,
|
||||
borderBottomWidth: 20,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
child: {
|
||||
// core styles
|
||||
paddingTop: 10,
|
||||
paddingBottom: 20,
|
||||
marginTop: 10,
|
||||
marginBottom: 20,
|
||||
borderTopWidth: 10,
|
||||
borderBottomWidth: 20,
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
||||
```js
|
||||
parent: {
|
||||
// core styles
|
||||
paddingTop: 10,
|
||||
paddingBottom: 20,
|
||||
borderTopWidth: 10,
|
||||
borderBottomWidth: 20,
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
child: {
|
||||
// core styles
|
||||
paddingTop: 10,
|
||||
paddingBottom: 20,
|
||||
marginTop: 10,
|
||||
marginBottom: 20,
|
||||
borderTopWidth: 10,
|
||||
borderBottomWidth: 20,
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
There were other fixes not specifically mentioned above. Because this change may result in layout differences for many real-world scenarios, Yoga may be configured to prefer the legacy behavior, by setting the `AbsolutePositioningIncorrect` erratum. This means this fix is not enabled by default in frameworks like React Native, in order to preserve compatibility.
|
||||
|
||||
|
||||
Additionally, Yoga will now correctly account for padding when calculating the size of `absolute` nodes with percentage lengths.absolute size of percentage lengths referring to an absolutely positioned node.
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td>Style</td><td>Before</td><td>After</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
||||
```js
|
||||
parent: {
|
||||
backgroundColor: 'green',
|
||||
height: 200,
|
||||
width: 200,
|
||||
padding: 50,
|
||||
},
|
||||
child: {
|
||||
position: 'absolute',
|
||||
backgroundColor: 'blue',
|
||||
height: '25%',
|
||||
width: '25%',
|
||||
},
|
||||
```
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
Just like with positioning, this fix may result in layout differences in many cases. Setting the `AbsolutePercentAgainstInnerSize` erratum will preserve the legacy behavior, which is set by default in frameworks like React Native.
|
||||
|
||||
|
||||
## Better support for multiline containers
|
||||
|
||||
Yoga now offers better support for Flexbox containers which span multiple lines.
|
||||
|
||||
Yoga now supports `align-content: space-evenly`, contributed by [@nicoburns](https://github.com/nicoburns), to distribute line boxes with equal space around them.
|
||||
|
||||

|
||||
|
||||
> https://www.w3.org/TR/css-align-3/#distribution-values
|
||||
|
||||
Yoga now correctly supports the combination of `align-content` and `align-items` when both cause changes to alignment.
|
||||
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td>Style</td><td>Before</td><td>After</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
||||
```jsx
|
||||
|
||||
<Node
|
||||
style={{
|
||||
width: 300,
|
||||
height: 300,
|
||||
backgroundColor: 'red',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
alignContent: 'space-around',
|
||||
alignItems: 'flex-end',
|
||||
}}
|
||||
>
|
||||
<Node
|
||||
style={{
|
||||
width: 150,
|
||||
height: 50,
|
||||
backgroundColor: 'powderblue',
|
||||
}}
|
||||
/>
|
||||
<Node
|
||||
style={{
|
||||
width: 120,
|
||||
height: 100,
|
||||
backgroundColor: 'skyblue',
|
||||
}}
|
||||
/>
|
||||
<Node
|
||||
style={{
|
||||
width: 120,
|
||||
height: 50,
|
||||
backgroundColor: 'steelblue',
|
||||
}}
|
||||
/>
|
||||
</Node>
|
||||
```
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
> https://github.com/facebook/yoga/issues/1008
|
||||
|
||||
|
||||
Yoga now correctly supports `min-height` set on a multiline container.
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td>Style</td><td>Before</td><td>After</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
||||
```jsx
|
||||
<Node
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
width: 150,
|
||||
minHeight: 200,
|
||||
backgroundColor: 'blue',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'center',
|
||||
padding: 10,
|
||||
gap: 10,
|
||||
}}
|
||||
>
|
||||
<Node
|
||||
style={{
|
||||
backgroundColor: 'red',
|
||||
height: 100,
|
||||
width: 100,
|
||||
}}
|
||||
/>
|
||||
<Node
|
||||
style={{
|
||||
backgroundColor: 'red',
|
||||
height: 100,
|
||||
width: 100,
|
||||
}}
|
||||
/>
|
||||
</Node>
|
||||
```
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
## Correct handling of logical edges in row-reverse containers
|
||||
|
||||
Yoga would previously incorrectly reverse `start` and `end` edges, when operating on:
|
||||
|
||||
1. The padding, border, or margin of a row-reverse container
|
||||
2. The position, of the child of a row-reverse container
|
||||
|
||||
In React Native, this also presents as `left` and `right` edges being swapped inside of row-reverse containers.
|
||||
|
||||
We determined that few enough surfaces are impacted by this bug to enable the correct behavior globally. Existing row-reverse containers which run into these cases may need to be updated to layout correctly in newer versions of Yoga.
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td>Style</td><td>Before</td><td>After</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
||||
```jsx
|
||||
<Node
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
backgroundColor: 'red',
|
||||
margin: 10,
|
||||
width: 200,
|
||||
height: 100,
|
||||
}}
|
||||
>
|
||||
<Node
|
||||
style={{
|
||||
flexDirection: 'row-reverse',
|
||||
backgroundColor: 'blue',
|
||||
flex: 1,
|
||||
marginStart: 50,
|
||||
}}
|
||||
>
|
||||
<Node
|
||||
style={{
|
||||
backgroundColor: 'green',
|
||||
height: '50%',
|
||||
flex: 1,
|
||||
marginStart: 50,
|
||||
}}
|
||||
/>
|
||||
</Node>
|
||||
</Node>
|
||||
```
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
## Correct main-axis size calculation for indefinite containers using `justify-content`
|
||||
|
||||
Yoga previously calculated an incorrect main-axis size for containers which specified a min-dimension on the main axis, and have a `justify-content` of `space-around` or `space-between`.
|
||||
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td>Style</td><td>Before</td><td>After</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>
|
||||
|
||||
```jsx
|
||||
<Node
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
backgroundColor: 'red',
|
||||
height: 75,
|
||||
minWidth: 200,
|
||||
gap: 10,
|
||||
padding: 10,
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Node
|
||||
style={{
|
||||
backgroundColor: 'blue',
|
||||
width: 50,
|
||||
height: 50,
|
||||
}}
|
||||
/>
|
||||
<Node
|
||||
style={{
|
||||
backgroundColor: 'blue',
|
||||
width: 50,
|
||||
height: 50,
|
||||
}}
|
||||
/>
|
||||
</Node>
|
||||
|
||||
```
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||

|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
This change was observed to impact existing layouts rarely enough to enable globally, and while this change was not present in Yoga 2.0, it was present in the version of Yoga ultimately shipped in React Native 0.73.
|
||||
|
||||
|
||||
## Distribution as an ES Module
|
||||
|
||||
Yoga’s previous JavaScript package exported a convoluted matrix of different binaries, across asm.js and wasm, sync vs async, and browser vs node.
|
||||
|
||||
When it came time to look at adding ES Module support into the mix, we decided to take a [forward looking approach](https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration), and distribute Yoga as an ES Module, using top-level await, loading WebAssembly. This allows distributing a single binary which presents a sync looking API, even in browsers.
|
||||
|
||||
The underlying binary is still distributed as a JavaScript blob of base64 encoded WebAssembly, usable across different environments and bundlers.
|
||||
|
||||
|
||||
## Java reliability improvements
|
||||
|
||||
Several crashes have been fixed in Yoga’s Java bindings:
|
||||
|
||||
1. Yoga for Java [no longer performs an invalid read](https://github.com/facebook/yoga/commit/38ad93c87baa2127872892a6da674fc93e84f4b8) if a message is logged
|
||||
2. Yoga for Java now makes [more efficient use of JNI references](https://github.com/facebook/yoga/commit/49fbd406b62566d8b243297725d3485d9de9d442). This can help avoid app crashes in large trees, or interaction with other layout systems also using JNI.
|
||||
|
||||
|
||||
|
||||
## Infrastructure changes
|
||||
|
||||
Yoga’s implementation now targets a well-supported subset of C++ 20. Supported toolchains include:
|
||||
|
||||
1. MSVC 2019+
|
||||
2. Clang/libc++ 14+
|
||||
3. GCC/libstdc++ 11+
|
||||
4. Android NDK 26+
|
||||
5. XCode 14.3+
|
||||
|
||||
Yoga’s reference Android build and accompanying artifacts now target Android SDK 34.
|
||||
|
||||
Yoga now compiles cleanly against higher warning levels, such as `-Wextra` and `-Wconversion` in Clang/GCC, and `/W4` in MSVC.
|
||||
|
||||
|
||||
## Deprecations and removals
|
||||
|
||||
|
||||
### Changes to C++ APIs
|
||||
|
||||
Yoga’s previous structure made it easy to intermingle Yoga’s public APIs, and Yoga’s C++ implementation structures. The boundary between these two has been made firmer.
|
||||
|
||||
1. Every top-level header is now a public API
|
||||
2. All public APIs may be used from C, C++, Objective C, and Swift
|
||||
|
||||
|
||||
We have made some minor changes to this public API, which will require changes for Yoga integrators. The most significant is an increased const-correctness, which may require mechanical changes to measure functions. Yoga’s internal implementation has seen more radical changes.
|
||||
|
||||
|
||||
### Removal of UseLegacyStretchBehaviour
|
||||
|
||||
APIs related to “UseLegacyStretchBehaviour” were deprecated as part of Yoga 2.0, and have now been removed. Users of “UseLegacyStretchBehaviour” most often want to enable `YGErrataAll`, to opt-out of future conformance fixes.
|
||||
|
||||
|
||||
### Removal of YogaKit and the YogaLayout ViewGroup
|
||||
|
||||
Yoga previously provided direct integrations with UIKit, and the Android View System. These were deprecated as part of Yoga 2.0 and are no longer published as part of Yoga 3.0.
|
||||
|
||||
### Per-node `pointScaleFactor`
|
||||
|
||||
Yoga would previously only ever read the `pointScaleFactor` associated with the root node, even if child nodes configured a different value. Yoga now respects the `pointScaleFactor` associated with a given node. This change may be breaking for code which previously set a scale factor on a config used by the root node, where a different value was provided to child nodes.
|
||||
|
||||
## Integrating Yoga into your project
|
||||
|
||||
Yoga includes a reference CMake build, and has official bindings published across several package managers:
|
||||
|
||||
**JavaScript**
|
||||
|
||||
```json
|
||||
// package.json
|
||||
{
|
||||
"dependencies": {
|
||||
"yoga-layout": "^3.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Android**
|
||||
|
||||
```kts
|
||||
// build.gradle.kts
|
||||
dependencies {
|
||||
implementation("com.facebook.yoga:yoga:3.0.0")
|
||||
}
|
||||
```
|
||||
|
||||
**CocoaPods**
|
||||
|
||||
```rb
|
||||
# Podfile
|
||||
pod 'Yoga', '~> 3.0.0'
|
||||
```
|
||||
|
||||
**SwiftPM** (new, contributed by [@cntrump](https://github.com/cntrump))
|
||||
|
||||
```swift
|
||||
// Package.swift
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/facebook/yoga.git", from: "3.0.0")
|
||||
],
|
||||
)
|
||||
```
|
BIN
website/blog/yoga-3-release/img/image1.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
website/blog/yoga-3-release/img/image10.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
website/blog/yoga-3-release/img/image11.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
website/blog/yoga-3-release/img/image12.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
website/blog/yoga-3-release/img/image13.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
website/blog/yoga-3-release/img/image14.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
website/blog/yoga-3-release/img/image15.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
website/blog/yoga-3-release/img/image16.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
website/blog/yoga-3-release/img/image17.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
website/blog/yoga-3-release/img/image2.png
Normal file
After Width: | Height: | Size: 118 KiB |
BIN
website/blog/yoga-3-release/img/image3.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
website/blog/yoga-3-release/img/image4.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
website/blog/yoga-3-release/img/image5.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
website/blog/yoga-3-release/img/image6.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
website/blog/yoga-3-release/img/image7.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
website/blog/yoga-3-release/img/image8.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
website/blog/yoga-3-release/img/image9.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
13
website/docs/about-yoga.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# About Yoga
|
||||
|
||||
Yoga is an embeddable layout system used in popular UI frameworks like React Native. Yoga itself is not a UI framework, and does not do any drawing itself. Yoga's only responsibility is determining the size and position of boxes.
|
||||
|
||||

|
||||
|
||||
Yoga supports a familiar subset of CSS, mostly focused on Flexbox. This gives users a familiar model, and enables sharing code between native platforms and the browser.
|
||||
|
||||
Yoga is written in C++, with a public C API. This allows Yoga to be used by a wide variety of languages, via both offficial and unofficial bindings.
|
4
website/docs/advanced/_category_.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"label": "Advanced",
|
||||
"position": 3
|
||||
}
|
89
website/docs/advanced/containing-block.md
Normal file
@@ -0,0 +1,89 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Containing block
|
||||
|
||||
Often times certain properties depend on a node beyond the
|
||||
one it is applied to. An example of this is percentage lengths like `width: 50%` which
|
||||
will set the width of a node to 50% of some other length. That other length is determined
|
||||
by the size of the _containing block_. A containing block is not a Yoga-specific
|
||||
concept and exists in the [web](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block),
|
||||
but since Yoga only implements a subset of web browser capabilities the behavior of
|
||||
containing blocks is much more streamlined and it is helpful to frame it differently.
|
||||
|
||||
### Identifying the containing block of a node
|
||||
|
||||
- If the [position type](/docs/styling/position) of a node is static or relative then the containing block
|
||||
is always the _content box_ of the parent. This is because in Yoga every node is a
|
||||
flex container and therefore establishes a formatting context which would form a
|
||||
containing block on the web. The content box is formed by the node without margin, padding, or borders.
|
||||
- If the [position type](/docs/styling/position) of a node is absolute then the containing block will be
|
||||
the _padding box_ (the content box plus padding) of any of:
|
||||
- The nearest non-static ancestor.
|
||||
- The nearest ancestor which is configured to always form a containing block. This
|
||||
is helpful for supporting things outside of Yoga which would form a containing block
|
||||
on the web, such as [filters](https://developer.mozilla.org/en-US/docs/Web/CSS/filter)
|
||||
or [transforms](https://developer.mozilla.org/en-US/docs/Web/CSS/transform). This
|
||||
is done by calling the corresponding API for the lanuage you are working in.
|
||||
<Tabs groupId="language">
|
||||
<TabItem value="cpp" label="C/C++">
|
||||
```cpp
|
||||
YGNodeSetAlwaysFormsContainingBlock(node, true /*alwaysFormsContainingBlock*/);
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="java" label="Java">
|
||||
```java
|
||||
node.setAlwaysFormsContainingBlock(true /*alwaysFormsContainingBlock*/);
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="ts" label="Typescript">
|
||||
```typescript
|
||||
node.setAlwaysFormsContainingBlock(true /*alwaysFormsContainingBlock*/);
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
- The root if none of the above apply. Note that this is different from the web
|
||||
which has the notion of the _initial containing block_ that depends on the size
|
||||
of the viewport.
|
||||
- If the node in question is the root then there is no containing block, but it will
|
||||
use the `availableWidth` and `availableHeight` that is passed in to the call to
|
||||
[`CalculateLayout`](/docs/getting-started/laying-out-a-tree).
|
||||
|
||||
### What the containing block affects
|
||||
|
||||
- Any percentage-based lengths will depend on the size of the containing block.
|
||||
Specifically the [height](/docs/styling/width-height), top, and bottom properties will use the height of the
|
||||
containing block. The [width](/docs/styling/width-height), left, right, [margin](/docs/styling/margin-padding-border),
|
||||
and [padding](/docs/styling/margin-padding-border) will use the width of the containing block.
|
||||
- Any insets (left, right, top, bottom, etc.) applied to absolute nodes will be
|
||||
relative to the corresponding edge of the containing block.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: 10
|
||||
}}>
|
||||
<Node
|
||||
style={{
|
||||
height: 100,
|
||||
width: 100,
|
||||
position: 'static'
|
||||
}}>
|
||||
<Node
|
||||
style={{
|
||||
height: 25,
|
||||
width: '50%',
|
||||
bottom: 10,
|
||||
position: 'absolute'
|
||||
}}
|
||||
/>
|
||||
</Node>
|
||||
</Node>
|
||||
</Layout>`} />
|
106
website/docs/advanced/external-layout-systems.mdx
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Integrating with external layout systems
|
||||
|
||||
It is typical for applications to have content whose size may be dependent on factors not expressible inside of Yoga. This can often include text, or views which are rendered or laid out using a different system. Yoga allows leaf nodes to delegate to a different layout system via **Measure Functions**.
|
||||
|
||||
## Setting a measure function
|
||||
|
||||
A measure function (callback) is set on a node, to instruct Yoga to ask an external layout system for sizing of a given structure when it is time to measure the leaf node.
|
||||
|
||||
<Tabs groupId="language">
|
||||
|
||||
<TabItem value="cpp" label="C/C++">
|
||||
|
||||
Measure functions in the C/C++ APIs are represented as C function pointers and do not carry state. A Yoga node may be associated with an external structure by setting a **context** on the node. This is a `void*` tag, which may be read during callbacks.
|
||||
|
||||
|
||||
```cpp
|
||||
Widget widget{};
|
||||
|
||||
YGNodeSetContext(node, &w);
|
||||
YGNodeSetMeasureFunc(node, &measureWidget);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="java" label="Java">
|
||||
|
||||
Measure functions are represented by the `YogaMeasureFunction` interface. This interface can be fulfilled by an explicit subclass, an anonymous inner class, or a lambda. Framework data may be associated with the underlying measure function, or a global measure function may be used, with data set on the underlying Yoga node.
|
||||
|
||||
|
||||
```java
|
||||
Widget widget = new Widget();
|
||||
|
||||
node.setData(widget);
|
||||
node.setMeasureFunction(MEASURE_WIDGET);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
Measure functions are represented as an anonymous function, which may be bound to framework data.
|
||||
|
||||
```ts
|
||||
const widget = new Widget();
|
||||
|
||||
node.setMeasureFunction((width, widthMode, height, heightMode) => {
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Responding with measurements
|
||||
|
||||
Yoga will call a node's measure function if the node does not otherwise have a definite dimension. This measure function is given the available space in each axis if constrained, with border and padding already subtracted.
|
||||
|
||||
:::warning
|
||||
|
||||
Yoga is not guaranteed to call a node's measure function if the node already has a definite dimension. Final content dimensions for a node should be read from the node's layout results, instead of caching measure function results.
|
||||
|
||||
:::
|
||||
|
||||
Each axis is passed a `MeasureMode` as a constraint:
|
||||
1. `Exactly`: The measured length of the given axis is imposed to be the available length. This corresponds to [`stretch-fit`](https://www.w3.org/TR/css-sizing-3/#stretch-fit-size) sizing.
|
||||
2. `Undefined`: The measured length in the given axis should be the maximum natural length of the content. This corresponds to [`max-content`](https://www.w3.org/TR/css-sizing-3/#max-content) sizing.
|
||||
3. `AtMost`: The measured length in the given axis should be the minimum of the available space in the axis, and the natural content size. This corresponds to [`fit-content`](https://www.w3.org/TR/css-sizing-3/#fit-content-size) sizing.
|
||||
|
||||
## Invalidating measurements
|
||||
|
||||
Yoga must be notified if the content associated with a node changes in a way which may effect measurement.
|
||||
|
||||
<Tabs groupId="language">
|
||||
|
||||
<TabItem value="cpp" label="C/C++">
|
||||
|
||||
```cpp
|
||||
YGNodeMarkDirty(node);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="java" label="Java">
|
||||
|
||||
|
||||
```java
|
||||
node.dirty();
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
```ts
|
||||
node.markDirty();
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
75
website/docs/advanced/incremental-layout.mdx
Normal file
@@ -0,0 +1,75 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Incremental layout
|
||||
|
||||
Most real-world UIs are not static. Yoga trees may be laid out incrementally to avoid large work when only a small portion of the UI changes. Yoga will automatically mark a node and its ancestors as "dirty" if the node's style or children are changed. During the first layout, all nodes are considered dirty, and every node is visited. On subsequent layout, any nodes that are not dirty are skipped, so long as their parent constraints have not changed.
|
||||
|
||||
Yoga exposes whether the layout of a node or its children have changed via a `HasNewLayout` flag. This flag may be read when applying Yoga layout results to avoid traversing any subtrees where there are no updates.
|
||||
|
||||
<Tabs groupId="language">
|
||||
|
||||
<TabItem value="cpp" label="C/C++">
|
||||
|
||||
```cpp
|
||||
void applyLayout(YGNodeRef node) {
|
||||
if (!YGNodeHasNewLayout(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset the flag
|
||||
YGNodeSetHasNewLayout(node, false);
|
||||
|
||||
// Do the real work
|
||||
...
|
||||
|
||||
for (size_t i = 0; i < YGNodeGetChildCount(node); i++) {
|
||||
applyLayout(YGNodeGetChild(node, i));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="java" label="Java">
|
||||
|
||||
```java
|
||||
void applyLayout(YogaNode node) {
|
||||
if (!node.hasNewLayout()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset the flag
|
||||
node.markLayoutSeen();
|
||||
|
||||
// Do the real work
|
||||
...
|
||||
|
||||
for (int i = 0; i < node.getChildCount(); i++) {
|
||||
applyLayout(node.getChildAt(i));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
:::danger
|
||||
|
||||
Yoga's JavaScript bindings are missing support for acessing the `HasNewLayout` flag. https://github.com/facebook/yoga/issues/681
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
In the below example, we start with an already laid out tree. The style of `F` is then modified, dirtying the node and its ancestors. After layout, the dirtied nodes, and any effected children, are marked as having new layout.
|
||||
|
||||
| Clean tree | Dirtied tree | Has new layout |
|
||||
| - | - | - |
|
||||
|  |  |  |
|
4
website/docs/getting-started/_category_.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"label": "Getting Started",
|
||||
"position": 2
|
||||
}
|
165
website/docs/getting-started/configuring-yoga.mdx
Normal file
@@ -0,0 +1,165 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Configuring Yoga
|
||||
|
||||
Yoga may be configured to use different behavior, using a **Yoga Config**. A config is attached to a specific Yoga Node, allowing different parts of the Yoga tree to behave differently during layout.
|
||||
|
||||
Most UI frameworks will apply a single uniform configuration. It is common in these cases to allocate a single Yoga Config which lasts the duration of the application. Other ownership structures are possible, which allow scenarios like laying out part of a tree with a different layout conformance than another part of the tree.
|
||||
|
||||
| Global | Per-node | Contextual |
|
||||
| - | - | - |
|
||||
|  |  |  |
|
||||
|
||||
<Tabs groupId="language">
|
||||
|
||||
<TabItem value="cpp" label="C/C++">
|
||||
|
||||
```cpp
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
YGConfigRef config = YGConfigNew();
|
||||
// Setup config...
|
||||
|
||||
YGNodeRef root = YGNodeNewWithConfig(config);
|
||||
```
|
||||
|
||||
:::warning
|
||||
|
||||
Yoga configs are not freed automatically, and should be freed via `YGConfigFree(config)` when no longer needed.
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="java" label="Java">
|
||||
|
||||
```java
|
||||
import com.facebook.yoga.YogaConfigFactory;
|
||||
import com.facebook.yoga.YogaNodeFactory;
|
||||
|
||||
YogaConfig config = YogaConfigFactory.create();
|
||||
// Setup config...
|
||||
|
||||
YogaNode root = YogaNodeFactory.create(config);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
```ts
|
||||
import Yoga from 'yoga-layout';
|
||||
|
||||
const config = Yoga.Config.create();
|
||||
// Setup config...
|
||||
|
||||
const root = Yoga.Node.create(config);
|
||||
```
|
||||
|
||||
:::warning
|
||||
|
||||
Yoga configs are not freed automatically, and should be freed via `config.free()` when no longer needed.
|
||||
|
||||
A future revision of JavaScript bindings for Yoga may move to garbage collection to remove this requirement.
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Layout Conformance and Yoga Errata
|
||||
|
||||
Yoga has historically had several behaviors which are not standards compliant, and can lead to styles being laid out differently compared to a web browser. Fixing issues with Yoga's behavior may change the layout of existing applications written against Yoga's previous behaviors. Yoga can be configured with a set of **Errata** which control whether Yoga prefers standard compliance, or backwards compatibility. By default, Yoga will prefer standards compliance.
|
||||
|
||||
Errata may be configured granularity, as a set of bit flags, with several common presets available:
|
||||
1. `None` (default): Prefer standards compliance. Breaking layout fixes are enabled when updating Yoga.
|
||||
2. `Classic`: Operate as close as possible to Yoga 1.x.
|
||||
3. `All`: Enable the errata in `Classic`, alongside `StretchFlexBasis`, mapping to `UseLegacyStretchBehaviour` in Yoga 1.x, which was not enabled by default.
|
||||
|
||||
<Tabs groupId="language">
|
||||
|
||||
<TabItem value="cpp" label="C/C++">
|
||||
|
||||
```cpp
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
YGConfigRef config = YGConfigNew();
|
||||
YGConfigSetErrata(config, YGErrataClassic);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="java" label="Java">
|
||||
|
||||
```java
|
||||
import com.facebook.yoga.YogaConfigFactory;
|
||||
import com.facebook.yoga.YogaErrata;
|
||||
|
||||
YogaConfig config = YogaConfigFactory.create();
|
||||
config.setErrata(YogaErrata.CLASSIC);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
```ts
|
||||
import Yoga, {Errata} from 'yoga-layout';
|
||||
|
||||
const config = Yoga.Config.create();
|
||||
config.setErrata(Errata.Classic);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Point Scale Factor
|
||||
|
||||
Yoga represents positions on a floating-point grid of "points". This would normally lead to edges of a layout box ending up on a subpixel boundary when displayed by the underlying UI framework. This can create issues such as inconsistent rendering, or blurriness. To mitigate this, Yoga will by default round positions such that box edges are aligned to a physical "pixel grid".
|
||||
|
||||
Nodes may be configured with a `PointScaleFactor` to inform Yoga of the mapping between points to physical pixels (usually the "density" of the display). Pixel grid rounding may be disabled by setting `PointScaleFactor` to `0`.
|
||||
|
||||
| Before rounding | After rounding |
|
||||
| - | - |
|
||||
|  |  |
|
||||
|
||||
<Tabs groupId="language">
|
||||
|
||||
<TabItem value="cpp" label="C/C++">
|
||||
|
||||
```cpp
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
YGConfigRef config = YGConfigNew();
|
||||
YGConfigSetPointScaleFactor(config, 2.0f);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="java" label="Java">
|
||||
|
||||
```java
|
||||
import com.facebook.yoga.YogaConfigFactory;
|
||||
|
||||
YogaConfig config = YogaConfigFactory.create();
|
||||
config.setPointScaleFactor(2.0f);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
```ts
|
||||
import Yoga from 'yoga-layout';
|
||||
|
||||
const config = Yoga.Config.create();
|
||||
config.setPointScaleFactor(2);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
178
website/docs/getting-started/laying-out-a-tree.mdx
Normal file
@@ -0,0 +1,178 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Laying out a Yoga tree
|
||||
|
||||
Each box in Yoga is represented as a **Yoga Node**. These nodes form a tree which is used to store both input styles, and output layout results.
|
||||
|
||||
## Building a Yoga tree
|
||||
|
||||
Yoga nodes may be created, styled, and linked together. See [Styling](../styling/) for a more comprehensive reference of how to style a Yoga Node.
|
||||
|
||||
<Tabs groupId="language">
|
||||
|
||||
<TabItem value="cpp" label="C/C++">
|
||||
|
||||
```cpp
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
YGNodeRef root = YGNodeNew();
|
||||
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
|
||||
YGNodeStyleSetWidth(root, 100.0f);
|
||||
YGNodeStyleSetHeight(root, 100.0f);
|
||||
|
||||
YGNodeRef child0 = YGNodeNew();
|
||||
YGNodeStyleSetFlexGrow(child0, 1.0f);
|
||||
YGNodeStyleSetMargin(child0, YGEdgeRight, 10.0f);
|
||||
YGNodeInsertChild(root, child0, 0.0f);
|
||||
|
||||
YGNodeRef child1 = YGNodeNew();
|
||||
YGNodeStyleSetFlexGrow(child1, 1.0f);
|
||||
YGNodeInsertChild(root, child1, 1.0f);
|
||||
```
|
||||
|
||||
:::warning
|
||||
|
||||
Yoga Nodes are not freed automatically and should be discarded when no longer needed. Individual nodes may be freed by calling `YGNodeFree(node)`, or an entire Yoga tree may be freed by calling `YGNodeFreeRecursive(node)`.
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="java" label="Java">
|
||||
|
||||
```java
|
||||
import com.facebook.yoga.YogaEdge;
|
||||
import com.facebook.yoga.YogaFlexDirection;
|
||||
import com.facebook.yoga.YogaNode;
|
||||
import com.facebook.yoga.YogaNodeFactory;
|
||||
import com.facebook.yoga.YogaPositionType;
|
||||
|
||||
YogaNode root = YogaNodeFactory.create();
|
||||
root.setFlexDirection(YogaFlexDirection.ROW);
|
||||
root.setWidth(100.0f);
|
||||
root.setHeight(100.0f);
|
||||
|
||||
YogaNode child0 = YogaNodeFactory.create();
|
||||
child0.setFlexGrow(1.0f);
|
||||
child0.setMargin(YogaEdge.Right, 10.0f);
|
||||
root.addChildAt(child0, 0.0f);
|
||||
|
||||
YogaNode child1 = YogaNodeFactory.create();
|
||||
child1.setFlexGrow(1.0f);
|
||||
root.addChildAt(child1, 1.0f);
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
Java backed Yoga Nodes are garbage collected, and do not need to manually be freed.
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
```ts
|
||||
import Yoga, {Edge, FlexDirection, PositionType} from 'yoga-layout';
|
||||
|
||||
const root = Yoga.Node.create();
|
||||
root.setFlexDirection(FlexDirection.Row);
|
||||
root.setWidth(100);
|
||||
root.setHeight(100);
|
||||
|
||||
const child0 = Yoga.Node.create();
|
||||
child0.setFlexGrow(1);
|
||||
child0.setMargin(Edge.Right, 10);
|
||||
root.insertChild(child0, 0);
|
||||
|
||||
const child1 = Yoga.Node.create();
|
||||
child1.setFlexGrow(1);
|
||||
root.insertChild(child1, 1);
|
||||
```
|
||||
|
||||
:::warning
|
||||
|
||||
Yoga Nodes are not freed automatically and should be discarded when no longer needed. Individual nodes may be freed by calling `node.free()`, or an entire Yoga tree may be freed by calling `node.freeRecursive()`.
|
||||
|
||||
A future revision of JavaScript bindings for Yoga may move to garbage collection to remove this requirement.
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Laying out the tree
|
||||
|
||||
The full tree of Yoga nodes is laid out all at once. This layout may be constrained to a passed `availableWidth` and `availableHeight`, or may be allowed to expand infinitely in a given axis by passing Undefined.
|
||||
|
||||
<Tabs groupId="language">
|
||||
|
||||
<TabItem value="cpp" label="C/C++">
|
||||
|
||||
```cpp
|
||||
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="java" label="Java">
|
||||
|
||||
```java
|
||||
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
A tree of Java Yoga nodes may be laid out in RTL by setting the `direction` of the root node.
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
```ts
|
||||
root.calculateLayout(undefined, undefined, Direction.LTR);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Reading layout results
|
||||
|
||||
Layout results are now written to each Yoga node. This includes an offset relative to the border box of the node's parent, along with dimensions, and the resolved values for margin, border, and padding for each physical edge.
|
||||
|
||||
<Tabs groupId="language">
|
||||
|
||||
<TabItem value="cpp" label="C/C++">
|
||||
|
||||
```cpp
|
||||
float left = YGNodeLayoutGetLeft(child0);
|
||||
float height = YGNodeLayoutGetHeight(child0);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="java" label="Java">
|
||||
|
||||
```java
|
||||
float left = child0.getLayoutX();
|
||||
float height = child0.getLayoutHeight();
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
```ts
|
||||
const left = child0.getComputedLeft();
|
||||
const height = child0.getComputedHeight();
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
17
website/docs/img/config-contextual.svg
Normal file
After Width: | Height: | Size: 16 KiB |
17
website/docs/img/config-per-node.svg
Normal file
After Width: | Height: | Size: 15 KiB |
17
website/docs/img/config-uniform.svg
Normal file
After Width: | Height: | Size: 16 KiB |
17
website/docs/img/invalidation-clean-tree.svg
Normal file
After Width: | Height: | Size: 43 KiB |
17
website/docs/img/invalidation-dirtied-tree.svg
Normal file
After Width: | Height: | Size: 43 KiB |
17
website/docs/img/invalidation-new-layout-tree.svg
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
website/docs/img/pixel-grid-after.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
website/docs/img/pixel-grid-before.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
105
website/docs/img/wireframe-example.svg
Normal file
After Width: | Height: | Size: 68 KiB |
4
website/docs/styling/_category_.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"label": "Styling",
|
||||
"position": 4
|
||||
}
|
47
website/docs/styling/align-content.mdx
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Align Content
|
||||
|
||||
Align content defines the distribution of lines along the cross-axis. This only
|
||||
has effect when items are wrapped to multiple lines using [flex wrap](/docs/styling/flex-wrap).
|
||||
|
||||
**Flex start (default)**: Align wrapped lines to the start of the container's cross axis.
|
||||
|
||||
**Flex end**: Align wrapped lines to the end of the container's cross axis.
|
||||
|
||||
**Stretch**: Stretch wrapped lines to match the [height](/docs/styling/width-height) of the container's cross axis.
|
||||
|
||||
**Center**: Align wrapped lines in the center of the container's cross axis.
|
||||
|
||||
**Space between**: Evenly space wrapped lines across the container's main axis, distributing
|
||||
remaining space between the lines.
|
||||
|
||||
**Space around**: Evenly space wrapped lines across the container's main axis, distributing
|
||||
remaining space around the lines. Compared to space between using
|
||||
space around will result in space being distributed to the begining of
|
||||
the first lines and end of the last line.
|
||||
|
||||
**Space evenly**: Evenly space wrapped lines across the container's main axis, distributing
|
||||
remaining space around the lines. Compared to space around, space evenly will not
|
||||
double the gaps between children. The size of gaps between children and between
|
||||
the parent's edges and the first/last child will all be equal.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 250,
|
||||
padding: 10,
|
||||
alignContent: 'flex-start',
|
||||
flexWrap: 'wrap',
|
||||
}}>
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
48
website/docs/styling/align-items-self.mdx
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Align Items
|
||||
|
||||
Align items describes how to align children along the cross axis of their container.
|
||||
Align items is very similar to [justify content](/docs/styling/justify-content) but instead of
|
||||
applying to the main axis, align items applies to the cross axis.
|
||||
|
||||
**Stretch (default)**: Stretch children of a container to match the [height](/docs/styling/width-height) of the container's cross axis.
|
||||
|
||||
**Flex start**: Align children of a container to the start of the container's cross axis.
|
||||
|
||||
**Flex end**: Align children of a container to the end of the container's cross axis.
|
||||
|
||||
**Center**: Align children of a container in the center of the container's cross axis.
|
||||
|
||||
**Baseline**: Align children of a container along a common baseline. Individual children can be set to be the reference baseline for their parents.
|
||||
|
||||
# Align Self
|
||||
|
||||
Align self has the same options and effect as align items but instead of
|
||||
affecting the children within a container, you can apply this property to
|
||||
a single child to change its alignment within its parent. Align self
|
||||
overrides any option set by the parent with align items.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 250,
|
||||
padding: 10,
|
||||
alignItems: 'flex-start',
|
||||
}}>
|
||||
<Node
|
||||
style={{
|
||||
margin: 5,
|
||||
height: 50,
|
||||
width: 50,
|
||||
alignSelf: 'center',
|
||||
}}
|
||||
/>
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
27
website/docs/styling/aspect-ratio.mdx
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Aspect Ratio
|
||||
|
||||
The aspect ratio property in Yoga has the following properties:
|
||||
|
||||
- Accepts any floating point value > 0, the default is undefined.
|
||||
- Defined as the ratio between the [width](/docs/styling/width-height) and the [height](/docs/styling/width-height) of a node e.g. if a node has an aspect ratio of 2 then its [width](/docs/styling/width-height) is twice the size of its [height](/docs/styling/width-height).
|
||||
- Respects the [min](/docs/styling/min-max-width-height) and [max](/docs/styling/min-max-width-height) dimensions of an item.
|
||||
- Has higher priority than [flex grow](/docs/styling/flex-basis-grow-shrink)
|
||||
- If aspect ratio, [width](/docs/styling/width-height), and [height](/docs/styling/width-height) are set then the cross axis dimension is overridden.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
}}>
|
||||
<Node style={{margin: 5, height: 50, aspectRatio: 1.0}} />
|
||||
<Node style={{margin: 5, height: 50, aspectRatio: 1.5}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
25
website/docs/styling/display.mdx
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Display
|
||||
|
||||
Display controls which layout specification to follow.
|
||||
|
||||
**Flex (default)**: The CSS Flexible Box Model specification.
|
||||
|
||||
**None**: The node is removed from the layout tree and will not be visible.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
}}>
|
||||
<Node style={{margin: 5, height: 50, display: 'none'}} />
|
||||
<Node style={{margin: 5, height: 50, display: 'flex'}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
65
website/docs/styling/flex-basis-grow-shrink.mdx
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Flex Basis, Grow, and Shrink
|
||||
|
||||
**Flex basis**: Is an axis-independent way of providing the default size of an item
|
||||
along the main axis. Setting the flex basis of a child is similar to setting the [width](/docs/styling/width-height) of that
|
||||
child if its parent is a container with a row [flex direction](/docs/styling/flex-direction) or setting the [height](/docs/styling/width-height) of a child
|
||||
if its parent is a container with a column [flex direction](/docs/styling/flex-direction). The flex basis of an item is the
|
||||
default size of that item, the size of the item before any flex grow and flex shrink
|
||||
calculations are performed.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
}}>
|
||||
<Node style={{margin: 5, flexBasis: 50}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
||||
|
||||
**Flex grow**: Describes how any space within a container should be distributed
|
||||
among its children along the main axis. After laying out its children, a container will
|
||||
distribute any remaining space according to the flex grow values specified by its children.
|
||||
|
||||
Flex grow accepts any floating point value >= 0, with 0 being the default value.
|
||||
A container will distribute any remaining space among its children weighted by the child’s flex grow value.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
}}>
|
||||
<Node style={{margin: 5, flexGrow: 0.25}} />
|
||||
<Node style={{margin: 5, flexGrow: 0.75}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
||||
|
||||
**Flex shrink**: Describes how to shrink children along the main axis in the
|
||||
case that the total size of the children overflow the size of the container on the main axis.
|
||||
flex shrink is very similar to flex grow and can be thought of in the same way if
|
||||
any overflowing size is considered to be negative remaining space.
|
||||
These two properties also work well together by allowing children to grow and shrink as needed.
|
||||
|
||||
Flex shrink accepts any floating point value >= 0, with 1 being the default value.
|
||||
A container will shrink its children weighted by the child’s flex shrink value.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
}}>
|
||||
<Node style={{margin: 5, flexShrink: 5, height: 150}} />
|
||||
<Node style={{margin: 5, flexShrink: 10, height: 150}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
37
website/docs/styling/flex-direction.mdx
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Flex Direction
|
||||
|
||||
Flex direction controls the direction in which children of a node are laid out.
|
||||
This is also referred to as the main axis. The main axis is the direction in
|
||||
which children are laid out. The cross axis is the axis perpendicular to the
|
||||
main axis, or the axis which wrapping lines are laid out in.
|
||||
|
||||
**Column (default)**: Align children from top to bottom. If [wrapping](/docs/styling/flex-wrap) is enabled then
|
||||
the next line will start to the left first item on the top of the container.
|
||||
|
||||
**Row**: Align children from left to right. If [wrapping](/docs/styling/flex-wrap) is enabled then
|
||||
the next line will start under the first item on the left of the container.
|
||||
|
||||
**Row reverse**: Align children from right to left. If [wrapping](/docs/styling/flex-wrap) is enabled then
|
||||
the next line will start under the first item on the right of the container.
|
||||
|
||||
**Column reverse**: Align children from bottom to top. If [wrapping](/docs/styling/flex-wrap) is enabled then
|
||||
the next line will start to the left first item on the bottom of the container.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
flexDirection: 'column',
|
||||
}}>
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
33
website/docs/styling/flex-wrap.mdx
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Flex Wrap
|
||||
|
||||
The flex wrap property is set on containers and controls what happens when
|
||||
children overflow the size of the container along the main axis. By default
|
||||
children are forced into a single line (which can shrink nodes). When wrapping lines [align content](/docs/styling/align-content) can be used to specify how the
|
||||
lines are placed in the container.
|
||||
|
||||
**No wrap (default)**: No wrapping and children might shrink as a result.
|
||||
|
||||
**Wrap**: Nodes are wrapped into multiple lines along the main axis if needed.
|
||||
|
||||
**Wrap reverse**: Behaves the same as wrap but the order of the lines is reversed.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 250,
|
||||
padding: 10,
|
||||
flexWrap: 'wrap',
|
||||
}}>
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
49
website/docs/styling/gap.mdx
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
sidebar_position: 8
|
||||
---
|
||||
import Playground from '@site/src/components/Playground';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Gap
|
||||
|
||||
Gap will add spacing between the rows and columns of a flex container. You can
|
||||
specify if you want the gaps to be between only the rows, only the columns, or
|
||||
both. You can do this by passing in the corresponding gutter value to the API,
|
||||
for example
|
||||
|
||||
<Tabs groupId="language">
|
||||
<TabItem value="cpp" label="C/C++">
|
||||
```cpp
|
||||
YGNodeStyleSetGap(node, YGGutterRow, amount);
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="java" label="Java">
|
||||
```java
|
||||
node.setGap(YogaGutter.ROW, amount);
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="ts" label="Typescript">
|
||||
```typescript
|
||||
node.setGap(Gutter.Row, amount);
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 250,
|
||||
padding: 10,
|
||||
flexWrap: 'wrap',
|
||||
gap: 10,
|
||||
}}>
|
||||
<Node style={{height: 50, width: 50}} />
|
||||
<Node style={{height: 50, width: 50}} />
|
||||
<Node style={{height: 50, width: 50}} />
|
||||
<Node style={{height: 50, width: 50}} />
|
||||
<Node style={{height: 50, width: 50}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
47
website/docs/styling/index.md
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Styling
|
||||
|
||||
Each Yoga node has an associated style. Nodes may be styled using similar properties to CSS, with some caveats.
|
||||
|
||||
## Default styles
|
||||
|
||||
The default Yoga node style is similar to a box on web set to `display: flex`, with a few notable exceptions:
|
||||
|
||||
1. `flex-direction` defaults to `column` instead of `row`
|
||||
2. `align-content` defaults to `flex-start` instead of `stretch`
|
||||
3. `flex-shrink` defaults to `0` instead of `1`
|
||||
4. `position` defaults to `relative` instead of `static`
|
||||
|
||||
Yoga may be [configured](../getting-started/configuring-yoga.mdx) to align to the defaults on web for `flex-direction`, `align-content`, and `flex-shrink` by setting the `UseWebDefaults` flag.
|
||||
|
||||
:::warning
|
||||
|
||||
Because `UseWebDefaults` was established before the introduction of `position: 'static'`, it does not change the default `position`, in order to preserve compatibility.
|
||||
|
||||
:::
|
||||
|
||||
## Box Sizing
|
||||
|
||||
Yoga acts as if [`box-sizing: 'border-box'`](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing) is set. This means that specified dimensions for a box will include the space taken for padding and border.
|
||||
|
||||
## Edges
|
||||
|
||||
Margin, padding, position, and border, are set against an Edge, which may be:
|
||||
1. Relative to writing direction (start/end)
|
||||
2. A physical edge (top/right/left/bottom)
|
||||
3. A collection of edges (vertical/horizontal/all)
|
||||
|
||||
A style value may be set against multiple Edge values at once, with precedence given in the above order.
|
||||
|
||||
## Units
|
||||
|
||||
Yoga does not operate on CSS units like `px` or `em`. Yoga instead works on "points", representing an arbitrary, canonical absolute unit (usually mapped to display independent pixels), along with percentage. Other units should be absolutized before being given to Yoga.
|
||||
|
||||
## Non-standard properties
|
||||
|
||||
Yoga's `aspect-ratio` property was added before the same property was added to CSS, and may act subtlety different. These differences may be reconciled in a future version of Yoga.
|
||||
|
||||
Yoga's `flex` shorthand will act as `flex-grow` if positive, or `flex-shrink` if negative.
|
62
website/docs/styling/insets.mdx
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
sidebar_position: 8.5
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Insets
|
||||
|
||||
Insets refer to the position property that you can assign to an edge
|
||||
(not to be confused with [position type](/docs/styling/position)) using one of the following
|
||||
APIs:
|
||||
<Tabs groupId="language">
|
||||
<TabItem value="cpp" label="C/C++">
|
||||
```cpp
|
||||
YGNodeStyleSetPosition(node, edge, position);
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="java" label="Java">
|
||||
```java
|
||||
node.setPosition(edge, position);
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="ts" label="Typescript">
|
||||
```typescript
|
||||
node.setPosition(edge, position);
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
This property will offset the node in a specific way depending on
|
||||
what [position type](/docs/styling/position) the node has.
|
||||
|
||||
* If the node is static then insets have no effect.
|
||||
* If the node is relative then insets will move the node the designated amount
|
||||
from where the node would normally be in the container. Each inset property
|
||||
is relative to the node's corresponding physical edge. So `YGNodeStyleSetPosition(node, YGEdgeRight, 10.0f)` will offset the node
|
||||
so that the right edge is 10 units away from where the right edge would be originally.
|
||||
* If the node is aboslute then insets will move the node the designated amount away from
|
||||
the node's [containing block](/docs/advanced/containing-block). So `YGNodeStyleSetPosition(node, YGEdgeRight, 10.0f)`
|
||||
will offset the node so that the right edge is 10 units away from the [containing block's](/docs/advanced/containing-block)
|
||||
right edge.
|
||||
|
||||
In the event that a node has a fixed size and opposite insets are defined
|
||||
(e.g. a value assigned to the right edge and left edge) then the left and top edge will have priority.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
}}>
|
||||
<Node
|
||||
style={{
|
||||
height: 50,
|
||||
width: 50,
|
||||
top: 50,
|
||||
left: 50,
|
||||
}}
|
||||
/>
|
||||
</Node>
|
||||
</Layout>`} />
|
43
website/docs/styling/justify-content.mdx
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
sidebar_position: 9
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Justify Content
|
||||
|
||||
Justify content describes how to align children within the main axis of their container.
|
||||
For example, you can use this property to center a child horizontally within a container
|
||||
with [flex direction](/docs/styling/flex-direction) set to row or vertically within a container with [flex direction](/docs/styling/flex-direction)
|
||||
set to column.
|
||||
|
||||
**Flex start (default)**: Align children of a container to the start of the container's main axis.
|
||||
|
||||
**Flex end**: Align children of a container to the end of the container's main axis.
|
||||
|
||||
**Center**: Align children of a container in the center of the container's main axis.
|
||||
|
||||
**Space between**: Evenly space of children across the container's main axis, distributing
|
||||
remaining space between the children.
|
||||
|
||||
**Space around**: Evenly space of children across the container's main axis, distributing
|
||||
remaining space around the children. Compared to space between using
|
||||
space around will result in space being distributed to the beginning of
|
||||
the first child and end of the last child.
|
||||
|
||||
**Space evenly**: Evenly distributed within the alignment container along the main axis.
|
||||
The spacing between each pair of adjacent items, the main-start edge and the first item,
|
||||
and the main-end edge and the last item, are all exactly the same.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
justifyContent: 'flex-start',
|
||||
}}>
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
34
website/docs/styling/layout-direction.mdx
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
sidebar_position: 10
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Layout Direction
|
||||
|
||||
Layout direction specifies the direction in which children and text
|
||||
in a hierarchy should be laid out. Layout direction also effects what
|
||||
edge `start` and `end` refer to. By default Yoga lays out with left-to-right (LTR)
|
||||
layout direction. In this mode `start` refers to `left` and `end`
|
||||
refers to `right`. When localizing your apps for markets with right-to-left (RTL) languages
|
||||
you should customize this by either by passing a direction
|
||||
to the [CalculateLayout](/docs/getting-started/laying-out-a-tree) call or by setting the direction on the root node.
|
||||
|
||||
**LTR (default)**: Text and children and laid out from left to right. Styles applied
|
||||
the start of an element are applied on the left side.
|
||||
|
||||
**RTL**: Text and children and laid out from right to left. Styles applied the
|
||||
start of an element are applied on the right side.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
direction: 'ltr',
|
||||
}}>
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
<Node style={{margin: 5, height: 50, width: 50}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
41
website/docs/styling/margin-padding-border.mdx
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
sidebar_position: 11
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Margin, Padding, and Border
|
||||
|
||||
**Margin**: Affects the spacing around the outside of a node. A node with margin
|
||||
will offset itself from the bounds of its parent but also offset the
|
||||
location of any siblings. The margin of a node contributes to the total size
|
||||
of its parent if the parent is auto sized.
|
||||
|
||||
**Padding**: Affects the size of the node it is applied to. Padding in Yoga acts as if
|
||||
`box-sizing: border-box;` was set. That is padding will not add to the total size
|
||||
of an element if it has an explicit size set. For auto sized nodes padding will increase
|
||||
the size of the node as well as offset the location of any children.
|
||||
|
||||
**Border**: in Yoga acts exactly like padding and only exists as a seperate property so
|
||||
that higher level frameworks get a hint as to how thick to draw a border. Yoga however
|
||||
does not do any drawing so just uses this information during layout where border
|
||||
acts exactly like padding.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
}}>
|
||||
<Node
|
||||
style={{
|
||||
margin: 5,
|
||||
padding: 20,
|
||||
borderWidth: 20,
|
||||
height: 50,
|
||||
}}
|
||||
/>
|
||||
<Node style={{height: 50}} />
|
||||
</Node>
|
||||
</Layout>`} />
|
52
website/docs/styling/min-max-width-height.mdx
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
sidebar_position: 12
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Min/Max Width and Height
|
||||
|
||||
These properties set the maximum and minimum size constraints of a node.
|
||||
They have higher priority than all other properties and will always be respected.
|
||||
Constraints can be specified as either absolute pixel values or as percentages of their
|
||||
[containing block's](/docs/advanced/containing-block) size. By default all these constraints are `undefined`.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 250,
|
||||
padding: 10,
|
||||
}}>
|
||||
<Node style={{margin: 5, height: 25}} />
|
||||
<Node
|
||||
style={{
|
||||
margin: 5,
|
||||
height: 100,
|
||||
maxHeight: 25,
|
||||
}}
|
||||
/>
|
||||
<Node
|
||||
style={{
|
||||
margin: 5,
|
||||
height: 25,
|
||||
minHeight: 50,
|
||||
}}
|
||||
/>
|
||||
<Node
|
||||
style={{
|
||||
margin: 5,
|
||||
height: 25,
|
||||
maxWidth: 25,
|
||||
}}
|
||||
/>
|
||||
<Node
|
||||
style={{
|
||||
margin: 5,
|
||||
height: 25,
|
||||
width: 25,
|
||||
minWidth: 50,
|
||||
}}
|
||||
/>
|
||||
</Node>
|
||||
</Layout>`} />
|
37
website/docs/styling/position.mdx
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
sidebar_position: 11
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Position
|
||||
|
||||
**Relative (default)**: This node is laid out according to the specified flow of the flex container it is apart of.
|
||||
That is, it particpates in the flexbox algorithm and will take up space within the container, unlike absolute.
|
||||
[Insets](/docs/styling/insets) will offset the node from its normal position within its container.
|
||||
This node will always form a [containing block](/docs/advanced/containing-block).
|
||||
|
||||
**Absolute**: This node is removed from the specified flow of the flex container it is apart of.
|
||||
Absolute nodes do not take up space in its flex container and will not affect the position of
|
||||
its siblings. [Insets](/docs/styling/insets) will offset the node from its [containing block](/docs/advanced/containing-block).
|
||||
|
||||
**Static**: This node behaves like relative except it will ignore [insets](/docs/styling/insets) and will not
|
||||
form a [containing block](/docs/advanced/containing-block).
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
}}>
|
||||
<Node
|
||||
style={{
|
||||
margin: 5,
|
||||
height: 50,
|
||||
top: 20,
|
||||
position: 'relative',
|
||||
}}
|
||||
/>
|
||||
</Node>
|
||||
</Layout>`} />
|
37
website/docs/styling/width-height.mdx
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
sidebar_position: 14
|
||||
---
|
||||
|
||||
import Playground from '@site/src/components/Playground';
|
||||
|
||||
# Width and Height
|
||||
|
||||
The width property specifies the width of the node's border box (the collective size of the node's content, padding, and border).
|
||||
Similarly height property specifies the height of the node's border box.
|
||||
|
||||
Both width and height can take following values:
|
||||
|
||||
**Auto**: The default Value, Yoga calculates the width/height for the node based
|
||||
on its content, whether that is other children, text, or an image.
|
||||
|
||||
**Pixels**: Defines the width/height in absolute pixels. Depending on other properties set on
|
||||
the Yoga node this may or may not be the final dimension of the node.
|
||||
|
||||
**Percentage**: Defines the width or height in percentage of its [containing block's](/docs/advanced/containing-block) width or height respectively.
|
||||
|
||||
<Playground code={`<Layout config={{useWebDefaults: false}}>
|
||||
<Node
|
||||
style={{
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
}}>
|
||||
<Node
|
||||
style={{
|
||||
margin: 5,
|
||||
height: 50,
|
||||
width: 50,
|
||||
}}
|
||||
/>
|
||||
</Node>
|
||||
</Layout>`} />
|
148
website/docusaurus.config.js
Normal file
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
// @ts-check
|
||||
|
||||
import {themes as prismThemes} from 'prism-react-renderer';
|
||||
|
||||
/** @type {import('@docusaurus/types').Config} */
|
||||
export default {
|
||||
title: 'Yoga',
|
||||
tagline:
|
||||
'Build flexible layouts on any platform with a highly optimized open source layout engine designed with speed, size, and ease of use in mind.',
|
||||
favicon: 'img/favicon.png',
|
||||
|
||||
url: 'https:/yogalayout.dev',
|
||||
baseUrl: '/',
|
||||
|
||||
organizationName: 'facebook',
|
||||
projectName: 'yoga',
|
||||
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en'],
|
||||
},
|
||||
|
||||
presets: [
|
||||
[
|
||||
'classic',
|
||||
/** @type {import('@docusaurus/preset-classic').Options} */
|
||||
({
|
||||
docs: {
|
||||
sidebarPath: require.resolve('./sidebars.cjs'),
|
||||
editUrl: 'https://github.com/facebook/yoga/tree/main/website',
|
||||
},
|
||||
blog: {
|
||||
showReadingTime: true,
|
||||
editUrl: 'https://github.com/facebook/yoga/tree/main/website',
|
||||
},
|
||||
theme: {
|
||||
customCss: require.resolve('./src/css/custom.css'),
|
||||
},
|
||||
}),
|
||||
],
|
||||
],
|
||||
|
||||
themeConfig:
|
||||
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
||||
({
|
||||
navbar: {
|
||||
title: 'Yoga',
|
||||
logo: {
|
||||
alt: 'Yoga Logo',
|
||||
src: 'img/logo.svg',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'docSidebar',
|
||||
sidebarId: 'docsSidebar',
|
||||
position: 'left',
|
||||
label: 'Documentation',
|
||||
},
|
||||
{to: '/playground', label: 'Playground', position: 'left'},
|
||||
{to: '/blog', label: 'Blog', position: 'left'},
|
||||
{
|
||||
href: 'https://github.com/facebook/yoga',
|
||||
label: 'GitHub',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
style: 'dark',
|
||||
logo: {
|
||||
alt: 'Meta Open Source',
|
||||
src: 'img/meta_oss.svg',
|
||||
href: 'https://opensource.fb.com',
|
||||
width: 300,
|
||||
height: 64,
|
||||
},
|
||||
links: [
|
||||
{
|
||||
title: 'Docs',
|
||||
items: [
|
||||
{
|
||||
label: 'About Yoga',
|
||||
to: '/docs/about-yoga',
|
||||
},
|
||||
{
|
||||
label: 'Getting Started',
|
||||
to: '/docs/getting-started/laying-out-a-tree',
|
||||
},
|
||||
{
|
||||
label: 'Advanced',
|
||||
to: '/docs/advanced/incremental-layout',
|
||||
},
|
||||
{
|
||||
label: 'Styling',
|
||||
to: '/docs/styling',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Community',
|
||||
items: [
|
||||
{
|
||||
label: 'Stack Overflow',
|
||||
href: 'https://stackoverflow.com/questions/tagged/yoga',
|
||||
},
|
||||
{
|
||||
label: 'Twitter',
|
||||
href: 'https://twitter.com/yogalayout',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'More',
|
||||
items: [
|
||||
{
|
||||
label: 'Blog',
|
||||
to: '/blog',
|
||||
},
|
||||
{
|
||||
label: 'GitHub',
|
||||
href: 'https://github.com/facebook/yoga',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Meta Platforms, Inc.`,
|
||||
},
|
||||
prism: {
|
||||
theme: prismThemes.github,
|
||||
darkTheme: prismThemes.oneDark,
|
||||
additionalLanguages: ['gradle', 'java', 'json', 'json5', 'ruby'],
|
||||
},
|
||||
colorMode: {
|
||||
defaultMode: 'dark',
|
||||
respectPrefersColorScheme: true,
|
||||
},
|
||||
}),
|
||||
};
|
43
website/package.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "website-next",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "yarn workspace yoga-layout build && docusaurus start",
|
||||
"build": "yarn workspace yoga-layout build && docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve",
|
||||
"write-translations": "docusaurus write-translations",
|
||||
"write-heading-ids": "docusaurus write-heading-ids",
|
||||
"typecheck": "tsc",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.0.1",
|
||||
"@docusaurus/preset-classic": "3.0.1",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"lz-string": "^1.5.0",
|
||||
"nullthrows": "^1.1.1",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"react-live": "^4.1.5",
|
||||
"yoga-layout": "0.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.0.0",
|
||||
"@docusaurus/tsconfig": "3.0.0",
|
||||
"@docusaurus/types": "3.0.0",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0"
|
||||
},
|
||||
"browserslist": "> 0.5%, last 2 versions, Firefox ESR, not dead",
|
||||
"engines": {
|
||||
"node": ">=16.14"
|
||||
}
|
||||
}
|
27
website/sidebars.cjs
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creating a sidebar enables you to:
|
||||
- create an ordered group of docs
|
||||
- render a sidebar for each doc of that group
|
||||
- provide next/previous navigation
|
||||
|
||||
The sidebars can be generated from the filesystem, or explicitly defined here.
|
||||
|
||||
Create as many sidebars as you want.
|
||||
*/
|
||||
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
|
||||
const sidebars = {
|
||||
// By default, Docusaurus generates a sidebar from the docs folder structure
|
||||
docsSidebar: [{type: 'autogenerated', dirName: '.'}],
|
||||
};
|
||||
|
||||
module.exports = sidebars;
|
77
website/src/components/EditorToolbar.module.css
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
column-gap: 8px;
|
||||
}
|
||||
|
||||
.toolbar button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: var(--prism-background-color);
|
||||
color: var(--prism-color);
|
||||
border: 1px solid var(--ifm-color-emphasis-300);
|
||||
border-radius: var(--ifm-global-radius);
|
||||
padding: 0.4rem;
|
||||
line-height: 0;
|
||||
transition: opacity var(--ifm-transition-fast) ease-in-out;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.toolbar button:focus-visible,
|
||||
.toolbar button:hover {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.iconSwitcher {
|
||||
position: relative;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.actionIcon,
|
||||
.successIcon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
fill: currentColor;
|
||||
opacity: inherit;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
transition: all var(--ifm-transition-fast) ease;
|
||||
}
|
||||
|
||||
.successIcon {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) scale(0.33);
|
||||
opacity: 0;
|
||||
color: #00d600;
|
||||
}
|
||||
|
||||
.clicked .actionIcon {
|
||||
transform: scale(0.33);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.clicked .successIcon {
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
opacity: 1;
|
||||
transition-delay: 0.075s;
|
||||
}
|
||||
|
||||
@media (max-width: 996px) {
|
||||
.toolbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
80
website/src/components/EditorToolbar.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {useCallback, useEffect, useRef, useState} from 'react';
|
||||
import clsx from 'clsx';
|
||||
import lzString from 'lz-string';
|
||||
|
||||
import LinkIcon from '../../static/img/link.svg';
|
||||
import SuccessIcon from '@theme/Icon/Success';
|
||||
|
||||
import styles from './EditorToolbar.module.css';
|
||||
|
||||
export type Props = Readonly<{
|
||||
code: string;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}>;
|
||||
|
||||
export default function EditorToolbar({
|
||||
code,
|
||||
className,
|
||||
style,
|
||||
}: Props): JSX.Element {
|
||||
const handleShare = useCallback(() => {
|
||||
navigator.clipboard.writeText(
|
||||
window.location.origin +
|
||||
`/playground?code=${lzString.compressToEncodedURIComponent(code)}`,
|
||||
);
|
||||
}, [code]);
|
||||
|
||||
return (
|
||||
<div className={clsx(styles.toolbar, className)} style={style}>
|
||||
<ToolbarButton Icon={LinkIcon} label="Share" onClick={handleShare} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type ToolbarButtonProps = Readonly<{
|
||||
onClick: () => void;
|
||||
Icon: React.ComponentType<React.SVGProps<SVGSVGElement>>;
|
||||
label?: string;
|
||||
}>;
|
||||
|
||||
function ToolbarButton({
|
||||
onClick,
|
||||
Icon,
|
||||
label,
|
||||
}: ToolbarButtonProps): JSX.Element {
|
||||
const [isSuccess, setIsSuccess] = useState(false);
|
||||
const copyTimeout = useRef<number | undefined>(undefined);
|
||||
|
||||
useEffect(() => () => window.clearTimeout(copyTimeout.current), []);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
onClick();
|
||||
setIsSuccess(true);
|
||||
copyTimeout.current = window.setTimeout(() => {
|
||||
setIsSuccess(false);
|
||||
}, 1000);
|
||||
}, [onClick]);
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={clsx('clean-btn', isSuccess && styles.clicked)}
|
||||
onClick={handleClick}
|
||||
aria-label={label}>
|
||||
<span className={styles.iconSwitcher} aria-hidden="true">
|
||||
<Icon className={styles.actionIcon} />
|
||||
<SuccessIcon className={styles.successIcon} />
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
}
|
426
website/src/components/FlexStyle.ts
Normal file
@@ -0,0 +1,426 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {
|
||||
Align,
|
||||
Direction,
|
||||
Display,
|
||||
Edge,
|
||||
FlexDirection,
|
||||
Gutter,
|
||||
Justify,
|
||||
Overflow,
|
||||
PositionType,
|
||||
Wrap,
|
||||
Node as YogaNode,
|
||||
} from 'yoga-layout';
|
||||
|
||||
export type AlignContent =
|
||||
| 'flex-start'
|
||||
| 'flex-end'
|
||||
| 'center'
|
||||
| 'stretch'
|
||||
| 'space-between'
|
||||
| 'space-around'
|
||||
| 'space-evenly';
|
||||
|
||||
export type AlignItems =
|
||||
| 'flex-start'
|
||||
| 'flex-end'
|
||||
| 'center'
|
||||
| 'stretch'
|
||||
| 'baseline';
|
||||
|
||||
export type JustifyContent =
|
||||
| 'flex-start'
|
||||
| 'flex-end'
|
||||
| 'center'
|
||||
| 'space-between'
|
||||
| 'space-around'
|
||||
| 'space-evenly';
|
||||
|
||||
export type FlexStyle = {
|
||||
alignContent?: AlignContent;
|
||||
alignItems?: AlignItems;
|
||||
alignSelf?: AlignItems;
|
||||
aspectRatio?: number;
|
||||
borderBottomWidth?: number;
|
||||
borderEndWidth?: number;
|
||||
borderLeftWidth?: number;
|
||||
borderRightWidth?: number;
|
||||
borderStartWidth?: number;
|
||||
borderTopWidth?: number;
|
||||
borderWidth?: number;
|
||||
borderInlineWidth?: number;
|
||||
borderBlockWidth?: number;
|
||||
bottom?: number | `${number}%`;
|
||||
direction?: 'ltr' | 'rtl';
|
||||
display?: 'none' | 'flex';
|
||||
end?: number | `${number}%`;
|
||||
flex?: number;
|
||||
flexBasis?: number | 'auto' | `${number}%`;
|
||||
flexDirection?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
|
||||
rowGap?: number;
|
||||
gap?: number;
|
||||
columnGap?: number;
|
||||
flexGrow?: number;
|
||||
flexShrink?: number;
|
||||
flexWrap?: 'wrap' | 'nowrap' | 'wrap-reverse';
|
||||
height?: number | 'auto' | `${number}%`;
|
||||
justifyContent?: JustifyContent;
|
||||
left?: number | `${number}%`;
|
||||
margin?: number | 'auto' | `${number}%`;
|
||||
marginBottom?: number | 'auto' | `${number}%`;
|
||||
marginEnd?: number | 'auto' | `${number}%`;
|
||||
marginLeft?: number | 'auto' | `${number}%`;
|
||||
marginRight?: number | 'auto' | `${number}%`;
|
||||
marginStart?: number | 'auto' | `${number}%`;
|
||||
marginTop?: number | 'auto' | `${number}%`;
|
||||
marginInline?: number | 'auto' | `${number}%`;
|
||||
marginBlock?: number | 'auto' | `${number}%`;
|
||||
maxHeight?: number | `${number}%`;
|
||||
maxWidth?: number | `${number}%`;
|
||||
minHeight?: number | `${number}%`;
|
||||
minWidth?: number | `${number}%`;
|
||||
overflow?: 'visible' | 'hidden' | 'scroll';
|
||||
padding?: number | `${number}%`;
|
||||
paddingBottom?: number | `${number}%`;
|
||||
paddingEnd?: number | `${number}%`;
|
||||
paddingLeft?: number | `${number}%`;
|
||||
paddingRight?: number | `${number}%`;
|
||||
paddingStart?: number | `${number}%`;
|
||||
paddingTop?: number | `${number}%`;
|
||||
paddingInline?: number | `${number}%`;
|
||||
paddingBlock?: number | `${number}%`;
|
||||
position?: 'absolute' | 'relative' | 'static';
|
||||
right?: number | `${number}%`;
|
||||
start?: number | `${number}%`;
|
||||
top?: number | `${number}%`;
|
||||
insetInline?: number | `${number}%`;
|
||||
insetBlock?: number | `${number}%`;
|
||||
inset?: number | `${number}%`;
|
||||
width?: number | 'auto' | `${number}%`;
|
||||
};
|
||||
|
||||
export function applyStyle(node: YogaNode, style: FlexStyle = {}): void {
|
||||
for (const key of Object.keys(style)) {
|
||||
try {
|
||||
switch (key) {
|
||||
case 'alignContent':
|
||||
node.setAlignContent(alignContent(style.alignContent));
|
||||
break;
|
||||
case 'alignItems':
|
||||
node.setAlignItems(alignItems(style.alignItems));
|
||||
break;
|
||||
case 'alignSelf':
|
||||
node.setAlignSelf(alignItems(style.alignSelf));
|
||||
break;
|
||||
case 'aspectRatio':
|
||||
node.setAspectRatio(style.aspectRatio);
|
||||
break;
|
||||
case 'borderBottomWidth':
|
||||
node.setBorder(Edge.Bottom, style.borderBottomWidth);
|
||||
break;
|
||||
case 'borderEndWidth':
|
||||
node.setBorder(Edge.End, style.borderEndWidth);
|
||||
break;
|
||||
case 'borderLeftWidth':
|
||||
node.setBorder(Edge.Left, style.borderLeftWidth);
|
||||
break;
|
||||
case 'borderRightWidth':
|
||||
node.setBorder(Edge.Right, style.borderRightWidth);
|
||||
break;
|
||||
case 'borderStartWidth':
|
||||
node.setBorder(Edge.Start, style.borderStartWidth);
|
||||
break;
|
||||
case 'borderTopWidth':
|
||||
node.setBorder(Edge.Top, style.borderTopWidth);
|
||||
break;
|
||||
case 'borderWidth':
|
||||
node.setBorder(Edge.All, style.borderWidth);
|
||||
break;
|
||||
case 'borderInlineWidth':
|
||||
node.setBorder(Edge.Horizontal, style.borderInlineWidth);
|
||||
break;
|
||||
case 'borderBlockWidth':
|
||||
node.setBorder(Edge.Vertical, style.borderBlockWidth);
|
||||
break;
|
||||
case 'bottom':
|
||||
node.setPosition(Edge.Bottom, style.bottom);
|
||||
break;
|
||||
case 'direction':
|
||||
node.setDirection(direction(style.direction));
|
||||
break;
|
||||
case 'display':
|
||||
node.setDisplay(display(style.display));
|
||||
break;
|
||||
case 'end':
|
||||
node.setPosition(Edge.End, style.end);
|
||||
break;
|
||||
case 'flex':
|
||||
node.setFlex(style.flex);
|
||||
break;
|
||||
case 'flexBasis':
|
||||
node.setFlexBasis(style.flexBasis);
|
||||
break;
|
||||
case 'flexDirection':
|
||||
node.setFlexDirection(flexDirection(style.flexDirection));
|
||||
break;
|
||||
case 'rowGap':
|
||||
node.setGap(Gutter.Row, style.rowGap);
|
||||
break;
|
||||
case 'gap':
|
||||
node.setGap(Gutter.All, style.gap);
|
||||
break;
|
||||
case 'columnGap':
|
||||
node.setGap(Gutter.Column, style.columnGap);
|
||||
break;
|
||||
case 'flexGrow':
|
||||
node.setFlexGrow(style.flexGrow);
|
||||
break;
|
||||
case 'flexShrink':
|
||||
node.setFlexShrink(style.flexShrink);
|
||||
break;
|
||||
case 'flexWrap':
|
||||
node.setFlexWrap(flexWrap(style.flexWrap));
|
||||
break;
|
||||
case 'height':
|
||||
node.setHeight(style.height);
|
||||
break;
|
||||
case 'justifyContent':
|
||||
node.setJustifyContent(justifyContent(style.justifyContent));
|
||||
break;
|
||||
case 'left':
|
||||
node.setPosition(Edge.Left, style.left);
|
||||
break;
|
||||
case 'margin':
|
||||
node.setMargin(Edge.All, style.margin);
|
||||
break;
|
||||
case 'marginBottom':
|
||||
node.setMargin(Edge.Bottom, style.marginBottom);
|
||||
break;
|
||||
case 'marginEnd':
|
||||
node.setMargin(Edge.End, style.marginEnd);
|
||||
break;
|
||||
case 'marginLeft':
|
||||
node.setMargin(Edge.Left, style.marginLeft);
|
||||
break;
|
||||
case 'marginRight':
|
||||
node.setMargin(Edge.Right, style.marginRight);
|
||||
break;
|
||||
case 'marginStart':
|
||||
node.setMargin(Edge.Start, style.marginStart);
|
||||
break;
|
||||
case 'marginTop':
|
||||
node.setMargin(Edge.Top, style.marginTop);
|
||||
break;
|
||||
case 'marginInline':
|
||||
node.setMargin(Edge.Horizontal, style.marginInline);
|
||||
break;
|
||||
case 'marginBlock':
|
||||
node.setMargin(Edge.Vertical, style.marginBlock);
|
||||
break;
|
||||
case 'maxHeight':
|
||||
node.setMaxHeight(style.maxHeight);
|
||||
break;
|
||||
case 'maxWidth':
|
||||
node.setMaxWidth(style.maxWidth);
|
||||
break;
|
||||
case 'minHeight':
|
||||
node.setMinHeight(style.minHeight);
|
||||
break;
|
||||
case 'minWidth':
|
||||
node.setMinWidth(style.minWidth);
|
||||
break;
|
||||
case 'overflow':
|
||||
node.setOverflow(overflow(style.overflow));
|
||||
break;
|
||||
case 'padding':
|
||||
node.setPadding(Edge.All, style.padding);
|
||||
break;
|
||||
case 'paddingBottom':
|
||||
node.setPadding(Edge.Bottom, style.paddingBottom);
|
||||
break;
|
||||
case 'paddingEnd':
|
||||
node.setPadding(Edge.End, style.paddingEnd);
|
||||
break;
|
||||
case 'paddingLeft':
|
||||
node.setPadding(Edge.Left, style.paddingLeft);
|
||||
break;
|
||||
case 'paddingRight':
|
||||
node.setPadding(Edge.Right, style.paddingRight);
|
||||
break;
|
||||
case 'paddingStart':
|
||||
node.setPadding(Edge.Start, style.paddingStart);
|
||||
break;
|
||||
case 'paddingTop':
|
||||
node.setPadding(Edge.Top, style.paddingTop);
|
||||
break;
|
||||
case 'paddingInline':
|
||||
node.setPadding(Edge.Horizontal, style.paddingInline);
|
||||
break;
|
||||
case 'paddingBlock':
|
||||
node.setPadding(Edge.Vertical, style.paddingBlock);
|
||||
break;
|
||||
case 'position':
|
||||
node.setPositionType(position(style.position));
|
||||
break;
|
||||
case 'right':
|
||||
node.setPosition(Edge.Right, style.right);
|
||||
break;
|
||||
case 'start':
|
||||
node.setPosition(Edge.Start, style.start);
|
||||
break;
|
||||
case 'top':
|
||||
node.setPosition(Edge.Top, style.top);
|
||||
break;
|
||||
case 'insetInline':
|
||||
node.setPosition(Edge.Horizontal, style.insetInline);
|
||||
break;
|
||||
case 'insetBlock':
|
||||
node.setPosition(Edge.Vertical, style.insetBlock);
|
||||
break;
|
||||
case 'inset':
|
||||
node.setPosition(Edge.All, style.inset);
|
||||
break;
|
||||
case 'width':
|
||||
node.setWidth(style.width);
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
// Fail gracefully
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function alignContent(str?: AlignContent): Align {
|
||||
switch (str) {
|
||||
case 'flex-start':
|
||||
return Align.FlexStart;
|
||||
case 'flex-end':
|
||||
return Align.FlexEnd;
|
||||
case 'center':
|
||||
return Align.Center;
|
||||
case 'stretch':
|
||||
return Align.Stretch;
|
||||
case 'space-between':
|
||||
return Align.SpaceBetween;
|
||||
case 'space-around':
|
||||
return Align.SpaceAround;
|
||||
case 'space-evenly':
|
||||
return Align.SpaceEvenly;
|
||||
}
|
||||
throw new Error(`"${str}" is not a valid value for alignContent`);
|
||||
}
|
||||
|
||||
function alignItems(str?: AlignItems): Align {
|
||||
switch (str) {
|
||||
case 'flex-start':
|
||||
return Align.FlexStart;
|
||||
case 'flex-end':
|
||||
return Align.FlexEnd;
|
||||
case 'center':
|
||||
return Align.Center;
|
||||
case 'stretch':
|
||||
return Align.Stretch;
|
||||
case 'baseline':
|
||||
return Align.Baseline;
|
||||
}
|
||||
throw new Error(`"${str}" is not a valid value for alignItems`);
|
||||
}
|
||||
|
||||
function direction(str?: 'ltr' | 'rtl'): Direction {
|
||||
switch (str) {
|
||||
case 'ltr':
|
||||
return Direction.LTR;
|
||||
case 'rtl':
|
||||
return Direction.RTL;
|
||||
}
|
||||
throw new Error(`"${str}" is not a valid value for direction`);
|
||||
}
|
||||
|
||||
function display(str?: 'none' | 'flex'): Display {
|
||||
switch (str) {
|
||||
case 'none':
|
||||
return Display.None;
|
||||
case 'flex':
|
||||
return Display.Flex;
|
||||
}
|
||||
throw new Error(`"${str}" is not a valid value for display`);
|
||||
}
|
||||
|
||||
function flexDirection(
|
||||
str?: 'row' | 'column' | 'row-reverse' | 'column-reverse',
|
||||
): FlexDirection {
|
||||
switch (str) {
|
||||
case 'row':
|
||||
return FlexDirection.Row;
|
||||
case 'column':
|
||||
return FlexDirection.Column;
|
||||
case 'row-reverse':
|
||||
return FlexDirection.RowReverse;
|
||||
case 'column-reverse':
|
||||
return FlexDirection.ColumnReverse;
|
||||
}
|
||||
throw new Error(`"${str}" is not a valid value for flexDirection`);
|
||||
}
|
||||
|
||||
function flexWrap(str?: 'wrap' | 'nowrap' | 'wrap-reverse'): Wrap {
|
||||
switch (str) {
|
||||
case 'wrap':
|
||||
return Wrap.Wrap;
|
||||
case 'nowrap':
|
||||
return Wrap.NoWrap;
|
||||
case 'wrap-reverse':
|
||||
return Wrap.WrapReverse;
|
||||
}
|
||||
throw new Error(`"${str}" is not a valid value for flexWrap`);
|
||||
}
|
||||
|
||||
function justifyContent(str?: JustifyContent): Justify {
|
||||
switch (str) {
|
||||
case 'flex-start':
|
||||
return Justify.FlexStart;
|
||||
case 'flex-end':
|
||||
return Justify.FlexEnd;
|
||||
case 'center':
|
||||
return Justify.Center;
|
||||
case 'space-between':
|
||||
return Justify.SpaceBetween;
|
||||
case 'space-around':
|
||||
return Justify.SpaceAround;
|
||||
case 'space-evenly':
|
||||
return Justify.SpaceEvenly;
|
||||
}
|
||||
throw new Error(`"${str}" is not a valid value for justifyContent`);
|
||||
}
|
||||
|
||||
function overflow(str?: 'visible' | 'hidden' | 'scroll'): Overflow {
|
||||
switch (str) {
|
||||
case 'visible':
|
||||
return Overflow.Visible;
|
||||
case 'hidden':
|
||||
return Overflow.Hidden;
|
||||
case 'scroll':
|
||||
return Overflow.Scroll;
|
||||
}
|
||||
throw new Error(`"${str}" is not a valid value for overflow`);
|
||||
}
|
||||
|
||||
function position(str?: 'absolute' | 'relative' | 'static'): PositionType {
|
||||
switch (str) {
|
||||
case 'absolute':
|
||||
return PositionType.Absolute;
|
||||
case 'relative':
|
||||
return PositionType.Relative;
|
||||
case 'static':
|
||||
return PositionType.Static;
|
||||
}
|
||||
throw new Error(`"${str}" is not a valid value for position`);
|
||||
}
|
68
website/src/components/LayoutBox.module.css
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
html[data-theme='light'] {
|
||||
--yg-color-node-depth-0: var(--ifm-color-gray-0);
|
||||
--yg-color-node-depth-1: var(--ifm-color-gray-200);
|
||||
--yg-color-node-depth-2: var(--ifm-color-gray-400);
|
||||
--yg-color-node-depth-3: var(--ifm-color-gray-600);
|
||||
--yg-color-node-depth-4: var(--ifm-color-gray-800);
|
||||
|
||||
--yg-border-node-depth-0: 1px solid var(--ifm-color-gray-200);
|
||||
--yg-border-node-depth-1: 1px solid var(--ifm-color-gray-600);
|
||||
--yg-border-node-depth-2: 1px solid var(--ifm-color-gray-700);
|
||||
--yg-border-node-depth-3: 1px solid var(--ifm-color-gray-800);
|
||||
--yg-border-node-depth-4: 1px solid var(--ifm-color-gray-900);
|
||||
}
|
||||
|
||||
html[data-theme='dark'] {
|
||||
--yg-color-node-depth-0: var(--ifm-color-gray-900);
|
||||
--yg-color-node-depth-1: var(--ifm-color-gray-800);
|
||||
--yg-color-node-depth-2: var(--ifm-color-gray-700);
|
||||
--yg-color-node-depth-3: var(--ifm-color-gray-600);
|
||||
--yg-color-node-depth-4: var(--ifm-color-gray-500);
|
||||
|
||||
--yg-border-node-depth-0: 1px solid var(--ifm-color-gray-800);
|
||||
--yg-border-node-depth-1: 1px solid var(--ifm-color-gray-700);
|
||||
--yg-border-node-depth-2: 1px solid var(--ifm-color-gray-600);
|
||||
--yg-border-node-depth-3: 1px solid var(--ifm-color-gray-500);
|
||||
--yg-border-node-depth-4: 1px solid var(--ifm-color-gray-400);
|
||||
}
|
||||
|
||||
.layoutBox {
|
||||
box-sizing: border-box;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.zeroDim {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.depthZero {
|
||||
background: var(--yg-color-node-depth-0);
|
||||
border: var(--yg-border-node-depth-0);
|
||||
}
|
||||
|
||||
.depthOne {
|
||||
background-color: var(--yg-color-node-depth-1);
|
||||
border: var(--yg-border-node-depth-1);
|
||||
}
|
||||
|
||||
.depthTwo {
|
||||
background-color: var(--yg-color-node-depth-2);
|
||||
border: var(--yg-border-node-depth-2);
|
||||
}
|
||||
|
||||
.depthThree {
|
||||
background-color: var(--yg-color-node-depth-3);
|
||||
border: var(--yg-border-node-depth-3);
|
||||
}
|
||||
|
||||
.depthFour {
|
||||
background-color: var(--yg-color-node-depth-4);
|
||||
border: var(--yg-border-node-depth-4);
|
||||
}
|
56
website/src/components/LayoutBox.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import styles from './LayoutBox.module.css';
|
||||
import clsx from 'clsx';
|
||||
|
||||
export type LayoutMetrics = {
|
||||
top: number;
|
||||
left: number;
|
||||
width: number;
|
||||
height: number;
|
||||
overflow?: 'visible' | 'hidden' | 'scroll';
|
||||
children?: LayoutMetrics[];
|
||||
};
|
||||
|
||||
export type Props = Readonly<{
|
||||
metrics: LayoutMetrics;
|
||||
className?: string;
|
||||
depth: number;
|
||||
}>;
|
||||
|
||||
export default function LayoutBox({metrics, depth, className}: Props) {
|
||||
const {children, ...style} = metrics;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
styles.layoutBox,
|
||||
(metrics.height === 0 || metrics.width === 0) && styles.zeroDim,
|
||||
depth % 5 == 0 && styles.depthZero,
|
||||
depth % 5 == 1 && styles.depthOne,
|
||||
depth % 5 == 2 && styles.depthTwo,
|
||||
depth % 5 == 3 && styles.depthThree,
|
||||
depth % 5 == 4 && styles.depthFour,
|
||||
className,
|
||||
)}
|
||||
style={{
|
||||
top: style.top,
|
||||
left: style.left,
|
||||
width: style.width,
|
||||
height: style.height,
|
||||
overflow: style.overflow,
|
||||
position: depth === 0 ? 'relative' : 'absolute',
|
||||
}}>
|
||||
{children?.map((child, i) => (
|
||||
<LayoutBox key={i} metrics={child} depth={depth + 1} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
130
website/src/components/Playground.module.css
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
html[data-theme='light'] {
|
||||
--yg-color-preview-background: var(--ifm-color-primary-lighter);
|
||||
--yg-color-editor-border: var(--ifm-color-gray-400);
|
||||
--yg-color-editor-fallback-bg: rgb(246, 248, 250);
|
||||
--yg-color-editor-fallback-text: rgb(0, 0, 159);
|
||||
}
|
||||
|
||||
html[data-theme='dark'] {
|
||||
--yg-color-preview-background: var(--ifm-color-primary-dark);
|
||||
--yg-color-editor-border: var(--ifm-color-gray-800);
|
||||
--yg-color-editor-fallback-bg: rgb(40, 44, 52);
|
||||
--yg-color-editor-fallback-text: rgb(209, 154, 102);
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
min-width: 600px;
|
||||
padding-block: 16px;
|
||||
}
|
||||
|
||||
.playgroundRow {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
column-gap: 16px;
|
||||
}
|
||||
|
||||
.editorColumn {
|
||||
flex: 8;
|
||||
min-width: 0;
|
||||
overflow-y: auto;
|
||||
border: 1px solid var(--yg-color-editor-border);
|
||||
border-radius: var(--ifm-pre-border-radius);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.editorScroll {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.editorToolbar {
|
||||
position: absolute;
|
||||
top: var(--ifm-pre-padding);
|
||||
right: var(--ifm-pre-padding);
|
||||
}
|
||||
|
||||
.playgroundEditor {
|
||||
font: var(--ifm-code-font-size) / var(--ifm-pre-line-height)
|
||||
var(--ifm-font-family-monospace) !important;
|
||||
direction: ltr;
|
||||
height: calc(var(--yg-playground-height) - 32px);
|
||||
}
|
||||
|
||||
.playgroundEditor :global(.prism-code) {
|
||||
box-shadow: var(--ifm-global-shadow-lw);
|
||||
height: calc(var(--yg-playground-height) - 32px);
|
||||
min-height: 300px;
|
||||
border-radius: 0;
|
||||
padding: var(--ifm-pre-padding) !important;
|
||||
}
|
||||
|
||||
.liveEditorFallback {
|
||||
background-color: var(--yg-color-editor-fallback-bg);
|
||||
color: var(--yg-color-editor-fallback-text);
|
||||
}
|
||||
|
||||
.previewColumn {
|
||||
display: flex;
|
||||
flex: 5;
|
||||
height: calc(var(--yg-playground-height) - 32px);
|
||||
min-height: 300px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--yg-color-preview-background);
|
||||
overflow: hidden;
|
||||
border-radius: var(--ifm-pre-border-radius);
|
||||
align-self: stretch;
|
||||
box-shadow: var(--ifm-global-shadow-lw);
|
||||
}
|
||||
|
||||
.livePreviewWrapper {
|
||||
box-shadow: var(--ifm-global-shadow-md);
|
||||
}
|
||||
|
||||
.liveError {
|
||||
align-self: flex-start;
|
||||
font-size: 12px;
|
||||
box-shadow: var(--ifm-global-shadow-lw);
|
||||
background-color:var(--ifm-color-danger-darker);
|
||||
color: white;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 996px) {
|
||||
.wrapper {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.playgroundEditor {
|
||||
height: unset;
|
||||
}
|
||||
|
||||
.playgroundEditor :global(.prism-code) {
|
||||
height: unset;
|
||||
min-height: 10em;
|
||||
}
|
||||
|
||||
.playgroundRow {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.editorColumn {
|
||||
padding: 0;
|
||||
margin-bottom: 10px;
|
||||
flex: unset;
|
||||
}
|
||||
|
||||
.previewColumn {
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
flex: unset;
|
||||
}
|
||||
}
|
187
website/src/components/Playground.tsx
Normal file
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {
|
||||
CSSProperties,
|
||||
Suspense,
|
||||
lazy,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import {usePrismTheme} from '@docusaurus/theme-common';
|
||||
import clsx from 'clsx';
|
||||
import {LiveProvider, LiveEditor, LivePreview, LiveError} from 'react-live';
|
||||
import EditorToolbar from './EditorToolbar';
|
||||
|
||||
import type {FlexStyle} from './FlexStyle';
|
||||
import type {StyleNode} from './YogaViewer';
|
||||
|
||||
import styles from './Playground.module.css';
|
||||
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||
|
||||
export type Props = Readonly<{
|
||||
code: string;
|
||||
height?: CSSProperties['height'];
|
||||
autoFocus?: boolean;
|
||||
}>;
|
||||
|
||||
export default function Playground({code, height, autoFocus}: Props) {
|
||||
const prismTheme = usePrismTheme();
|
||||
const editorScrollRef = useRef<HTMLDivElement>(null);
|
||||
const isBrowser = useIsBrowser();
|
||||
|
||||
const [liveCode, setLiveCode] = useState(code);
|
||||
const [hasCodeChanged, setHasCodeChanged] = useState(false);
|
||||
const [scrollbarWidth, setScrollbarWidth] = useState(0);
|
||||
|
||||
// Once react-live has hydrated the content-editable area, set focus to it
|
||||
// if requested
|
||||
useEffect(() => {
|
||||
if (autoFocus && hasCodeChanged) {
|
||||
const codeElem = editorScrollRef?.current?.querySelector('.prism-code');
|
||||
const sel = window.getSelection();
|
||||
if (codeElem?.clientHeight && sel != null) {
|
||||
sel.selectAllChildren(codeElem);
|
||||
sel.collapseToStart();
|
||||
}
|
||||
}
|
||||
}, [autoFocus, hasCodeChanged]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
// The toolbar is positioned relative to the outside of the scrolling
|
||||
// container so it stays in the same place when scrolling, but this means
|
||||
// it isn't automatically adjusted for scrollbar width. If code change
|
||||
// causes overflow/scrollbar, adjust its position based on its width progrmatically.
|
||||
if (editorScrollRef.current) {
|
||||
setScrollbarWidth(
|
||||
editorScrollRef.current.offsetWidth -
|
||||
editorScrollRef.current.clientWidth,
|
||||
);
|
||||
}
|
||||
}, [editorScrollRef, code]);
|
||||
|
||||
const heightStyle = height
|
||||
? ({'--yg-playground-height': height} as React.CSSProperties)
|
||||
: undefined;
|
||||
|
||||
const handleCodeChange = useCallback((code: string) => {
|
||||
setHasCodeChanged(true);
|
||||
setLiveCode(code);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<LiveProvider
|
||||
code={liveCode}
|
||||
theme={prismTheme}
|
||||
scope={{Node: LiveNode, Layout: RootLiveNode}}>
|
||||
<div className={styles.wrapper} style={heightStyle}>
|
||||
<div className={clsx(styles.playgroundRow)}>
|
||||
<div className={clsx(styles.editorColumn, 'playground-editor')}>
|
||||
<div className={styles.editorScroll} ref={editorScrollRef}>
|
||||
<EditorToolbar
|
||||
code={liveCode}
|
||||
className={styles.editorToolbar}
|
||||
style={{paddingRight: scrollbarWidth + 'px'}}
|
||||
/>
|
||||
|
||||
{isBrowser ? (
|
||||
<LiveEditor
|
||||
className={clsx(styles.playgroundEditor)}
|
||||
onChange={handleCodeChange}
|
||||
/>
|
||||
) : (
|
||||
<LiveEditorFallback code={liveCode} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={clsx(styles.previewColumn)}>
|
||||
<LivePreview className={clsx(styles.livePreview)} />
|
||||
<LiveError className={clsx(styles.liveError)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</LiveProvider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a non-editable approximation of the LiveEditor result, without
|
||||
* relying on prism rendering, for use during SSR.
|
||||
* See https://github.com/facebook/docusaurus/issues/9629
|
||||
*/
|
||||
function LiveEditorFallback({code}: Readonly<{code: string}>) {
|
||||
return (
|
||||
<div className={clsx(styles.playgroundEditor)}>
|
||||
<pre className={clsx('prism-code', styles.liveEditorFallback)}>
|
||||
{code}
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type RootLiveNodeProps = Readonly<{
|
||||
children: React.ReactNode;
|
||||
config?: {useWebDefaults?: boolean};
|
||||
}>;
|
||||
|
||||
function RootLiveNode({children, config}: RootLiveNodeProps) {
|
||||
if (React.Children.count(children) !== 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const child = React.Children.only(children);
|
||||
if (!React.isValidElement(child) || child.type !== LiveNode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const styleNode = styleNodeFromLiveNode(child as unknown as LiveNode);
|
||||
|
||||
return (
|
||||
<Suspense fallback={null}>
|
||||
<LazyYogaViewer
|
||||
rootNode={styleNode}
|
||||
useWebDefaults={config?.useWebDefaults}
|
||||
/>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
type LiveNodeProps = Readonly<{
|
||||
children: React.ReactNode;
|
||||
style: FlexStyle;
|
||||
}>;
|
||||
|
||||
class LiveNode extends React.PureComponent<LiveNodeProps> {}
|
||||
|
||||
function styleNodeFromLiveNode(
|
||||
liveNode: React.ElementRef<typeof LiveNode>,
|
||||
): StyleNode {
|
||||
const children: StyleNode[] = [];
|
||||
|
||||
React.Children.forEach(liveNode.props.children, child => {
|
||||
if (React.isValidElement(child) && child.type === LiveNode) {
|
||||
children.push(styleNodeFromLiveNode(child as unknown as LiveNode));
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
style: liveNode.props.style,
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
// Docusaurus SSR does not correctly support top-level await in the import
|
||||
// chain
|
||||
// 1. https://github.com/facebook/docusaurus/issues/7238
|
||||
// 2. https://github.com/facebook/docusaurus/issues/9468
|
||||
const LazyYogaViewer = lazy(() => import('./YogaViewer'));
|
114
website/src/components/YogaViewer.tsx
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {useMemo} from 'react';
|
||||
import Yoga, {Direction, Overflow, Node as YogaNode} from 'yoga-layout';
|
||||
import {FlexStyle, applyStyle} from './FlexStyle';
|
||||
import LayoutBox from './LayoutBox';
|
||||
|
||||
import type {LayoutMetrics} from './LayoutBox';
|
||||
|
||||
export type Props = Readonly<{
|
||||
rootNode: StyleNode;
|
||||
width?: number;
|
||||
height?: number;
|
||||
className?: string;
|
||||
useWebDefaults?: boolean;
|
||||
}>;
|
||||
|
||||
export type StyleNode = {
|
||||
style?: FlexStyle;
|
||||
children?: StyleNode[];
|
||||
};
|
||||
|
||||
export default function YogaViewer({
|
||||
rootNode,
|
||||
width,
|
||||
height,
|
||||
className,
|
||||
useWebDefaults,
|
||||
}: Props) {
|
||||
const layout = useMemo(
|
||||
() => layoutStyleTree(rootNode, width, height, {useWebDefaults}),
|
||||
[rootNode, width, height, useWebDefaults],
|
||||
);
|
||||
return <LayoutBox metrics={layout} depth={0} className={className} />;
|
||||
}
|
||||
|
||||
type LayoutConfig = Readonly<{
|
||||
useWebDefaults?: boolean;
|
||||
}>;
|
||||
|
||||
// This is not efficient and not a good real-world-example for the best way to use Yoga, but sufficient for a playground
|
||||
function layoutStyleTree(
|
||||
node: StyleNode,
|
||||
rootWidth: number | undefined,
|
||||
rootHeight: number | undefined,
|
||||
layoutConfig: LayoutConfig,
|
||||
): LayoutMetrics {
|
||||
const root = yogaNodeFromStyleNode(node, layoutConfig);
|
||||
root.calculateLayout(rootWidth, rootHeight, Direction.LTR);
|
||||
|
||||
const layoutMetrics = metricsFromYogaNode(root);
|
||||
layoutMetrics.overflow = node.style?.overflow;
|
||||
|
||||
root.freeRecursive();
|
||||
return layoutMetrics;
|
||||
}
|
||||
|
||||
function yogaNodeFromStyleNode(
|
||||
styleNode: StyleNode,
|
||||
layoutConfig: LayoutConfig,
|
||||
): YogaNode {
|
||||
const node = Yoga.Node.create(
|
||||
layoutConfig.useWebDefaults ? webDefaultsConfig : undefined,
|
||||
);
|
||||
applyStyle(node, styleNode.style);
|
||||
|
||||
for (const child of styleNode.children ?? []) {
|
||||
node.insertChild(
|
||||
yogaNodeFromStyleNode(child, layoutConfig),
|
||||
node.getChildCount(),
|
||||
);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
const webDefaultsConfig = Yoga.Config.create();
|
||||
webDefaultsConfig.setUseWebDefaults(true);
|
||||
|
||||
function metricsFromYogaNode(node: YogaNode): LayoutMetrics {
|
||||
const children: LayoutMetrics[] = [];
|
||||
for (let i = 0; i < node.getChildCount(); i++) {
|
||||
children.push(metricsFromYogaNode(node.getChild(i)));
|
||||
}
|
||||
|
||||
// Offset is relative to parent padding box, so we need to subtract the extra
|
||||
// border we show as part of the box.
|
||||
const parentBorderThickness = 1;
|
||||
|
||||
return {
|
||||
top: node.getComputedTop() - parentBorderThickness,
|
||||
left: node.getComputedLeft() - parentBorderThickness,
|
||||
width: node.getComputedWidth(),
|
||||
height: node.getComputedHeight(),
|
||||
overflow: (() => {
|
||||
switch (node.getOverflow()) {
|
||||
case Overflow.Hidden:
|
||||
return 'hidden';
|
||||
case Overflow.Scroll:
|
||||
return 'scroll';
|
||||
case Overflow.Visible:
|
||||
return 'visible';
|
||||
}
|
||||
})(),
|
||||
children,
|
||||
};
|
||||
}
|
37
website/src/css/custom.css
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Any CSS included here will be global. The classic template
|
||||
* bundles Infima by default. Infima is a CSS framework designed to
|
||||
* work well for content-centric websites.
|
||||
*/
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
:root {
|
||||
--ifm-color-primary-lightest: rgb(99, 183, 168);
|
||||
--ifm-color-primary-lighter: rgb(70, 159, 143);
|
||||
--ifm-color-primary-light: rgb(48, 135, 119);
|
||||
--ifm-color-primary: rgb(33, 111, 97);
|
||||
--ifm-color-primary-dark: rgb(22, 87, 75);
|
||||
--ifm-color-primary-darker: rgb(14, 63, 54);
|
||||
--ifm-color-primary-darkest: rgb(8, 39, 33);
|
||||
--ifm-code-font-size: 95%;
|
||||
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* For readability concerns, you should choose a lighter palette in dark mode. */
|
||||
[data-theme='dark'] {
|
||||
--ifm-color-primary-lightest: rgb(192, 231, 224);
|
||||
--ifm-color-primary-lighter: rgb(146, 207, 196);
|
||||
--ifm-color-primary-light: rgb(106, 183, 169);
|
||||
--ifm-color-primary: rgb(74, 159, 144);
|
||||
--ifm-color-primary-dark: rgb(51, 135, 120);
|
||||
--ifm-color-primary-darker: rgb(34, 111, 97);
|
||||
--ifm-color-primary-darkest: rgb(22, 87, 75);
|
||||
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
|
||||
}
|
34
website/src/pages/index.module.css
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.heroBanner {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.heroRow {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.heroLogo {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
@media (max-width: 996px) {
|
||||
.heroLogo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.playgroundSection :global(.playground-editor) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.bg {
|
||||
background-color: var(--yg-color-playground-background);
|
||||
}
|
84
website/src/pages/index.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import clsx from 'clsx';
|
||||
import Link from '@docusaurus/Link';
|
||||
import Layout from '@theme/Layout';
|
||||
|
||||
import styles from './index.module.css';
|
||||
|
||||
import YogaLogo from '../../static/img/logo.svg';
|
||||
import Playground from '../components/Playground';
|
||||
|
||||
function HeroSection() {
|
||||
return (
|
||||
<header className={clsx('hero', styles.heroBanner)}>
|
||||
<div className={clsx('row', 'container', styles.heroRow)}>
|
||||
<div className="col col--6">
|
||||
<h1 className="hero__title">Yoga</h1>
|
||||
<p className="hero__subtitle">
|
||||
A portable layout engine targeting web standards
|
||||
</p>
|
||||
|
||||
<Link
|
||||
className="button button--primary button--lg"
|
||||
to="/docs/about-yoga">
|
||||
Learn more
|
||||
</Link>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<YogaLogo className={styles.heroLogo} />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
const playgroundCode = `
|
||||
<Layout config={{useWebDefaults: false}}>
|
||||
<Node style={{width: 250, height: 475, padding: 10}}>
|
||||
<Node style={{flex: 1, rowGap: 10}}>
|
||||
<Node style={{height: 60}} />
|
||||
<Node style={{flex: 1, marginInline: 10}} />
|
||||
<Node style={{flex: 2, marginInline: 10}} />
|
||||
<Node
|
||||
style={{
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
bottom: 0,
|
||||
height: 64,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-around",
|
||||
}}
|
||||
>
|
||||
<Node style={{height: 40, width: 40}} />
|
||||
<Node style={{height: 40, width: 40}} />
|
||||
<Node style={{height: 40, width: 40}} />
|
||||
<Node style={{height: 40, width: 40}} />
|
||||
</Node>
|
||||
</Node>
|
||||
</Node>
|
||||
</Layout>
|
||||
`.trim();
|
||||
|
||||
function PlaygroundSection() {
|
||||
return (
|
||||
<main className={clsx('container', styles.playgroundSection)}>
|
||||
<Playground height="600px" code={playgroundCode} autoFocus={true} />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Home(): JSX.Element {
|
||||
return (
|
||||
<Layout>
|
||||
<HeroSection />
|
||||
<PlaygroundSection />
|
||||
</Layout>
|
||||
);
|
||||
}
|
7
website/src/pages/markdown-page.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Markdown page example
|
||||
---
|
||||
|
||||
# Markdown page example
|
||||
|
||||
You don't need React to write simple standalone pages.
|
11
website/src/pages/playground.module.css
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.playgroundContainer {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
56
website/src/pages/playground.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import Layout from '@theme/Layout';
|
||||
import {useLocation} from '@docusaurus/router';
|
||||
import lzString from 'lz-string';
|
||||
|
||||
import Playground from '../components/Playground';
|
||||
|
||||
import clsx from 'clsx';
|
||||
import styles from './playground.module.css';
|
||||
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||
|
||||
const defaultCode = `
|
||||
<Layout config={{useWebDefaults: false}}>
|
||||
<Node style={{width: 350, height: 350, padding: 20}}>
|
||||
<Node style={{flex: 1}} />
|
||||
</Node>
|
||||
</Layout>
|
||||
`.trim();
|
||||
|
||||
export default function PlaygroundPage(): JSX.Element {
|
||||
const code = useCodeFromQueryParam();
|
||||
|
||||
return (
|
||||
// @ts-ignore missing prop for `wrapperClassName`
|
||||
<Layout wrapperClassName={clsx('container', styles.bg)} title="Playground">
|
||||
<Playground
|
||||
height="max(80vh, 600px)"
|
||||
code={code}
|
||||
autoFocus={true}
|
||||
key={String(useIsBrowser())}
|
||||
/>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
function useCodeFromQueryParam(): string {
|
||||
const location = useLocation();
|
||||
|
||||
// We don't know the query param ahead of time when doing SSR, so just render
|
||||
// blank to avoid the appearance of code changing.
|
||||
if (!useIsBrowser()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const params = new URLSearchParams(location.search);
|
||||
const codeParam = params.get('code');
|
||||
return codeParam
|
||||
? lzString.decompressFromEncodedURIComponent(codeParam)
|
||||
: defaultCode;
|
||||
}
|
0
website/static/.nojekyll
Normal file
BIN
website/static/img/docusaurus.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
website/static/img/favicon.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
4
website/static/img/link.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-link" viewBox="0 0 16 16">
|
||||
<path d="M6.354 5.5H4a3 3 0 0 0 0 6h3a3 3 0 0 0 2.83-4H9c-.086 0-.17.01-.25.031A2 2 0 0 1 7 10.5H4a2 2 0 1 1 0-4h1.535c.218-.376.495-.714.82-1z"/>
|
||||
<path d="M9 5.5a3 3 0 0 0-2.83 4h1.098A2 2 0 0 1 9 6.5h3a2 2 0 1 1 0 4h-1.535a4.02 4.02 0 0 1-.82 1H12a3 3 0 1 0 0-6z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 401 B |
17
website/static/img/logo.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 200 200" enable-background="new 0 0 200 200" xml:space="preserve">
|
||||
<g>
|
||||
<circle fill="#303846" cx="100" cy="100" r="74"/>
|
||||
<g>
|
||||
<path fill="none" stroke="#97DCCF" stroke-width="5" stroke-miterlimit="10" d="M100.6,130.6c5.9-10.3,6.3-23.3,0-34.3
|
||||
c-6.3-11-17.9-17.1-29.7-17.1c-5.9,10.3-6.3,23.3,0,34.3C77.2,124.4,88.7,130.6,100.6,130.6z"/>
|
||||
<path fill="none" stroke="#97DCCF" stroke-width="5" stroke-miterlimit="10" d="M99.4,130.6c11.8,0,23.3-6.1,29.7-17.1
|
||||
c6.3-11,5.9-24,0-34.3c-11.8,0-23.3,6.1-29.7,17.1C93.1,107.3,93.5,120.3,99.4,130.6z"/>
|
||||
</g>
|
||||
<path fill="none" stroke="#97DCCF" stroke-width="5" stroke-miterlimit="10" d="M100,129.4c10.2-5.9,17.1-17,17.1-29.7
|
||||
c0-12.7-6.9-23.8-17.1-29.7c-10.2,5.9-17.1,17-17.1,29.7C82.9,112.4,89.8,123.5,100,129.4z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
1
website/static/img/meta_oss.svg
Normal file
After Width: | Height: | Size: 14 KiB |
171
website/static/img/undraw_docusaurus_mountain.svg
Normal file
@@ -0,0 +1,171 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1088" height="687.962" viewBox="0 0 1088 687.962">
|
||||
<title>Easy to Use</title>
|
||||
<g id="Group_12" data-name="Group 12" transform="translate(-57 -56)">
|
||||
<g id="Group_11" data-name="Group 11" transform="translate(57 56)">
|
||||
<path id="Path_83" data-name="Path 83" d="M1017.81,560.461c-5.27,45.15-16.22,81.4-31.25,110.31-20,38.52-54.21,54.04-84.77,70.28a193.275,193.275,0,0,1-27.46,11.94c-55.61,19.3-117.85,14.18-166.74,3.99a657.282,657.282,0,0,0-104.09-13.16q-14.97-.675-29.97-.67c-15.42.02-293.07,5.29-360.67-131.57-16.69-33.76-28.13-75-32.24-125.27-11.63-142.12,52.29-235.46,134.74-296.47,155.97-115.41,369.76-110.57,523.43,7.88C941.15,276.621,1036.99,396.031,1017.81,560.461Z" transform="translate(-56 -106.019)" fill="#3f3d56"/>
|
||||
<path id="Path_84" data-name="Path 84" d="M986.56,670.771c-20,38.52-47.21,64.04-77.77,80.28a193.272,193.272,0,0,1-27.46,11.94c-55.61,19.3-117.85,14.18-166.74,3.99a657.3,657.3,0,0,0-104.09-13.16q-14.97-.675-29.97-.67-23.13.03-46.25,1.72c-100.17,7.36-253.82-6.43-321.42-143.29L382,283.981,444.95,445.6l20.09,51.59,55.37-75.98L549,381.981l130.2,149.27,36.8-81.27L970.78,657.9l14.21,11.59Z" transform="translate(-56 -106.019)" fill="#f2f2f2"/>
|
||||
<path id="Path_85" data-name="Path 85" d="M302,282.962l26-57,36,83-31-60Z" opacity="0.1"/>
|
||||
<path id="Path_86" data-name="Path 86" d="M610.5,753.821q-14.97-.675-29.97-.67L465.04,497.191Z" transform="translate(-56 -106.019)" opacity="0.1"/>
|
||||
<path id="Path_87" data-name="Path 87" d="M464.411,315.191,493,292.962l130,150-132-128Z" opacity="0.1"/>
|
||||
<path id="Path_88" data-name="Path 88" d="M908.79,751.051a193.265,193.265,0,0,1-27.46,11.94L679.2,531.251Z" transform="translate(-56 -106.019)" opacity="0.1"/>
|
||||
<circle id="Ellipse_11" data-name="Ellipse 11" cx="3" cy="3" r="3" transform="translate(479 98.962)" fill="#f2f2f2"/>
|
||||
<circle id="Ellipse_12" data-name="Ellipse 12" cx="3" cy="3" r="3" transform="translate(396 201.962)" fill="#f2f2f2"/>
|
||||
<circle id="Ellipse_13" data-name="Ellipse 13" cx="2" cy="2" r="2" transform="translate(600 220.962)" fill="#f2f2f2"/>
|
||||
<circle id="Ellipse_14" data-name="Ellipse 14" cx="2" cy="2" r="2" transform="translate(180 265.962)" fill="#f2f2f2"/>
|
||||
<circle id="Ellipse_15" data-name="Ellipse 15" cx="2" cy="2" r="2" transform="translate(612 96.962)" fill="#f2f2f2"/>
|
||||
<circle id="Ellipse_16" data-name="Ellipse 16" cx="2" cy="2" r="2" transform="translate(736 192.962)" fill="#f2f2f2"/>
|
||||
<circle id="Ellipse_17" data-name="Ellipse 17" cx="2" cy="2" r="2" transform="translate(858 344.962)" fill="#f2f2f2"/>
|
||||
<path id="Path_89" data-name="Path 89" d="M306,121.222h-2.76v-2.76h-1.48v2.76H299V122.7h2.76v2.759h1.48V122.7H306Z" fill="#f2f2f2"/>
|
||||
<path id="Path_90" data-name="Path 90" d="M848,424.222h-2.76v-2.76h-1.48v2.76H841V425.7h2.76v2.759h1.48V425.7H848Z" fill="#f2f2f2"/>
|
||||
<path id="Path_91" data-name="Path 91" d="M1144,719.981c0,16.569-243.557,74-544,74s-544-57.431-544-74,243.557,14,544,14S1144,703.413,1144,719.981Z" transform="translate(-56 -106.019)" fill="#3f3d56"/>
|
||||
<path id="Path_92" data-name="Path 92" d="M1144,719.981c0,16.569-243.557,74-544,74s-544-57.431-544-74,243.557,14,544,14S1144,703.413,1144,719.981Z" transform="translate(-56 -106.019)" opacity="0.1"/>
|
||||
<ellipse id="Ellipse_18" data-name="Ellipse 18" cx="544" cy="30" rx="544" ry="30" transform="translate(0 583.962)" fill="#3f3d56"/>
|
||||
<path id="Path_93" data-name="Path 93" d="M624,677.981c0,33.137-14.775,24-33,24s-33,9.137-33-24,33-96,33-96S624,644.844,624,677.981Z" transform="translate(-56 -106.019)" fill="#ff6584"/>
|
||||
<path id="Path_94" data-name="Path 94" d="M606,690.66c0,15.062-6.716,10.909-15,10.909s-15,4.153-15-10.909,15-43.636,15-43.636S606,675.6,606,690.66Z" transform="translate(-56 -106.019)" opacity="0.1"/>
|
||||
<rect id="Rectangle_97" data-name="Rectangle 97" width="92" height="18" rx="9" transform="translate(489 604.962)" fill="#2f2e41"/>
|
||||
<rect id="Rectangle_98" data-name="Rectangle 98" width="92" height="18" rx="9" transform="translate(489 586.962)" fill="#2f2e41"/>
|
||||
<path id="Path_95" data-name="Path 95" d="M193,596.547c0,55.343,34.719,100.126,77.626,100.126" transform="translate(-56 -106.019)" fill="#3f3d56"/>
|
||||
<path id="Path_96" data-name="Path 96" d="M270.626,696.673c0-55.965,38.745-101.251,86.626-101.251" transform="translate(-56 -106.019)" fill="#6c63ff"/>
|
||||
<path id="Path_97" data-name="Path 97" d="M221.125,601.564c0,52.57,22.14,95.109,49.5,95.109" transform="translate(-56 -106.019)" fill="#6c63ff"/>
|
||||
<path id="Path_98" data-name="Path 98" d="M270.626,696.673c0-71.511,44.783-129.377,100.126-129.377" transform="translate(-56 -106.019)" fill="#3f3d56"/>
|
||||
<path id="Path_99" data-name="Path 99" d="M254.3,697.379s11.009-.339,14.326-2.7,16.934-5.183,17.757-1.395,16.544,18.844,4.115,18.945-28.879-1.936-32.19-3.953S254.3,697.379,254.3,697.379Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
|
||||
<path id="Path_100" data-name="Path 100" d="M290.716,710.909c-12.429.1-28.879-1.936-32.19-3.953-2.522-1.536-3.527-7.048-3.863-9.591l-.368.014s.7,8.879,4.009,10.9,19.761,4.053,32.19,3.953c3.588-.029,4.827-1.305,4.759-3.2C294.755,710.174,293.386,710.887,290.716,710.909Z" transform="translate(-56 -106.019)" opacity="0.2"/>
|
||||
<path id="Path_101" data-name="Path 101" d="M777.429,633.081c0,38.029,23.857,68.8,53.341,68.8" transform="translate(-56 -106.019)" fill="#3f3d56"/>
|
||||
<path id="Path_102" data-name="Path 102" d="M830.769,701.882c0-38.456,26.623-69.575,59.525-69.575" transform="translate(-56 -106.019)" fill="#6c63ff"/>
|
||||
<path id="Path_103" data-name="Path 103" d="M796.755,636.528c0,36.124,15.213,65.354,34.014,65.354" transform="translate(-56 -106.019)" fill="#6c63ff"/>
|
||||
<path id="Path_104" data-name="Path 104" d="M830.769,701.882c0-49.139,30.773-88.9,68.8-88.9" transform="translate(-56 -106.019)" fill="#3f3d56"/>
|
||||
<path id="Path_105" data-name="Path 105" d="M819.548,702.367s7.565-.233,9.844-1.856,11.636-3.562,12.2-.958,11.368,12.949,2.828,13.018-19.844-1.33-22.119-2.716S819.548,702.367,819.548,702.367Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
|
||||
<path id="Path_106" data-name="Path 106" d="M844.574,711.664c-8.54.069-19.844-1.33-22.119-2.716-1.733-1.056-2.423-4.843-2.654-6.59l-.253.01s.479,6.1,2.755,7.487,13.579,2.785,22.119,2.716c2.465-.02,3.317-.9,3.27-2.2C847.349,711.159,846.409,711.649,844.574,711.664Z" transform="translate(-56 -106.019)" opacity="0.2"/>
|
||||
<path id="Path_107" data-name="Path 107" d="M949.813,724.718s11.36-1.729,14.5-4.591,16.89-7.488,18.217-3.667,19.494,17.447,6.633,19.107-30.153,1.609-33.835-.065S949.813,724.718,949.813,724.718Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
|
||||
<path id="Path_108" data-name="Path 108" d="M989.228,734.173c-12.86,1.659-30.153,1.609-33.835-.065-2.8-1.275-4.535-6.858-5.2-9.45l-.379.061s1.833,9.109,5.516,10.783,20.975,1.725,33.835.065c3.712-.479,4.836-1.956,4.529-3.906C993.319,732.907,991.991,733.817,989.228,734.173Z" transform="translate(-56 -106.019)" opacity="0.2"/>
|
||||
<path id="Path_109" data-name="Path 109" d="M670.26,723.9s9.587-1.459,12.237-3.875,14.255-6.32,15.374-3.095,16.452,14.725,5.6,16.125-25.448,1.358-28.555-.055S670.26,723.9,670.26,723.9Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
|
||||
<path id="Path_110" data-name="Path 110" d="M703.524,731.875c-10.853,1.4-25.448,1.358-28.555-.055-2.367-1.076-3.827-5.788-4.39-7.976l-.32.051s1.547,7.687,4.655,9.1,17.7,1.456,28.555.055c3.133-.4,4.081-1.651,3.822-3.3C706.977,730.807,705.856,731.575,703.524,731.875Z" transform="translate(-56 -106.019)" opacity="0.2"/>
|
||||
<path id="Path_111" data-name="Path 111" d="M178.389,719.109s7.463-1.136,9.527-3.016,11.1-4.92,11.969-2.409,12.808,11.463,4.358,12.553-19.811,1.057-22.23-.043S178.389,719.109,178.389,719.109Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
|
||||
<path id="Path_112" data-name="Path 112" d="M204.285,725.321c-8.449,1.09-19.811,1.057-22.23-.043-1.842-.838-2.979-4.506-3.417-6.209l-.249.04s1.2,5.984,3.624,7.085,13.781,1.133,22.23.043c2.439-.315,3.177-1.285,2.976-2.566C206.973,724.489,206.1,725.087,204.285,725.321Z" transform="translate(-56 -106.019)" opacity="0.2"/>
|
||||
<path id="Path_113" data-name="Path 113" d="M439.7,707.337c0,30.22-42.124,20.873-93.7,20.873s-93.074,9.347-93.074-20.873,42.118-36.793,93.694-36.793S439.7,677.117,439.7,707.337Z" transform="translate(-56 -106.019)" opacity="0.1"/>
|
||||
<path id="Path_114" data-name="Path 114" d="M439.7,699.9c0,30.22-42.124,20.873-93.7,20.873s-93.074,9.347-93.074-20.873S295.04,663.1,346.616,663.1,439.7,669.676,439.7,699.9Z" transform="translate(-56 -106.019)" fill="#3f3d56"/>
|
||||
</g>
|
||||
<g id="docusaurus_keytar" transform="translate(312.271 493.733)">
|
||||
<path id="Path_40" data-name="Path 40" d="M99,52h91.791V89.153H99Z" transform="translate(5.904 -14.001)" fill="#fff" fill-rule="evenodd"/>
|
||||
<path id="Path_41" data-name="Path 41" d="M24.855,163.927A21.828,21.828,0,0,1,5.947,153a21.829,21.829,0,0,0,18.908,32.782H46.71V163.927Z" transform="translate(-3 -4.634)" fill="#3ecc5f" fill-rule="evenodd"/>
|
||||
<path id="Path_42" data-name="Path 42" d="M121.861,61.1l76.514-4.782V45.39A21.854,21.854,0,0,0,176.52,23.535H78.173L75.441,18.8a3.154,3.154,0,0,0-5.464,0l-2.732,4.732L64.513,18.8a3.154,3.154,0,0,0-5.464,0l-2.732,4.732L53.586,18.8a3.154,3.154,0,0,0-5.464,0L45.39,23.535c-.024,0-.046,0-.071,0l-4.526-4.525a3.153,3.153,0,0,0-5.276,1.414l-1.5,5.577-5.674-1.521a3.154,3.154,0,0,0-3.863,3.864L26,34.023l-5.575,1.494a3.155,3.155,0,0,0-1.416,5.278l4.526,4.526c0,.023,0,.046,0,.07L18.8,48.122a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,59.05a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,69.977a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,80.9a3.154,3.154,0,0,0,0,5.464L23.535,89.1,18.8,91.832a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,102.76a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,113.687a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,124.615a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,135.542a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,146.469a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,157.4a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,168.324a3.154,3.154,0,0,0,0,5.464l4.732,2.732A21.854,21.854,0,0,0,45.39,198.375H176.52a21.854,21.854,0,0,0,21.855-21.855V89.1l-76.514-4.782a11.632,11.632,0,0,1,0-23.219" transform="translate(-1.681 -17.226)" fill="#3ecc5f" fill-rule="evenodd"/>
|
||||
<path id="Path_43" data-name="Path 43" d="M143,186.71h32.782V143H143Z" transform="translate(9.984 -5.561)" fill="#3ecc5f" fill-rule="evenodd"/>
|
||||
<path id="Path_44" data-name="Path 44" d="M196.71,159.855a5.438,5.438,0,0,0-.7.07c-.042-.164-.081-.329-.127-.493a5.457,5.457,0,1,0-5.4-9.372q-.181-.185-.366-.367a5.454,5.454,0,1,0-9.384-5.4c-.162-.046-.325-.084-.486-.126a5.467,5.467,0,1,0-10.788,0c-.162.042-.325.08-.486.126a5.457,5.457,0,1,0-9.384,5.4,21.843,21.843,0,1,0,36.421,21.02,5.452,5.452,0,1,0,.7-10.858" transform="translate(10.912 -6.025)" fill="#44d860" fill-rule="evenodd"/>
|
||||
<path id="Path_45" data-name="Path 45" d="M153,124.855h32.782V103H153Z" transform="translate(10.912 -9.271)" fill="#3ecc5f" fill-rule="evenodd"/>
|
||||
<path id="Path_46" data-name="Path 46" d="M194.855,116.765a2.732,2.732,0,1,0,0-5.464,2.811,2.811,0,0,0-.349.035c-.022-.082-.04-.164-.063-.246a2.733,2.733,0,0,0-1.052-5.253,2.7,2.7,0,0,0-1.648.566q-.09-.093-.184-.184a2.7,2.7,0,0,0,.553-1.633,2.732,2.732,0,0,0-5.245-1.07,10.928,10.928,0,1,0,0,21.031,2.732,2.732,0,0,0,5.245-1.07,2.7,2.7,0,0,0-.553-1.633q.093-.09.184-.184a2.7,2.7,0,0,0,1.648.566,2.732,2.732,0,0,0,1.052-5.253c.023-.081.042-.164.063-.246a2.814,2.814,0,0,0,.349.035" transform="translate(12.767 -9.377)" fill="#44d860" fill-rule="evenodd"/>
|
||||
<path id="Path_47" data-name="Path 47" d="M65.087,56.891a2.732,2.732,0,0,1-2.732-2.732,8.2,8.2,0,0,0-16.391,0,2.732,2.732,0,0,1-5.464,0,13.659,13.659,0,0,1,27.319,0,2.732,2.732,0,0,1-2.732,2.732" transform="translate(0.478 -15.068)" fill-rule="evenodd"/>
|
||||
<path id="Path_48" data-name="Path 48" d="M103,191.347h65.565a21.854,21.854,0,0,0,21.855-21.855V93H124.855A21.854,21.854,0,0,0,103,114.855Z" transform="translate(6.275 -10.199)" fill="#ffff50" fill-rule="evenodd"/>
|
||||
<path id="Path_49" data-name="Path 49" d="M173.216,129.787H118.535a1.093,1.093,0,1,1,0-2.185h54.681a1.093,1.093,0,0,1,0,2.185m0,21.855H118.535a1.093,1.093,0,1,1,0-2.186h54.681a1.093,1.093,0,0,1,0,2.186m0,21.855H118.535a1.093,1.093,0,1,1,0-2.185h54.681a1.093,1.093,0,0,1,0,2.185m0-54.434H118.535a1.093,1.093,0,1,1,0-2.185h54.681a1.093,1.093,0,0,1,0,2.185m0,21.652H118.535a1.093,1.093,0,1,1,0-2.186h54.681a1.093,1.093,0,0,1,0,2.186m0,21.855H118.535a1.093,1.093,0,1,1,0-2.186h54.681a1.093,1.093,0,0,1,0,2.186M189.585,61.611c-.013,0-.024-.007-.037-.005-3.377.115-4.974,3.492-6.384,6.472-1.471,3.114-2.608,5.139-4.473,5.078-2.064-.074-3.244-2.406-4.494-4.874-1.436-2.835-3.075-6.049-6.516-5.929-3.329.114-4.932,3.053-6.346,5.646-1.5,2.762-2.529,4.442-4.5,4.364-2.106-.076-3.225-1.972-4.52-4.167-1.444-2.443-3.112-5.191-6.487-5.1-3.272.113-4.879,2.606-6.3,4.808-1.5,2.328-2.552,3.746-4.551,3.662-2.156-.076-3.27-1.65-4.558-3.472-1.447-2.047-3.077-4.363-6.442-4.251-3.2.109-4.807,2.153-6.224,3.954-1.346,1.709-2.4,3.062-4.621,2.977a1.093,1.093,0,0,0-.079,2.186c3.3.11,4.967-1.967,6.417-3.81,1.286-1.635,2.4-3.045,4.582-3.12,2.1-.09,3.091,1.218,4.584,3.327,1.417,2,3.026,4.277,6.263,4.394,3.391.114,5.022-2.42,6.467-4.663,1.292-2,2.406-3.734,4.535-3.807,1.959-.073,3.026,1.475,4.529,4.022,1.417,2.4,3.023,5.121,6.324,5.241,3.415.118,5.064-2.863,6.5-5.5,1.245-2.282,2.419-4.437,4.5-4.509,1.959-.046,2.981,1.743,4.492,4.732,1.412,2.79,3.013,5.95,6.365,6.071l.185,0c3.348,0,4.937-3.36,6.343-6.331,1.245-2.634,2.423-5.114,4.444-5.216Z" transform="translate(7.109 -13.11)" fill-rule="evenodd"/>
|
||||
<path id="Path_50" data-name="Path 50" d="M83,186.71h43.71V143H83Z" transform="translate(4.42 -5.561)" fill="#3ecc5f" fill-rule="evenodd"/>
|
||||
<g id="Group_8" data-name="Group 8" transform="matrix(0.966, -0.259, 0.259, 0.966, 109.327, 91.085)">
|
||||
<rect id="Rectangle_3" data-name="Rectangle 3" width="92.361" height="36.462" rx="2" transform="translate(0 0)" fill="#d8d8d8"/>
|
||||
<g id="Group_2" data-name="Group 2" transform="translate(1.531 23.03)">
|
||||
<rect id="Rectangle_4" data-name="Rectangle 4" width="5.336" height="5.336" rx="1" transform="translate(16.797 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_5" data-name="Rectangle 5" width="5.336" height="5.336" rx="1" transform="translate(23.12 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_6" data-name="Rectangle 6" width="5.336" height="5.336" rx="1" transform="translate(29.444 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_7" data-name="Rectangle 7" width="5.336" height="5.336" rx="1" transform="translate(35.768 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_8" data-name="Rectangle 8" width="5.336" height="5.336" rx="1" transform="translate(42.091 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_9" data-name="Rectangle 9" width="5.336" height="5.336" rx="1" transform="translate(48.415 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_10" data-name="Rectangle 10" width="5.336" height="5.336" rx="1" transform="translate(54.739 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_11" data-name="Rectangle 11" width="5.336" height="5.336" rx="1" transform="translate(61.063 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_12" data-name="Rectangle 12" width="5.336" height="5.336" rx="1" transform="translate(67.386 0)" fill="#4a4a4a"/>
|
||||
<path id="Path_51" data-name="Path 51" d="M1.093,0H14.518a1.093,1.093,0,0,1,1.093,1.093V4.243a1.093,1.093,0,0,1-1.093,1.093H1.093A1.093,1.093,0,0,1,0,4.243V1.093A1.093,1.093,0,0,1,1.093,0ZM75,0H88.426a1.093,1.093,0,0,1,1.093,1.093V4.243a1.093,1.093,0,0,1-1.093,1.093H75a1.093,1.093,0,0,1-1.093-1.093V1.093A1.093,1.093,0,0,1,75,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
|
||||
</g>
|
||||
<g id="Group_3" data-name="Group 3" transform="translate(1.531 10.261)">
|
||||
<path id="Path_52" data-name="Path 52" d="M1.093,0H6.218A1.093,1.093,0,0,1,7.31,1.093V4.242A1.093,1.093,0,0,1,6.218,5.335H1.093A1.093,1.093,0,0,1,0,4.242V1.093A1.093,1.093,0,0,1,1.093,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
|
||||
<rect id="Rectangle_13" data-name="Rectangle 13" width="5.336" height="5.336" rx="1" transform="translate(8.299 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_14" data-name="Rectangle 14" width="5.336" height="5.336" rx="1" transform="translate(14.623 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_15" data-name="Rectangle 15" width="5.336" height="5.336" rx="1" transform="translate(20.947 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_16" data-name="Rectangle 16" width="5.336" height="5.336" rx="1" transform="translate(27.271 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_17" data-name="Rectangle 17" width="5.336" height="5.336" rx="1" transform="translate(33.594 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_18" data-name="Rectangle 18" width="5.336" height="5.336" rx="1" transform="translate(39.918 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_19" data-name="Rectangle 19" width="5.336" height="5.336" rx="1" transform="translate(46.242 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_20" data-name="Rectangle 20" width="5.336" height="5.336" rx="1" transform="translate(52.565 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_21" data-name="Rectangle 21" width="5.336" height="5.336" rx="1" transform="translate(58.888 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_22" data-name="Rectangle 22" width="5.336" height="5.336" rx="1" transform="translate(65.212 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_23" data-name="Rectangle 23" width="5.336" height="5.336" rx="1" transform="translate(71.536 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_24" data-name="Rectangle 24" width="5.336" height="5.336" rx="1" transform="translate(77.859 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_25" data-name="Rectangle 25" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
|
||||
</g>
|
||||
<g id="Group_4" data-name="Group 4" transform="translate(91.05 9.546) rotate(180)">
|
||||
<path id="Path_53" data-name="Path 53" d="M1.093,0H6.219A1.093,1.093,0,0,1,7.312,1.093v3.15A1.093,1.093,0,0,1,6.219,5.336H1.093A1.093,1.093,0,0,1,0,4.243V1.093A1.093,1.093,0,0,1,1.093,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
|
||||
<rect id="Rectangle_26" data-name="Rectangle 26" width="5.336" height="5.336" rx="1" transform="translate(8.299 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_27" data-name="Rectangle 27" width="5.336" height="5.336" rx="1" transform="translate(14.623 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_28" data-name="Rectangle 28" width="5.336" height="5.336" rx="1" transform="translate(20.947 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_29" data-name="Rectangle 29" width="5.336" height="5.336" rx="1" transform="translate(27.271 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_30" data-name="Rectangle 30" width="5.336" height="5.336" rx="1" transform="translate(33.594 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_31" data-name="Rectangle 31" width="5.336" height="5.336" rx="1" transform="translate(39.918 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_32" data-name="Rectangle 32" width="5.336" height="5.336" rx="1" transform="translate(46.242 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_33" data-name="Rectangle 33" width="5.336" height="5.336" rx="1" transform="translate(52.565 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_34" data-name="Rectangle 34" width="5.336" height="5.336" rx="1" transform="translate(58.889 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_35" data-name="Rectangle 35" width="5.336" height="5.336" rx="1" transform="translate(65.213 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_36" data-name="Rectangle 36" width="5.336" height="5.336" rx="1" transform="translate(71.537 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_37" data-name="Rectangle 37" width="5.336" height="5.336" rx="1" transform="translate(77.86 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_38" data-name="Rectangle 38" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_39" data-name="Rectangle 39" width="5.336" height="5.336" rx="1" transform="translate(8.299 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_40" data-name="Rectangle 40" width="5.336" height="5.336" rx="1" transform="translate(14.623 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_41" data-name="Rectangle 41" width="5.336" height="5.336" rx="1" transform="translate(20.947 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_42" data-name="Rectangle 42" width="5.336" height="5.336" rx="1" transform="translate(27.271 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_43" data-name="Rectangle 43" width="5.336" height="5.336" rx="1" transform="translate(33.594 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_44" data-name="Rectangle 44" width="5.336" height="5.336" rx="1" transform="translate(39.918 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_45" data-name="Rectangle 45" width="5.336" height="5.336" rx="1" transform="translate(46.242 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_46" data-name="Rectangle 46" width="5.336" height="5.336" rx="1" transform="translate(52.565 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_47" data-name="Rectangle 47" width="5.336" height="5.336" rx="1" transform="translate(58.889 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_48" data-name="Rectangle 48" width="5.336" height="5.336" rx="1" transform="translate(65.213 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_49" data-name="Rectangle 49" width="5.336" height="5.336" rx="1" transform="translate(71.537 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_50" data-name="Rectangle 50" width="5.336" height="5.336" rx="1" transform="translate(77.86 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_51" data-name="Rectangle 51" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
|
||||
</g>
|
||||
<g id="Group_6" data-name="Group 6" transform="translate(1.531 16.584)">
|
||||
<path id="Path_54" data-name="Path 54" d="M1.093,0h7.3A1.093,1.093,0,0,1,9.485,1.093v3.15A1.093,1.093,0,0,1,8.392,5.336h-7.3A1.093,1.093,0,0,1,0,4.243V1.094A1.093,1.093,0,0,1,1.093,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
|
||||
<g id="Group_5" data-name="Group 5" transform="translate(10.671 0)">
|
||||
<rect id="Rectangle_52" data-name="Rectangle 52" width="5.336" height="5.336" rx="1" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_53" data-name="Rectangle 53" width="5.336" height="5.336" rx="1" transform="translate(6.324 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_54" data-name="Rectangle 54" width="5.336" height="5.336" rx="1" transform="translate(12.647 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_55" data-name="Rectangle 55" width="5.336" height="5.336" rx="1" transform="translate(18.971 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_56" data-name="Rectangle 56" width="5.336" height="5.336" rx="1" transform="translate(25.295 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_57" data-name="Rectangle 57" width="5.336" height="5.336" rx="1" transform="translate(31.619 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_58" data-name="Rectangle 58" width="5.336" height="5.336" rx="1" transform="translate(37.942 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_59" data-name="Rectangle 59" width="5.336" height="5.336" rx="1" transform="translate(44.265 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_60" data-name="Rectangle 60" width="5.336" height="5.336" rx="1" transform="translate(50.589 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_61" data-name="Rectangle 61" width="5.336" height="5.336" rx="1" transform="translate(56.912 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_62" data-name="Rectangle 62" width="5.336" height="5.336" rx="1" transform="translate(63.236 0)" fill="#4a4a4a"/>
|
||||
</g>
|
||||
<path id="Path_55" data-name="Path 55" d="M1.094,0H8A1.093,1.093,0,0,1,9.091,1.093v3.15A1.093,1.093,0,0,1,8,5.336H1.093A1.093,1.093,0,0,1,0,4.243V1.094A1.093,1.093,0,0,1,1.093,0Z" transform="translate(80.428 0)" fill="#4a4a4a" fill-rule="evenodd"/>
|
||||
</g>
|
||||
<g id="Group_7" data-name="Group 7" transform="translate(1.531 29.627)">
|
||||
<rect id="Rectangle_63" data-name="Rectangle 63" width="5.336" height="5.336" rx="1" transform="translate(0 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_64" data-name="Rectangle 64" width="5.336" height="5.336" rx="1" transform="translate(6.324 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_65" data-name="Rectangle 65" width="5.336" height="5.336" rx="1" transform="translate(12.647 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_66" data-name="Rectangle 66" width="5.336" height="5.336" rx="1" transform="translate(18.971 0)" fill="#4a4a4a"/>
|
||||
<path id="Path_56" data-name="Path 56" d="M1.093,0H31.515a1.093,1.093,0,0,1,1.093,1.093V4.244a1.093,1.093,0,0,1-1.093,1.093H1.093A1.093,1.093,0,0,1,0,4.244V1.093A1.093,1.093,0,0,1,1.093,0ZM34.687,0h3.942a1.093,1.093,0,0,1,1.093,1.093V4.244a1.093,1.093,0,0,1-1.093,1.093H34.687a1.093,1.093,0,0,1-1.093-1.093V1.093A1.093,1.093,0,0,1,34.687,0Z" transform="translate(25.294 0)" fill="#4a4a4a" fill-rule="evenodd"/>
|
||||
<rect id="Rectangle_67" data-name="Rectangle 67" width="5.336" height="5.336" rx="1" transform="translate(66.003 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_68" data-name="Rectangle 68" width="5.336" height="5.336" rx="1" transform="translate(72.327 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_69" data-name="Rectangle 69" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
|
||||
<path id="Path_57" data-name="Path 57" d="M5.336,0V1.18A1.093,1.093,0,0,1,4.243,2.273H1.093A1.093,1.093,0,0,1,0,1.18V0Z" transform="translate(83.59 2.273) rotate(180)" fill="#4a4a4a"/>
|
||||
<path id="Path_58" data-name="Path 58" d="M5.336,0V1.18A1.093,1.093,0,0,1,4.243,2.273H1.093A1.093,1.093,0,0,1,0,1.18V0Z" transform="translate(78.255 3.063)" fill="#4a4a4a"/>
|
||||
</g>
|
||||
<rect id="Rectangle_70" data-name="Rectangle 70" width="88.927" height="2.371" rx="1.085" transform="translate(1.925 1.17)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_71" data-name="Rectangle 71" width="4.986" height="1.581" rx="0.723" transform="translate(4.1 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_72" data-name="Rectangle 72" width="4.986" height="1.581" rx="0.723" transform="translate(10.923 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_73" data-name="Rectangle 73" width="4.986" height="1.581" rx="0.723" transform="translate(16.173 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_74" data-name="Rectangle 74" width="4.986" height="1.581" rx="0.723" transform="translate(21.421 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_75" data-name="Rectangle 75" width="4.986" height="1.581" rx="0.723" transform="translate(26.671 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_76" data-name="Rectangle 76" width="4.986" height="1.581" rx="0.723" transform="translate(33.232 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_77" data-name="Rectangle 77" width="4.986" height="1.581" rx="0.723" transform="translate(38.48 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_78" data-name="Rectangle 78" width="4.986" height="1.581" rx="0.723" transform="translate(43.73 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_79" data-name="Rectangle 79" width="4.986" height="1.581" rx="0.723" transform="translate(48.978 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_80" data-name="Rectangle 80" width="4.986" height="1.581" rx="0.723" transform="translate(55.54 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_81" data-name="Rectangle 81" width="4.986" height="1.581" rx="0.723" transform="translate(60.788 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_82" data-name="Rectangle 82" width="4.986" height="1.581" rx="0.723" transform="translate(66.038 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_83" data-name="Rectangle 83" width="4.986" height="1.581" rx="0.723" transform="translate(72.599 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_84" data-name="Rectangle 84" width="4.986" height="1.581" rx="0.723" transform="translate(77.847 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_85" data-name="Rectangle 85" width="4.986" height="1.581" rx="0.723" transform="translate(83.097 1.566)" fill="#d8d8d8" opacity="0.136"/>
|
||||
</g>
|
||||
<path id="Path_59" data-name="Path 59" d="M146.71,159.855a5.439,5.439,0,0,0-.7.07c-.042-.164-.081-.329-.127-.493a5.457,5.457,0,1,0-5.4-9.372q-.181-.185-.366-.367a5.454,5.454,0,1,0-9.384-5.4c-.162-.046-.325-.084-.486-.126a5.467,5.467,0,1,0-10.788,0c-.162.042-.325.08-.486.126a5.457,5.457,0,1,0-9.384,5.4,21.843,21.843,0,1,0,36.421,21.02,5.452,5.452,0,1,0,.7-10.858" transform="translate(6.275 -6.025)" fill="#44d860" fill-rule="evenodd"/>
|
||||
<path id="Path_60" data-name="Path 60" d="M83,124.855h43.71V103H83Z" transform="translate(4.42 -9.271)" fill="#3ecc5f" fill-rule="evenodd"/>
|
||||
<path id="Path_61" data-name="Path 61" d="M134.855,116.765a2.732,2.732,0,1,0,0-5.464,2.811,2.811,0,0,0-.349.035c-.022-.082-.04-.164-.063-.246a2.733,2.733,0,0,0-1.052-5.253,2.7,2.7,0,0,0-1.648.566q-.09-.093-.184-.184a2.7,2.7,0,0,0,.553-1.633,2.732,2.732,0,0,0-5.245-1.07,10.928,10.928,0,1,0,0,21.031,2.732,2.732,0,0,0,5.245-1.07,2.7,2.7,0,0,0-.553-1.633q.093-.09.184-.184a2.7,2.7,0,0,0,1.648.566,2.732,2.732,0,0,0,1.052-5.253c.023-.081.042-.164.063-.246a2.811,2.811,0,0,0,.349.035" transform="translate(7.202 -9.377)" fill="#44d860" fill-rule="evenodd"/>
|
||||
<path id="Path_62" data-name="Path 62" d="M143.232,42.33a2.967,2.967,0,0,1-.535-.055,2.754,2.754,0,0,1-.514-.153,2.838,2.838,0,0,1-.471-.251,4.139,4.139,0,0,1-.415-.339,3.2,3.2,0,0,1-.338-.415A2.7,2.7,0,0,1,140.5,39.6a2.968,2.968,0,0,1,.055-.535,3.152,3.152,0,0,1,.152-.514,2.874,2.874,0,0,1,.252-.47,2.633,2.633,0,0,1,.753-.754,2.837,2.837,0,0,1,.471-.251,2.753,2.753,0,0,1,.514-.153,2.527,2.527,0,0,1,1.071,0,2.654,2.654,0,0,1,.983.4,4.139,4.139,0,0,1,.415.339,4.019,4.019,0,0,1,.339.415,2.786,2.786,0,0,1,.251.47,2.864,2.864,0,0,1,.208,1.049,2.77,2.77,0,0,1-.8,1.934,4.139,4.139,0,0,1-.415.339,2.722,2.722,0,0,1-1.519.459m21.855-1.366a2.789,2.789,0,0,1-1.935-.8,4.162,4.162,0,0,1-.338-.415,2.7,2.7,0,0,1-.459-1.519,2.789,2.789,0,0,1,.8-1.934,4.139,4.139,0,0,1,.415-.339,2.838,2.838,0,0,1,.471-.251,2.752,2.752,0,0,1,.514-.153,2.527,2.527,0,0,1,1.071,0,2.654,2.654,0,0,1,.983.4,4.139,4.139,0,0,1,.415.339,2.79,2.79,0,0,1,.8,1.934,3.069,3.069,0,0,1-.055.535,2.779,2.779,0,0,1-.153.514,3.885,3.885,0,0,1-.251.47,4.02,4.02,0,0,1-.339.415,4.138,4.138,0,0,1-.415.339,2.722,2.722,0,0,1-1.519.459" transform="translate(9.753 -15.532)" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 31 KiB |
170
website/static/img/undraw_docusaurus_react.svg
Normal file
@@ -0,0 +1,170 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1041.277" height="554.141" viewBox="0 0 1041.277 554.141">
|
||||
<title>Powered by React</title>
|
||||
<g id="Group_24" data-name="Group 24" transform="translate(-440 -263)">
|
||||
<g id="Group_23" data-name="Group 23" transform="translate(439.989 262.965)">
|
||||
<path id="Path_299" data-name="Path 299" d="M1040.82,611.12q-1.74,3.75-3.47,7.4-2.7,5.67-5.33,11.12c-.78,1.61-1.56,3.19-2.32,4.77-8.6,17.57-16.63,33.11-23.45,45.89A73.21,73.21,0,0,1,942.44,719l-151.65,1.65h-1.6l-13,.14-11.12.12-34.1.37h-1.38l-17.36.19h-.53l-107,1.16-95.51,1-11.11.12-69,.75H429l-44.75.48h-.48l-141.5,1.53-42.33.46a87.991,87.991,0,0,1-10.79-.54h0c-1.22-.14-2.44-.3-3.65-.49a87.38,87.38,0,0,1-51.29-27.54C116,678.37,102.75,655,93.85,629.64q-1.93-5.49-3.6-11.12C59.44,514.37,97,380,164.6,290.08q4.25-5.64,8.64-11l.07-.08c20.79-25.52,44.1-46.84,68.93-62,44-26.91,92.75-34.49,140.7-11.9,40.57,19.12,78.45,28.11,115.17,30.55,3.71.24,7.42.42,11.11.53,84.23,2.65,163.17-27.7,255.87-47.29,3.69-.78,7.39-1.55,11.12-2.28,66.13-13.16,139.49-20.1,226.73-5.51a189.089,189.089,0,0,1,26.76,6.4q5.77,1.86,11.12,4c41.64,16.94,64.35,48.24,74,87.46q1.37,5.46,2.37,11.11C1134.3,384.41,1084.19,518.23,1040.82,611.12Z" transform="translate(-79.34 -172.91)" fill="#f2f2f2"/>
|
||||
<path id="Path_300" data-name="Path 300" d="M576.36,618.52a95.21,95.21,0,0,1-1.87,11.12h93.7V618.52Zm-78.25,62.81,11.11-.09V653.77c-3.81-.17-7.52-.34-11.11-.52ZM265.19,618.52v11.12h198.5V618.52ZM1114.87,279h-74V191.51q-5.35-2.17-11.12-4V279H776.21V186.58c-3.73.73-7.43,1.5-11.12,2.28V279H509.22V236.15c-3.69-.11-7.4-.29-11.11-.53V279H242.24V217c-24.83,15.16-48.14,36.48-68.93,62h-.07v.08q-4.4,5.4-8.64,11h8.64V618.52h-83q1.66,5.63,3.6,11.12h79.39v93.62a87,87,0,0,0,12.2,2.79c1.21.19,2.43.35,3.65.49h0a87.991,87.991,0,0,0,10.79.54l42.33-.46v-97H498.11v94.21l11.11-.12V629.64H765.09V721l11.12-.12V629.64H1029.7v4.77c.76-1.58,1.54-3.16,2.32-4.77q2.63-5.45,5.33-11.12,1.73-3.64,3.47-7.4v-321h76.42Q1116.23,284.43,1114.87,279ZM242.24,618.52V290.08H498.11V618.52Zm267,0V290.08H765.09V618.52Zm520.48,0H776.21V290.08H1029.7Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
|
||||
<path id="Path_301" data-name="Path 301" d="M863.09,533.65v13l-151.92,1.4-1.62.03-57.74.53-1.38.02-17.55.15h-.52l-106.98.99L349.77,551.4h-.15l-44.65.42-.48.01-198.4,1.82v-15l46.65-28,93.6-.78,2-.01.66-.01,2-.03,44.94-.37,2.01-.01.64-.01,2-.01L315,509.3l.38-.01,35.55-.3h.29l277.4-2.34,6.79-.05h.68l5.18-.05,37.65-.31,2-.03,1.85-.02h.96l11.71-.09,2.32-.03,3.11-.02,9.75-.09,15.47-.13,2-.02,3.48-.02h.65l74.71-.64Z" fill="#65617d"/>
|
||||
<path id="Path_302" data-name="Path 302" d="M863.09,533.65v13l-151.92,1.4-1.62.03-57.74.53-1.38.02-17.55.15h-.52l-106.98.99L349.77,551.4h-.15l-44.65.42-.48.01-198.4,1.82v-15l46.65-28,93.6-.78,2-.01.66-.01,2-.03,44.94-.37,2.01-.01.64-.01,2-.01L315,509.3l.38-.01,35.55-.3h.29l277.4-2.34,6.79-.05h.68l5.18-.05,37.65-.31,2-.03,1.85-.02h.96l11.71-.09,2.32-.03,3.11-.02,9.75-.09,15.47-.13,2-.02,3.48-.02h.65l74.71-.64Z" opacity="0.2"/>
|
||||
<path id="Path_303" data-name="Path 303" d="M375.44,656.57v24.49a6.13,6.13,0,0,1-3.5,5.54,6,6,0,0,1-2.5.6l-34.9.74a6,6,0,0,1-2.7-.57,6.12,6.12,0,0,1-3.57-5.57V656.57Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
|
||||
<path id="Path_304" data-name="Path 304" d="M375.44,656.57v24.49a6.13,6.13,0,0,1-3.5,5.54,6,6,0,0,1-2.5.6l-34.9.74a6,6,0,0,1-2.7-.57,6.12,6.12,0,0,1-3.57-5.57V656.57Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
|
||||
<path id="Path_305" data-name="Path 305" d="M377.44,656.57v24.49a6.13,6.13,0,0,1-3.5,5.54,6,6,0,0,1-2.5.6l-34.9.74a6,6,0,0,1-2.7-.57,6.12,6.12,0,0,1-3.57-5.57V656.57Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
|
||||
<rect id="Rectangle_137" data-name="Rectangle 137" width="47.17" height="31.5" transform="translate(680.92 483.65)" fill="#3f3d56"/>
|
||||
<rect id="Rectangle_138" data-name="Rectangle 138" width="47.17" height="31.5" transform="translate(680.92 483.65)" opacity="0.1"/>
|
||||
<rect id="Rectangle_139" data-name="Rectangle 139" width="47.17" height="31.5" transform="translate(678.92 483.65)" fill="#3f3d56"/>
|
||||
<path id="Path_306" data-name="Path 306" d="M298.09,483.65v4.97l-47.17,1.26v-6.23Z" opacity="0.1"/>
|
||||
<path id="Path_307" data-name="Path 307" d="M460.69,485.27v168.2a4,4,0,0,1-3.85,3.95l-191.65,5.1h-.05a4,4,0,0,1-3.95-3.95V485.27a4,4,0,0,1,3.95-3.95h191.6a4,4,0,0,1,3.95,3.95Z" transform="translate(-79.34 -172.91)" fill="#65617d"/>
|
||||
<path id="Path_308" data-name="Path 308" d="M265.19,481.32v181.2h-.05a4,4,0,0,1-3.95-3.95V485.27a4,4,0,0,1,3.95-3.95Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
|
||||
<path id="Path_309" data-name="Path 309" d="M194.59,319.15h177.5V467.4l-177.5,4Z" fill="#39374d"/>
|
||||
<path id="Path_310" data-name="Path 310" d="M726.09,483.65v6.41l-47.17-1.26v-5.15Z" opacity="0.1"/>
|
||||
<path id="Path_311" data-name="Path 311" d="M867.69,485.27v173.3a4,4,0,0,1-4,3.95h0L672,657.42a4,4,0,0,1-3.85-3.95V485.27a4,4,0,0,1,3.95-3.95H863.7a4,4,0,0,1,3.99,3.95Z" transform="translate(-79.34 -172.91)" fill="#65617d"/>
|
||||
<path id="Path_312" data-name="Path 312" d="M867.69,485.27v173.3a4,4,0,0,1-4,3.95h0V481.32h0a4,4,0,0,1,4,3.95Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
|
||||
<path id="Path_313" data-name="Path 313" d="M775.59,319.15H598.09V467.4l177.5,4Z" fill="#39374d"/>
|
||||
<path id="Path_314" data-name="Path 314" d="M663.19,485.27v168.2a4,4,0,0,1-3.85,3.95l-191.65,5.1h0a4,4,0,0,1-4-3.95V485.27a4,4,0,0,1,3.95-3.95h191.6A4,4,0,0,1,663.19,485.27Z" transform="translate(-79.34 -172.91)" fill="#65617d"/>
|
||||
<path id="Path_315" data-name="Path 315" d="M397.09,319.15h177.5V467.4l-177.5,4Z" fill="#4267b2"/>
|
||||
<path id="Path_316" data-name="Path 316" d="M863.09,533.65v13l-151.92,1.4-1.62.03-57.74.53-1.38.02-17.55.15h-.52l-106.98.99L349.77,551.4h-.15l-44.65.42-.48.01-198.4,1.82v-15l202.51-1.33h.48l40.99-.28h.19l283.08-1.87h.29l.17-.01h.47l4.79-.03h1.46l74.49-.5,4.4-.02.98-.01Z" opacity="0.1"/>
|
||||
<circle id="Ellipse_111" data-name="Ellipse 111" cx="51.33" cy="51.33" r="51.33" transform="translate(435.93 246.82)" fill="#fbbebe"/>
|
||||
<path id="Path_317" data-name="Path 317" d="M617.94,550.07s-99.5,12-90,0c3.44-4.34,4.39-17.2,4.2-31.85-.06-4.45-.22-9.06-.45-13.65-1.1-22-3.75-43.5-3.75-43.5s87-41,77-8.5c-4,13.13-2.69,31.57.35,48.88.89,5.05,1.92,10,3,14.7a344.66,344.66,0,0,0,9.65,33.92Z" transform="translate(-79.34 -172.91)" fill="#fbbebe"/>
|
||||
<path id="Path_318" data-name="Path 318" d="M585.47,546c11.51-2.13,23.7-6,34.53-1.54,2.85,1.17,5.47,2.88,8.39,3.86s6.12,1.22,9.16,1.91c10.68,2.42,19.34,10.55,24.9,20s8.44,20.14,11.26,30.72l6.9,25.83c6,22.45,12,45.09,13.39,68.3a2437.506,2437.506,0,0,1-250.84,1.43c5.44-10.34,11-21.31,10.54-33s-7.19-23.22-4.76-34.74c1.55-7.34,6.57-13.39,9.64-20.22,8.75-19.52,1.94-45.79,17.32-60.65,6.92-6.68,17-9.21,26.63-8.89,12.28.41,24.85,4.24,37,6.11C555.09,547.48,569.79,548.88,585.47,546Z" transform="translate(-79.34 -172.91)" fill="#ff6584"/>
|
||||
<path id="Path_319" data-name="Path 319" d="M716.37,657.17l-.1,1.43v.1l-.17,2.3-1.33,18.51-1.61,22.3-.46,6.28-1,13.44v.17l-107,1-175.59,1.9v.84h-.14v-1.12l.45-14.36.86-28.06.74-23.79.07-2.37a10.53,10.53,0,0,1,11.42-10.17c4.72.4,10.85.89,18.18,1.41l3,.22c42.33,2.94,120.56,6.74,199.5,2,1.66-.09,3.33-.19,5-.31,12.24-.77,24.47-1.76,36.58-3a10.53,10.53,0,0,1,11.6,11.23Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
|
||||
<path id="Path_320" data-name="Path 320" d="M429.08,725.44v-.84l175.62-1.91,107-1h.3v-.17l1-13.44.43-6,1.64-22.61,1.29-17.9v-.44a10.617,10.617,0,0,0-.11-2.47.3.3,0,0,0,0-.1,10.391,10.391,0,0,0-2-4.64,10.54,10.54,0,0,0-9.42-4c-12.11,1.24-24.34,2.23-36.58,3-1.67.12-3.34.22-5,.31-78.94,4.69-157.17.89-199.5-2l-3-.22c-7.33-.52-13.46-1-18.18-1.41a10.54,10.54,0,0,0-11.24,8.53,11,11,0,0,0-.18,1.64l-.68,22.16L429.54,710l-.44,14.36v1.12Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
|
||||
<path id="Path_321" data-name="Path 321" d="M716.67,664.18l-1.23,15.33-1.83,22.85-.46,5.72-1,12.81-.06.64v.17h0l-.15,1.48.11-1.48h-.29l-107,1-175.65,1.9v-.28l.49-14.36,1-28.06.64-18.65A6.36,6.36,0,0,1,434.3,658a6.25,6.25,0,0,1,3.78-.9c2.1.17,4.68.37,7.69.59,4.89.36,10.92.78,17.94,1.22,13,.82,29.31,1.7,48,2.42,52,2,122.2,2.67,188.88-3.17,3-.26,6.1-.55,9.13-.84a6.26,6.26,0,0,1,3.48.66,5.159,5.159,0,0,1,.86.54,6.14,6.14,0,0,1,2,2.46,3.564,3.564,0,0,1,.25.61A6.279,6.279,0,0,1,716.67,664.18Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
|
||||
<path id="Path_322" data-name="Path 322" d="M377.44,677.87v3.19a6.13,6.13,0,0,1-3.5,5.54l-40.1.77a6.12,6.12,0,0,1-3.57-5.57v-3Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
|
||||
<path id="Path_323" data-name="Path 323" d="M298.59,515.57l-52.25,1V507.9l52.25-1Z" fill="#3f3d56"/>
|
||||
<path id="Path_324" data-name="Path 324" d="M298.59,515.57l-52.25,1V507.9l52.25-1Z" opacity="0.1"/>
|
||||
<path id="Path_325" data-name="Path 325" d="M300.59,515.57l-52.25,1V507.9l52.25-1Z" fill="#3f3d56"/>
|
||||
<path id="Path_326" data-name="Path 326" d="M758.56,679.87v3.19a6.13,6.13,0,0,0,3.5,5.54l40.1.77a6.12,6.12,0,0,0,3.57-5.57v-3Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
|
||||
<path id="Path_327" data-name="Path 327" d="M678.72,517.57l52.25,1V509.9l-52.25-1Z" opacity="0.1"/>
|
||||
<path id="Path_328" data-name="Path 328" d="M676.72,517.57l52.25,1V509.9l-52.25-1Z" fill="#3f3d56"/>
|
||||
<path id="Path_329" data-name="Path 329" d="M534.13,486.79c.08,7-3.16,13.6-5.91,20.07a163.491,163.491,0,0,0-12.66,74.71c.73,11,2.58,22,.73,32.9s-8.43,21.77-19,24.9c17.53,10.45,41.26,9.35,57.76-2.66,8.79-6.4,15.34-15.33,21.75-24.11a97.86,97.86,0,0,1-13.31,44.75A103.43,103.43,0,0,0,637,616.53c4.31-5.81,8.06-12.19,9.72-19.23,3.09-13-1.22-26.51-4.51-39.5a266.055,266.055,0,0,1-6.17-33c-.43-3.56-.78-7.22.1-10.7,1-4.07,3.67-7.51,5.64-11.22,5.6-10.54,5.73-23.3,2.86-34.88s-8.49-22.26-14.06-32.81c-4.46-8.46-9.3-17.31-17.46-22.28-5.1-3.1-11-4.39-16.88-5.64l-25.37-5.43c-5.55-1.19-11.26-2.38-16.87-1.51-9.47,1.48-16.14,8.32-22,15.34-4.59,5.46-15.81,15.71-16.6,22.86-.72,6.59,5.1,17.63,6.09,24.58,1.3,9,2.22,6,7.3,11.52C532,478.05,534.07,482,534.13,486.79Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
|
||||
</g>
|
||||
<g id="docusaurus_keytar" transform="translate(670.271 615.768)">
|
||||
<path id="Path_40" data-name="Path 40" d="M99,52h43.635V69.662H99Z" transform="translate(-49.132 -33.936)" fill="#fff" fill-rule="evenodd"/>
|
||||
<path id="Path_41" data-name="Path 41" d="M13.389,158.195A10.377,10.377,0,0,1,4.4,153a10.377,10.377,0,0,0,8.988,15.584H23.779V158.195Z" transform="translate(-3 -82.47)" fill="#3ecc5f" fill-rule="evenodd"/>
|
||||
<path id="Path_42" data-name="Path 42" d="M66.967,38.083l36.373-2.273V30.615A10.389,10.389,0,0,0,92.95,20.226H46.2l-1.3-2.249a1.5,1.5,0,0,0-2.6,0L41,20.226l-1.3-2.249a1.5,1.5,0,0,0-2.6,0l-1.3,2.249-1.3-2.249a1.5,1.5,0,0,0-2.6,0l-1.3,2.249-.034,0-2.152-2.151a1.5,1.5,0,0,0-2.508.672L25.21,21.4l-2.7-.723a1.5,1.5,0,0,0-1.836,1.837l.722,2.7-2.65.71a1.5,1.5,0,0,0-.673,2.509l2.152,2.152c0,.011,0,.022,0,.033l-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6L20.226,41l-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3A10.389,10.389,0,0,0,30.615,103.34H92.95A10.389,10.389,0,0,0,103.34,92.95V51.393L66.967,49.12a5.53,5.53,0,0,1,0-11.038" transform="translate(-9.836 -17.226)" fill="#3ecc5f" fill-rule="evenodd"/>
|
||||
<path id="Path_43" data-name="Path 43" d="M143,163.779h15.584V143H143Z" transform="translate(-70.275 -77.665)" fill="#3ecc5f" fill-rule="evenodd"/>
|
||||
<path id="Path_44" data-name="Path 44" d="M173.779,148.389a2.582,2.582,0,0,0-.332.033c-.02-.078-.038-.156-.06-.234a2.594,2.594,0,1,0-2.567-4.455q-.086-.088-.174-.175a2.593,2.593,0,1,0-4.461-2.569c-.077-.022-.154-.04-.231-.06a2.6,2.6,0,1,0-5.128,0c-.077.02-.154.038-.231.06a2.594,2.594,0,1,0-4.461,2.569,10.384,10.384,0,1,0,17.314,9.992,2.592,2.592,0,1,0,.332-5.161" transform="translate(-75.08 -75.262)" fill="#44d860" fill-rule="evenodd"/>
|
||||
<path id="Path_45" data-name="Path 45" d="M153,113.389h15.584V103H153Z" transform="translate(-75.08 -58.444)" fill="#3ecc5f" fill-rule="evenodd"/>
|
||||
<path id="Path_46" data-name="Path 46" d="M183.389,108.944a1.3,1.3,0,1,0,0-2.6,1.336,1.336,0,0,0-.166.017c-.01-.039-.019-.078-.03-.117a1.3,1.3,0,0,0-.5-2.5,1.285,1.285,0,0,0-.783.269q-.043-.044-.087-.087a1.285,1.285,0,0,0,.263-.776,1.3,1.3,0,0,0-2.493-.509,5.195,5.195,0,1,0,0,10,1.3,1.3,0,0,0,2.493-.509,1.285,1.285,0,0,0-.263-.776q.044-.043.087-.087a1.285,1.285,0,0,0,.783.269,1.3,1.3,0,0,0,.5-2.5c.011-.038.02-.078.03-.117a1.337,1.337,0,0,0,.166.017" transform="translate(-84.691 -57.894)" fill="#44d860" fill-rule="evenodd"/>
|
||||
<path id="Path_47" data-name="Path 47" d="M52.188,48.292a1.3,1.3,0,0,1-1.3-1.3,3.9,3.9,0,0,0-7.792,0,1.3,1.3,0,1,1-2.6,0,6.493,6.493,0,0,1,12.987,0,1.3,1.3,0,0,1-1.3,1.3" transform="translate(-21.02 -28.41)" fill-rule="evenodd"/>
|
||||
<path id="Path_48" data-name="Path 48" d="M103,139.752h31.168a10.389,10.389,0,0,0,10.389-10.389V93H113.389A10.389,10.389,0,0,0,103,103.389Z" transform="translate(-51.054 -53.638)" fill="#ffff50" fill-rule="evenodd"/>
|
||||
<path id="Path_49" data-name="Path 49" d="M141.1,94.017H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.389H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.389H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0-25.877H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.293H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.389H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m7.782-47.993c-.006,0-.011,0-.018,0-1.605.055-2.365,1.66-3.035,3.077-.7,1.48-1.24,2.443-2.126,2.414-.981-.035-1.542-1.144-2.137-2.317-.683-1.347-1.462-2.876-3.1-2.819-1.582.054-2.344,1.451-3.017,2.684-.715,1.313-1.2,2.112-2.141,2.075-1-.036-1.533-.938-2.149-1.981-.686-1.162-1.479-2.467-3.084-2.423-1.555.053-2.319,1.239-2.994,2.286-.713,1.106-1.213,1.781-2.164,1.741-1.025-.036-1.554-.784-2.167-1.65-.688-.973-1.463-2.074-3.062-2.021a3.815,3.815,0,0,0-2.959,1.879c-.64.812-1.14,1.456-2.2,1.415a.52.52,0,0,0-.037,1.039,3.588,3.588,0,0,0,3.05-1.811c.611-.777,1.139-1.448,2.178-1.483,1-.043,1.47.579,2.179,1.582.674.953,1.438,2.033,2.977,2.089,1.612.054,2.387-1.151,3.074-2.217.614-.953,1.144-1.775,2.156-1.81.931-.035,1.438.7,2.153,1.912.674,1.141,1.437,2.434,3.006,2.491,1.623.056,2.407-1.361,3.09-2.616.592-1.085,1.15-2.109,2.14-2.143.931-.022,1.417.829,2.135,2.249.671,1.326,1.432,2.828,3.026,2.886l.088,0c1.592,0,2.347-1.6,3.015-3.01.592-1.252,1.152-2.431,2.113-2.479Z" transform="translate(-55.378 -38.552)" fill-rule="evenodd"/>
|
||||
<path id="Path_50" data-name="Path 50" d="M83,163.779h20.779V143H83Z" transform="translate(-41.443 -77.665)" fill="#3ecc5f" fill-rule="evenodd"/>
|
||||
<g id="Group_8" data-name="Group 8" transform="matrix(0.966, -0.259, 0.259, 0.966, 51.971, 43.3)">
|
||||
<rect id="Rectangle_3" data-name="Rectangle 3" width="43.906" height="17.333" rx="2" transform="translate(0 0)" fill="#d8d8d8"/>
|
||||
<g id="Group_2" data-name="Group 2" transform="translate(0.728 10.948)">
|
||||
<rect id="Rectangle_4" data-name="Rectangle 4" width="2.537" height="2.537" rx="1" transform="translate(7.985 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_5" data-name="Rectangle 5" width="2.537" height="2.537" rx="1" transform="translate(10.991 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_6" data-name="Rectangle 6" width="2.537" height="2.537" rx="1" transform="translate(13.997 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_7" data-name="Rectangle 7" width="2.537" height="2.537" rx="1" transform="translate(17.003 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_8" data-name="Rectangle 8" width="2.537" height="2.537" rx="1" transform="translate(20.009 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_9" data-name="Rectangle 9" width="2.537" height="2.537" rx="1" transform="translate(23.015 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_10" data-name="Rectangle 10" width="2.537" height="2.537" rx="1" transform="translate(26.021 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_11" data-name="Rectangle 11" width="2.537" height="2.537" rx="1" transform="translate(29.028 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_12" data-name="Rectangle 12" width="2.537" height="2.537" rx="1" transform="translate(32.034 0)" fill="#4a4a4a"/>
|
||||
<path id="Path_51" data-name="Path 51" d="M.519,0H6.9A.519.519,0,0,1,7.421.52v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.519A.519.519,0,0,1,.519,0ZM35.653,0h6.383a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H35.652a.519.519,0,0,1-.519-.519V.519A.519.519,0,0,1,35.652,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
|
||||
</g>
|
||||
<g id="Group_3" data-name="Group 3" transform="translate(0.728 4.878)">
|
||||
<path id="Path_52" data-name="Path 52" d="M.519,0H2.956a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.519A.519.519,0,0,1,.519,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
|
||||
<rect id="Rectangle_13" data-name="Rectangle 13" width="2.537" height="2.537" rx="1" transform="translate(3.945 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_14" data-name="Rectangle 14" width="2.537" height="2.537" rx="1" transform="translate(6.951 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_15" data-name="Rectangle 15" width="2.537" height="2.537" rx="1" transform="translate(9.958 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_16" data-name="Rectangle 16" width="2.537" height="2.537" rx="1" transform="translate(12.964 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_17" data-name="Rectangle 17" width="2.537" height="2.537" rx="1" transform="translate(15.97 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_18" data-name="Rectangle 18" width="2.537" height="2.537" rx="1" transform="translate(18.976 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_19" data-name="Rectangle 19" width="2.537" height="2.537" rx="1" transform="translate(21.982 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_20" data-name="Rectangle 20" width="2.537" height="2.537" rx="1" transform="translate(24.988 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_21" data-name="Rectangle 21" width="2.537" height="2.537" rx="1" transform="translate(27.994 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_22" data-name="Rectangle 22" width="2.537" height="2.537" rx="1" transform="translate(31 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_23" data-name="Rectangle 23" width="2.537" height="2.537" rx="1" transform="translate(34.006 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_24" data-name="Rectangle 24" width="2.537" height="2.537" rx="1" transform="translate(37.012 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_25" data-name="Rectangle 25" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
|
||||
</g>
|
||||
<g id="Group_4" data-name="Group 4" transform="translate(43.283 4.538) rotate(180)">
|
||||
<path id="Path_53" data-name="Path 53" d="M.519,0H2.956a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.519A.519.519,0,0,1,.519,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
|
||||
<rect id="Rectangle_26" data-name="Rectangle 26" width="2.537" height="2.537" rx="1" transform="translate(3.945 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_27" data-name="Rectangle 27" width="2.537" height="2.537" rx="1" transform="translate(6.951 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_28" data-name="Rectangle 28" width="2.537" height="2.537" rx="1" transform="translate(9.958 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_29" data-name="Rectangle 29" width="2.537" height="2.537" rx="1" transform="translate(12.964 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_30" data-name="Rectangle 30" width="2.537" height="2.537" rx="1" transform="translate(15.97 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_31" data-name="Rectangle 31" width="2.537" height="2.537" rx="1" transform="translate(18.976 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_32" data-name="Rectangle 32" width="2.537" height="2.537" rx="1" transform="translate(21.982 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_33" data-name="Rectangle 33" width="2.537" height="2.537" rx="1" transform="translate(24.988 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_34" data-name="Rectangle 34" width="2.537" height="2.537" rx="1" transform="translate(27.994 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_35" data-name="Rectangle 35" width="2.537" height="2.537" rx="1" transform="translate(31.001 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_36" data-name="Rectangle 36" width="2.537" height="2.537" rx="1" transform="translate(34.007 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_37" data-name="Rectangle 37" width="2.537" height="2.537" rx="1" transform="translate(37.013 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_38" data-name="Rectangle 38" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_39" data-name="Rectangle 39" width="2.537" height="2.537" rx="1" transform="translate(3.945 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_40" data-name="Rectangle 40" width="2.537" height="2.537" rx="1" transform="translate(6.951 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_41" data-name="Rectangle 41" width="2.537" height="2.537" rx="1" transform="translate(9.958 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_42" data-name="Rectangle 42" width="2.537" height="2.537" rx="1" transform="translate(12.964 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_43" data-name="Rectangle 43" width="2.537" height="2.537" rx="1" transform="translate(15.97 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_44" data-name="Rectangle 44" width="2.537" height="2.537" rx="1" transform="translate(18.976 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_45" data-name="Rectangle 45" width="2.537" height="2.537" rx="1" transform="translate(21.982 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_46" data-name="Rectangle 46" width="2.537" height="2.537" rx="1" transform="translate(24.988 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_47" data-name="Rectangle 47" width="2.537" height="2.537" rx="1" transform="translate(27.994 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_48" data-name="Rectangle 48" width="2.537" height="2.537" rx="1" transform="translate(31.001 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_49" data-name="Rectangle 49" width="2.537" height="2.537" rx="1" transform="translate(34.007 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_50" data-name="Rectangle 50" width="2.537" height="2.537" rx="1" transform="translate(37.013 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_51" data-name="Rectangle 51" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
|
||||
</g>
|
||||
<g id="Group_6" data-name="Group 6" transform="translate(0.728 7.883)">
|
||||
<path id="Path_54" data-name="Path 54" d="M.519,0h3.47a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.52A.519.519,0,0,1,.519,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
|
||||
<g id="Group_5" data-name="Group 5" transform="translate(5.073 0)">
|
||||
<rect id="Rectangle_52" data-name="Rectangle 52" width="2.537" height="2.537" rx="1" transform="translate(0 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_53" data-name="Rectangle 53" width="2.537" height="2.537" rx="1" transform="translate(3.006 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_54" data-name="Rectangle 54" width="2.537" height="2.537" rx="1" transform="translate(6.012 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_55" data-name="Rectangle 55" width="2.537" height="2.537" rx="1" transform="translate(9.018 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_56" data-name="Rectangle 56" width="2.537" height="2.537" rx="1" transform="translate(12.025 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_57" data-name="Rectangle 57" width="2.537" height="2.537" rx="1" transform="translate(15.031 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_58" data-name="Rectangle 58" width="2.537" height="2.537" rx="1" transform="translate(18.037 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_59" data-name="Rectangle 59" width="2.537" height="2.537" rx="1" transform="translate(21.042 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_60" data-name="Rectangle 60" width="2.537" height="2.537" rx="1" transform="translate(24.049 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_61" data-name="Rectangle 61" width="2.537" height="2.537" rx="1" transform="translate(27.055 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_62" data-name="Rectangle 62" width="2.537" height="2.537" rx="1" transform="translate(30.061 0)" fill="#4a4a4a"/>
|
||||
</g>
|
||||
<path id="Path_55" data-name="Path 55" d="M.52,0H3.8a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.52A.519.519,0,0,1,.519,0Z" transform="translate(38.234 0)" fill="#4a4a4a" fill-rule="evenodd"/>
|
||||
</g>
|
||||
<g id="Group_7" data-name="Group 7" transform="translate(0.728 14.084)">
|
||||
<rect id="Rectangle_63" data-name="Rectangle 63" width="2.537" height="2.537" rx="1" transform="translate(0 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_64" data-name="Rectangle 64" width="2.537" height="2.537" rx="1" transform="translate(3.006 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_65" data-name="Rectangle 65" width="2.537" height="2.537" rx="1" transform="translate(6.012 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_66" data-name="Rectangle 66" width="2.537" height="2.537" rx="1" transform="translate(9.018 0)" fill="#4a4a4a"/>
|
||||
<path id="Path_56" data-name="Path 56" d="M.519,0H14.981A.519.519,0,0,1,15.5.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.018V.519A.519.519,0,0,1,.519,0Zm15.97,0h1.874a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H16.489a.519.519,0,0,1-.519-.519V.519A.519.519,0,0,1,16.489,0Z" transform="translate(12.024 0)" fill="#4a4a4a" fill-rule="evenodd"/>
|
||||
<rect id="Rectangle_67" data-name="Rectangle 67" width="2.537" height="2.537" rx="1" transform="translate(31.376 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_68" data-name="Rectangle 68" width="2.537" height="2.537" rx="1" transform="translate(34.382 0)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_69" data-name="Rectangle 69" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
|
||||
<path id="Path_57" data-name="Path 57" d="M2.537,0V.561a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,.561V0Z" transform="translate(39.736 1.08) rotate(180)" fill="#4a4a4a"/>
|
||||
<path id="Path_58" data-name="Path 58" d="M2.537,0V.561a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,.561V0Z" transform="translate(37.2 1.456)" fill="#4a4a4a"/>
|
||||
</g>
|
||||
<rect id="Rectangle_70" data-name="Rectangle 70" width="42.273" height="1.127" rx="0.564" transform="translate(0.915 0.556)" fill="#4a4a4a"/>
|
||||
<rect id="Rectangle_71" data-name="Rectangle 71" width="2.37" height="0.752" rx="0.376" transform="translate(1.949 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_72" data-name="Rectangle 72" width="2.37" height="0.752" rx="0.376" transform="translate(5.193 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_73" data-name="Rectangle 73" width="2.37" height="0.752" rx="0.376" transform="translate(7.688 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_74" data-name="Rectangle 74" width="2.37" height="0.752" rx="0.376" transform="translate(10.183 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_75" data-name="Rectangle 75" width="2.37" height="0.752" rx="0.376" transform="translate(12.679 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_76" data-name="Rectangle 76" width="2.37" height="0.752" rx="0.376" transform="translate(15.797 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_77" data-name="Rectangle 77" width="2.37" height="0.752" rx="0.376" transform="translate(18.292 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_78" data-name="Rectangle 78" width="2.37" height="0.752" rx="0.376" transform="translate(20.788 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_79" data-name="Rectangle 79" width="2.37" height="0.752" rx="0.376" transform="translate(23.283 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_80" data-name="Rectangle 80" width="2.37" height="0.752" rx="0.376" transform="translate(26.402 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_81" data-name="Rectangle 81" width="2.37" height="0.752" rx="0.376" transform="translate(28.897 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_82" data-name="Rectangle 82" width="2.37" height="0.752" rx="0.376" transform="translate(31.393 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_83" data-name="Rectangle 83" width="2.37" height="0.752" rx="0.376" transform="translate(34.512 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_84" data-name="Rectangle 84" width="2.37" height="0.752" rx="0.376" transform="translate(37.007 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
<rect id="Rectangle_85" data-name="Rectangle 85" width="2.37" height="0.752" rx="0.376" transform="translate(39.502 0.744)" fill="#d8d8d8" opacity="0.136"/>
|
||||
</g>
|
||||
<path id="Path_59" data-name="Path 59" d="M123.779,148.389a2.583,2.583,0,0,0-.332.033c-.02-.078-.038-.156-.06-.234a2.594,2.594,0,1,0-2.567-4.455q-.086-.088-.174-.175a2.593,2.593,0,1,0-4.461-2.569c-.077-.022-.154-.04-.231-.06a2.6,2.6,0,1,0-5.128,0c-.077.02-.154.038-.231.06a2.594,2.594,0,1,0-4.461,2.569,10.384,10.384,0,1,0,17.314,9.992,2.592,2.592,0,1,0,.332-5.161" transform="translate(-51.054 -75.262)" fill="#44d860" fill-rule="evenodd"/>
|
||||
<path id="Path_60" data-name="Path 60" d="M83,113.389h20.779V103H83Z" transform="translate(-41.443 -58.444)" fill="#3ecc5f" fill-rule="evenodd"/>
|
||||
<path id="Path_61" data-name="Path 61" d="M123.389,108.944a1.3,1.3,0,1,0,0-2.6,1.338,1.338,0,0,0-.166.017c-.01-.039-.019-.078-.03-.117a1.3,1.3,0,0,0-.5-2.5,1.285,1.285,0,0,0-.783.269q-.043-.044-.087-.087a1.285,1.285,0,0,0,.263-.776,1.3,1.3,0,0,0-2.493-.509,5.195,5.195,0,1,0,0,10,1.3,1.3,0,0,0,2.493-.509,1.285,1.285,0,0,0-.263-.776q.044-.043.087-.087a1.285,1.285,0,0,0,.783.269,1.3,1.3,0,0,0,.5-2.5c.011-.038.02-.078.03-.117a1.335,1.335,0,0,0,.166.017" transform="translate(-55.859 -57.894)" fill="#44d860" fill-rule="evenodd"/>
|
||||
<path id="Path_62" data-name="Path 62" d="M141.8,38.745a1.41,1.41,0,0,1-.255-.026,1.309,1.309,0,0,1-.244-.073,1.349,1.349,0,0,1-.224-.119,1.967,1.967,0,0,1-.2-.161,1.52,1.52,0,0,1-.161-.2,1.282,1.282,0,0,1-.218-.722,1.41,1.41,0,0,1,.026-.255,1.5,1.5,0,0,1,.072-.244,1.364,1.364,0,0,1,.12-.223,1.252,1.252,0,0,1,.358-.358,1.349,1.349,0,0,1,.224-.119,1.309,1.309,0,0,1,.244-.073,1.2,1.2,0,0,1,.509,0,1.262,1.262,0,0,1,.468.192,1.968,1.968,0,0,1,.2.161,1.908,1.908,0,0,1,.161.2,1.322,1.322,0,0,1,.12.223,1.361,1.361,0,0,1,.1.5,1.317,1.317,0,0,1-.379.919,1.968,1.968,0,0,1-.2.161,1.346,1.346,0,0,1-.223.119,1.332,1.332,0,0,1-.5.1m10.389-.649a1.326,1.326,0,0,1-.92-.379,1.979,1.979,0,0,1-.161-.2,1.282,1.282,0,0,1-.218-.722,1.326,1.326,0,0,1,.379-.919,1.967,1.967,0,0,1,.2-.161,1.351,1.351,0,0,1,.224-.119,1.308,1.308,0,0,1,.244-.073,1.2,1.2,0,0,1,.509,0,1.262,1.262,0,0,1,.468.192,1.967,1.967,0,0,1,.2.161,1.326,1.326,0,0,1,.379.919,1.461,1.461,0,0,1-.026.255,1.323,1.323,0,0,1-.073.244,1.847,1.847,0,0,1-.119.223,1.911,1.911,0,0,1-.161.2,1.967,1.967,0,0,1-.2.161,1.294,1.294,0,0,1-.722.218" transform="translate(-69.074 -26.006)" fill-rule="evenodd"/>
|
||||
</g>
|
||||
<g id="React-icon" transform="translate(906.3 541.56)">
|
||||
<path id="Path_330" data-name="Path 330" d="M263.668,117.179c0-5.827-7.3-11.35-18.487-14.775,2.582-11.4,1.434-20.477-3.622-23.382a7.861,7.861,0,0,0-4.016-1v4a4.152,4.152,0,0,1,2.044.466c2.439,1.4,3.5,6.724,2.672,13.574-.2,1.685-.52,3.461-.914,5.272a86.9,86.9,0,0,0-11.386-1.954,87.469,87.469,0,0,0-7.459-8.965c5.845-5.433,11.332-8.41,15.062-8.41V78h0c-4.931,0-11.386,3.514-17.913,9.611-6.527-6.061-12.982-9.539-17.913-9.539v4c3.712,0,9.216,2.959,15.062,8.356a84.687,84.687,0,0,0-7.405,8.947,83.732,83.732,0,0,0-11.4,1.972c-.412-1.793-.717-3.532-.932-5.2-.843-6.85.2-12.175,2.618-13.592a3.991,3.991,0,0,1,2.062-.466v-4h0a8,8,0,0,0-4.052,1c-5.039,2.9-6.168,11.96-3.568,23.328-11.153,3.443-18.415,8.947-18.415,14.757,0,5.828,7.3,11.35,18.487,14.775-2.582,11.4-1.434,20.477,3.622,23.382a7.882,7.882,0,0,0,4.034,1c4.931,0,11.386-3.514,17.913-9.611,6.527,6.061,12.982,9.539,17.913,9.539a8,8,0,0,0,4.052-1c5.039-2.9,6.168-11.96,3.568-23.328C256.406,128.511,263.668,122.988,263.668,117.179Zm-23.346-11.96c-.663,2.313-1.488,4.7-2.421,7.083-.735-1.434-1.506-2.869-2.349-4.3-.825-1.434-1.7-2.833-2.582-4.2C235.517,104.179,237.974,104.645,240.323,105.219Zm-8.212,19.1c-1.4,2.421-2.833,4.716-4.321,6.85-2.672.233-5.379.359-8.1.359-2.708,0-5.415-.126-8.069-.341q-2.232-3.2-4.339-6.814-2.044-3.523-3.73-7.136c1.112-2.4,2.367-4.805,3.712-7.154,1.4-2.421,2.833-4.716,4.321-6.85,2.672-.233,5.379-.359,8.1-.359,2.708,0,5.415.126,8.069.341q2.232,3.2,4.339,6.814,2.044,3.523,3.73,7.136C234.692,119.564,233.455,121.966,232.11,124.315Zm5.792-2.331c.968,2.4,1.793,4.805,2.474,7.136-2.349.574-4.823,1.058-7.387,1.434.879-1.381,1.757-2.8,2.582-4.25C236.4,124.871,237.167,123.419,237.9,121.984ZM219.72,141.116a73.921,73.921,0,0,1-4.985-5.738c1.614.072,3.263.126,4.931.126,1.685,0,3.353-.036,4.985-.126A69.993,69.993,0,0,1,219.72,141.116ZM206.38,130.555c-2.546-.377-5-.843-7.352-1.417.663-2.313,1.488-4.7,2.421-7.083.735,1.434,1.506,2.869,2.349,4.3S205.5,129.192,206.38,130.555ZM219.63,93.241a73.924,73.924,0,0,1,4.985,5.738c-1.614-.072-3.263-.126-4.931-.126-1.686,0-3.353.036-4.985.126A69.993,69.993,0,0,1,219.63,93.241ZM206.362,103.8c-.879,1.381-1.757,2.8-2.582,4.25-.825,1.434-1.6,2.869-2.331,4.3-.968-2.4-1.793-4.805-2.474-7.136C201.323,104.663,203.8,104.179,206.362,103.8Zm-16.227,22.449c-6.348-2.708-10.454-6.258-10.454-9.073s4.106-6.383,10.454-9.073c1.542-.663,3.228-1.255,4.967-1.811a86.122,86.122,0,0,0,4.034,10.92,84.9,84.9,0,0,0-3.981,10.866C193.38,127.525,191.694,126.915,190.134,126.252Zm9.647,25.623c-2.439-1.4-3.5-6.724-2.672-13.574.2-1.686.52-3.461.914-5.272a86.9,86.9,0,0,0,11.386,1.954,87.465,87.465,0,0,0,7.459,8.965c-5.845,5.433-11.332,8.41-15.062,8.41A4.279,4.279,0,0,1,199.781,151.875Zm42.532-13.663c.843,6.85-.2,12.175-2.618,13.592a3.99,3.99,0,0,1-2.062.466c-3.712,0-9.216-2.959-15.062-8.356a84.689,84.689,0,0,0,7.405-8.947,83.731,83.731,0,0,0,11.4-1.972A50.194,50.194,0,0,1,242.313,138.212Zm6.9-11.96c-1.542.663-3.228,1.255-4.967,1.811a86.12,86.12,0,0,0-4.034-10.92,84.9,84.9,0,0,0,3.981-10.866c1.775.556,3.461,1.165,5.039,1.829,6.348,2.708,10.454,6.258,10.454,9.073C259.67,119.994,255.564,123.562,249.216,126.252Z" fill="#61dafb"/>
|
||||
<path id="Path_331" data-name="Path 331" d="M320.8,78.4Z" transform="translate(-119.082 -0.328)" fill="#61dafb"/>
|
||||
<circle id="Ellipse_112" data-name="Ellipse 112" cx="8.194" cy="8.194" r="8.194" transform="translate(211.472 108.984)" fill="#61dafb"/>
|
||||
<path id="Path_332" data-name="Path 332" d="M520.5,78.1Z" transform="translate(-282.975 -0.082)" fill="#61dafb"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 35 KiB |
40
website/static/img/undraw_docusaurus_tree.svg
Normal file
@@ -0,0 +1,40 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1129" height="663" viewBox="0 0 1129 663">
|
||||
<title>Focus on What Matters</title>
|
||||
<circle cx="321" cy="321" r="321" fill="#f2f2f2" />
|
||||
<ellipse cx="559" cy="635.49998" rx="514" ry="27.50002" fill="#3f3d56" />
|
||||
<ellipse cx="558" cy="627" rx="460" ry="22" opacity="0.2" />
|
||||
<rect x="131" y="152.5" width="840" height="50" fill="#3f3d56" />
|
||||
<path d="M166.5,727.3299A21.67009,21.67009,0,0,0,188.1701,749H984.8299A21.67009,21.67009,0,0,0,1006.5,727.3299V296h-840Z" transform="translate(-35.5 -118.5)" fill="#3f3d56" />
|
||||
<path d="M984.8299,236H188.1701A21.67009,21.67009,0,0,0,166.5,257.6701V296h840V257.6701A21.67009,21.67009,0,0,0,984.8299,236Z" transform="translate(-35.5 -118.5)" fill="#3f3d56" />
|
||||
<path d="M984.8299,236H188.1701A21.67009,21.67009,0,0,0,166.5,257.6701V296h840V257.6701A21.67009,21.67009,0,0,0,984.8299,236Z" transform="translate(-35.5 -118.5)" opacity="0.2" />
|
||||
<circle cx="181" cy="147.5" r="13" fill="#3f3d56" />
|
||||
<circle cx="217" cy="147.5" r="13" fill="#3f3d56" />
|
||||
<circle cx="253" cy="147.5" r="13" fill="#3f3d56" />
|
||||
<rect x="168" y="213.5" width="337" height="386" rx="5.33505" fill="#606060" />
|
||||
<rect x="603" y="272.5" width="284" height="22" rx="5.47638" fill="#2e8555" />
|
||||
<rect x="537" y="352.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
|
||||
<rect x="537" y="396.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
|
||||
<rect x="537" y="440.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
|
||||
<rect x="537" y="484.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
|
||||
<rect x="865" y="552.5" width="88" height="26" rx="7.02756" fill="#3ecc5f" />
|
||||
<path d="M1088.60287,624.61594a30.11371,30.11371,0,0,0,3.98291-15.266c0-13.79652-8.54358-24.98081-19.08256-24.98081s-19.08256,11.18429-19.08256,24.98081a30.11411,30.11411,0,0,0,3.98291,15.266,31.248,31.248,0,0,0,0,30.53213,31.248,31.248,0,0,0,0,30.53208,31.248,31.248,0,0,0,0,30.53208,30.11408,30.11408,0,0,0-3.98291,15.266c0,13.79652,8.54353,24.98081,19.08256,24.98081s19.08256-11.18429,19.08256-24.98081a30.11368,30.11368,0,0,0-3.98291-15.266,31.248,31.248,0,0,0,0-30.53208,31.248,31.248,0,0,0,0-30.53208,31.248,31.248,0,0,0,0-30.53213Z" transform="translate(-35.5 -118.5)" fill="#3f3d56" />
|
||||
<ellipse cx="1038.00321" cy="460.31783" rx="19.08256" ry="24.9808" fill="#3f3d56" />
|
||||
<ellipse cx="1038.00321" cy="429.78574" rx="19.08256" ry="24.9808" fill="#3f3d56" />
|
||||
<path d="M1144.93871,339.34489a91.61081,91.61081,0,0,0,7.10658-10.46092l-50.141-8.23491,54.22885.4033a91.566,91.566,0,0,0,1.74556-72.42605l-72.75449,37.74139,67.09658-49.32086a91.41255,91.41255,0,1,0-150.971,102.29805,91.45842,91.45842,0,0,0-10.42451,16.66946l65.0866,33.81447-69.40046-23.292a91.46011,91.46011,0,0,0,14.73837,85.83669,91.40575,91.40575,0,1,0,143.68892,0,91.41808,91.41808,0,0,0,0-113.02862Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
|
||||
<path d="M981.6885,395.8592a91.01343,91.01343,0,0,0,19.56129,56.51431,91.40575,91.40575,0,1,0,143.68892,0C1157.18982,436.82067,981.6885,385.60008,981.6885,395.8592Z" transform="translate(-35.5 -118.5)" opacity="0.1" />
|
||||
<path d="M365.62,461.43628H477.094v45.12043H365.62Z" transform="translate(-35.5 -118.5)" fill="#fff" fill-rule="evenodd" />
|
||||
<path d="M264.76252,608.74122a26.50931,26.50931,0,0,1-22.96231-13.27072,26.50976,26.50976,0,0,0,22.96231,39.81215H291.304V608.74122Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
|
||||
<path d="M384.17242,468.57061l92.92155-5.80726V449.49263a26.54091,26.54091,0,0,0-26.54143-26.54143H331.1161l-3.31768-5.74622a3.83043,3.83043,0,0,0-6.63536,0l-3.31768,5.74622-3.31767-5.74622a3.83043,3.83043,0,0,0-6.63536,0l-3.31768,5.74622L301.257,417.205a3.83043,3.83043,0,0,0-6.63536,0L291.304,422.9512c-.02919,0-.05573.004-.08625.004l-5.49674-5.49541a3.8293,3.8293,0,0,0-6.4071,1.71723l-1.81676,6.77338L270.607,424.1031a3.82993,3.82993,0,0,0-4.6912,4.69253l1.84463,6.89148-6.77072,1.81411a3.8315,3.8315,0,0,0-1.71988,6.40975l5.49673,5.49673c0,.02787-.004.05574-.004.08493l-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74621,3.31768L259.0163,466.081a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31767a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31767a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83042,3.83042,0,0,0,0,6.63535l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768L259.0163,558.976a3.83042,3.83042,0,0,0,0,6.63535l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83042,3.83042,0,0,0,0,6.63535l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768A26.54091,26.54091,0,0,0,291.304,635.28265H450.55254A26.5409,26.5409,0,0,0,477.094,608.74122V502.5755l-92.92155-5.80727a14.12639,14.12639,0,0,1,0-28.19762" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
|
||||
<path d="M424.01111,635.28265h39.81214V582.19979H424.01111Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
|
||||
<path d="M490.36468,602.10586a6.60242,6.60242,0,0,0-.848.08493c-.05042-.19906-.09821-.39945-.15393-.59852A6.62668,6.62668,0,1,0,482.80568,590.21q-.2203-.22491-.44457-.44589a6.62391,6.62391,0,1,0-11.39689-6.56369c-.1964-.05575-.39414-.10218-.59056-.15262a6.63957,6.63957,0,1,0-13.10086,0c-.1964.05042-.39414.09687-.59056.15262a6.62767,6.62767,0,1,0-11.39688,6.56369,26.52754,26.52754,0,1,0,44.23127,25.52756,6.6211,6.6211,0,1,0,.848-13.18579" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
|
||||
<path d="M437.28182,555.65836H477.094V529.11693H437.28182Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
|
||||
<path d="M490.36468,545.70532a3.31768,3.31768,0,0,0,0-6.63536,3.41133,3.41133,0,0,0-.42333.04247c-.02655-.09953-.04911-.19907-.077-.29859a3.319,3.319,0,0,0-1.278-6.37923,3.28174,3.28174,0,0,0-2.00122.68742q-.10947-.11346-.22294-.22295a3.282,3.282,0,0,0,.67149-1.98265,3.31768,3.31768,0,0,0-6.37-1.2992,13.27078,13.27078,0,1,0,0,25.54082,3.31768,3.31768,0,0,0,6.37-1.2992,3.282,3.282,0,0,0-.67149-1.98265q.11347-.10947.22294-.22294a3.28174,3.28174,0,0,0,2.00122.68742,3.31768,3.31768,0,0,0,1.278-6.37923c.02786-.0982.05042-.19907.077-.29859a3.41325,3.41325,0,0,0,.42333.04246" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
|
||||
<path d="M317.84538,466.081a3.31768,3.31768,0,0,1-3.31767-3.31768,9.953,9.953,0,1,0-19.90608,0,3.31768,3.31768,0,1,1-6.63535,0,16.58839,16.58839,0,1,1,33.17678,0,3.31768,3.31768,0,0,1-3.31768,3.31768" transform="translate(-35.5 -118.5)" fill-rule="evenodd" />
|
||||
<path d="M370.92825,635.28265h79.62429A26.5409,26.5409,0,0,0,477.094,608.74122v-92.895H397.46968a26.54091,26.54091,0,0,0-26.54143,26.54143Z" transform="translate(-35.5 -118.5)" fill="#ffff50" fill-rule="evenodd" />
|
||||
<path d="M457.21444,556.98543H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.54143H390.80778a1.32707,1.32707,0,1,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.54143H390.80778a1.32707,1.32707,0,1,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0-66.10674H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.29459H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.54143H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414M477.094,474.19076c-.01592,0-.0292-.008-.04512-.00663-4.10064.13934-6.04083,4.24132-7.75274,7.86024-1.78623,3.78215-3.16771,6.24122-5.43171,6.16691-2.50685-.09024-3.94007-2.92222-5.45825-5.91874-1.74377-3.44243-3.73438-7.34667-7.91333-7.20069-4.04227.138-5.98907,3.70784-7.70631,6.857-1.82738,3.35484-3.07084,5.39455-5.46887,5.30033-2.55727-.09289-3.91619-2.39536-5.48877-5.06013-1.75306-2.96733-3.77951-6.30359-7.8775-6.18946-3.97326.13669-5.92537,3.16507-7.64791,5.83912-1.82207,2.82666-3.09872,4.5492-5.52725,4.447-2.61832-.09289-3.9706-2.00388-5.53522-4.21611-1.757-2.4856-3.737-5.299-7.82308-5.16231-3.88567.13271-5.83779,2.61434-7.559,4.80135-1.635,2.07555-2.9116,3.71846-5.61218,3.615a1.32793,1.32793,0,1,0-.09555,2.65414c4.00377.134,6.03154-2.38873,7.79257-4.6275,1.562-1.9853,2.91027-3.69855,5.56441-3.78879,2.55594-.10882,3.75429,1.47968,5.56707,4.04093,1.7212,2.43385,3.67465,5.19416,7.60545,5.33616,4.11789.138,6.09921-2.93946,7.8536-5.66261,1.56861-2.43385,2.92221-4.53461,5.50734-4.62352,2.37944-.08892,3.67466,1.79154,5.50072,4.885,1.72121,2.91557,3.67069,6.21865,7.67977,6.36463,4.14709.14332,6.14965-3.47693,7.89475-6.68181,1.51155-2.77092,2.93814-5.38791,5.46621-5.4755,2.37944-.05573,3.62025,2.11668,5.45558,5.74622,1.71459,3.388,3.65875,7.22591,7.73019,7.37321l.22429.004c4.06614,0,5.99571-4.08074,7.70364-7.68905,1.51154-3.19825,2.94211-6.21069,5.3972-6.33411Z" transform="translate(-35.5 -118.5)" fill-rule="evenodd" />
|
||||
<path d="M344.38682,635.28265h53.08286V582.19979H344.38682Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
|
||||
<path d="M424.01111,602.10586a6.60242,6.60242,0,0,0-.848.08493c-.05042-.19906-.09821-.39945-.15394-.59852A6.62667,6.62667,0,1,0,416.45211,590.21q-.2203-.22491-.44458-.44589a6.62391,6.62391,0,1,0-11.39689-6.56369c-.1964-.05575-.39413-.10218-.59054-.15262a6.63957,6.63957,0,1,0-13.10084,0c-.19641.05042-.39414.09687-.59055.15262a6.62767,6.62767,0,1,0-11.39689,6.56369,26.52755,26.52755,0,1,0,44.2313,25.52756,6.6211,6.6211,0,1,0,.848-13.18579" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
|
||||
<path d="M344.38682,555.65836h53.08286V529.11693H344.38682Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
|
||||
<path d="M410.74039,545.70532a3.31768,3.31768,0,1,0,0-6.63536,3.41133,3.41133,0,0,0-.42333.04247c-.02655-.09953-.04911-.19907-.077-.29859a3.319,3.319,0,0,0-1.278-6.37923,3.28174,3.28174,0,0,0-2.00122.68742q-.10947-.11346-.22294-.22295a3.282,3.282,0,0,0,.67149-1.98265,3.31768,3.31768,0,0,0-6.37-1.2992,13.27078,13.27078,0,1,0,0,25.54082,3.31768,3.31768,0,0,0,6.37-1.2992,3.282,3.282,0,0,0-.67149-1.98265q.11347-.10947.22294-.22294a3.28174,3.28174,0,0,0,2.00122.68742,3.31768,3.31768,0,0,0,1.278-6.37923c.02786-.0982.05042-.19907.077-.29859a3.41325,3.41325,0,0,0,.42333.04246" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
|
||||
<path d="M424.01111,447.8338a3.60349,3.60349,0,0,1-.65028-.06636,3.34415,3.34415,0,0,1-.62372-.18579,3.44679,3.44679,0,0,1-.572-.30522,5.02708,5.02708,0,0,1-.50429-.4114,3.88726,3.88726,0,0,1-.41007-.50428,3.27532,3.27532,0,0,1-.55737-1.84463,3.60248,3.60248,0,0,1,.06636-.65027,3.82638,3.82638,0,0,1,.18447-.62373,3.48858,3.48858,0,0,1,.30656-.57064,3.197,3.197,0,0,1,.91436-.91568,3.44685,3.44685,0,0,1,.572-.30523,3.344,3.344,0,0,1,.62372-.18578,3.06907,3.06907,0,0,1,1.30053,0,3.22332,3.22332,0,0,1,1.19436.491,5.02835,5.02835,0,0,1,.50429.41139,4.8801,4.8801,0,0,1,.41139.50429,3.38246,3.38246,0,0,1,.30522.57064,3.47806,3.47806,0,0,1,.25215,1.274A3.36394,3.36394,0,0,1,426.36,446.865a5.02708,5.02708,0,0,1-.50429.4114,3.3057,3.3057,0,0,1-1.84463.55737m26.54143-1.65884a3.38754,3.38754,0,0,1-2.35024-.96877,5.04185,5.04185,0,0,1-.41007-.50428,3.27532,3.27532,0,0,1-.55737-1.84463,3.38659,3.38659,0,0,1,.96744-2.34892,5.02559,5.02559,0,0,1,.50429-.41139,3.44685,3.44685,0,0,1,.572-.30523,3.3432,3.3432,0,0,1,.62373-.18579,3.06952,3.06952,0,0,1,1.30052,0,3.22356,3.22356,0,0,1,1.19436.491,5.02559,5.02559,0,0,1,.50429.41139,3.38792,3.38792,0,0,1,.96876,2.34892,3.72635,3.72635,0,0,1-.06636.65026,3.37387,3.37387,0,0,1-.18579.62373,4.71469,4.71469,0,0,1-.30522.57064,4.8801,4.8801,0,0,1-.41139.50429,5.02559,5.02559,0,0,1-.50429.41139,3.30547,3.30547,0,0,1-1.84463.55737" transform="translate(-35.5 -118.5)" fill-rule="evenodd" />
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
10
website/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
// This file is not used in compilation. It is here just for a nice editor experience.
|
||||
"extends": "@docusaurus/tsconfig",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"target": "es2022",
|
||||
"allowImportingTsExtensions": true,
|
||||
"strict": true
|
||||
}
|
||||
}
|