├── .github
└── FUNDING.yml
├── .gitignore
├── LICENSE
├── assets
├── loader1.gif
├── loader2.gif
└── loader3.gif
├── index.d.ts
├── package-lock.json
├── package.json
├── readme.md
└── src
├── index.js
└── loader.json
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: vikrantnegi
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: #
10 | issuehunt: #
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/**/*
2 | .expo/*
3 | npm-debug.*
4 | *.jks
5 | *.p12
6 | *.key
7 | *.mobileprovision
8 | .vscode
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Vikrant Negi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/assets/loader1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vikrantnegi/react-native-animated-loader/3098f0faff593cfe11d5938f9be538782414e3cd/assets/loader1.gif
--------------------------------------------------------------------------------
/assets/loader2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vikrantnegi/react-native-animated-loader/3098f0faff593cfe11d5938f9be538782414e3cd/assets/loader2.gif
--------------------------------------------------------------------------------
/assets/loader3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vikrantnegi/react-native-animated-loader/3098f0faff593cfe11d5938f9be538782414e3cd/assets/loader3.gif
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | export type AnimatedLoaderProps = {
2 | /**
3 | * Controls the visibility of the loader.
4 | * @defaultValue false
5 | */
6 | visible?: boolean
7 |
8 | /**
9 | * Changes the color of the overlay.
10 | */
11 | overlayColor?: string
12 |
13 | /**
14 | * The source of animation. Can be referenced as a local asset by a string, or remotely with an object with a uri property, or it can be an actual JS object of an animation, obtained (for example) with something like `require('../path/to/animation.json')`.
15 | */
16 | source: object | string | { uri: string }
17 |
18 | /**
19 | * The speed the animation will progress.
20 | * @defaultValue 1
21 | */
22 | speed?: number
23 |
24 | /**
25 | * A boolean flag indicating whether or not the animation should loop.
26 | * @defaultValue true
27 | */
28 | loop?: boolean
29 |
30 | /**
31 | * Changes animation on show and hide loader's view.
32 | */
33 | animationType?: any
34 |
35 | /**
36 | * The style to be applied to the Lottie.
37 | */
38 | animationStyle?: import('react-native').StyleProp<
39 | import('react-native').ViewStyle
40 | >
41 | }
42 |
43 | export default function AnimatedLoader(
44 | props: AnimatedLoaderProps
45 | ): JSX.Element
46 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-animated-loader",
3 | "version": "1.0.0",
4 | "description": "Useful to show lottie animation spinners in react-native mobile apps",
5 | "main": "src/index.js",
6 | "files": [
7 | "src"
8 | ],
9 | "scripts": {
10 | "test": "echo \"Error: no test specified\" && exit 1"
11 | },
12 | "dependencies": {
13 | "prop-types": "^15.6.2"
14 | },
15 | "peerDependencies": {
16 | "react": "*",
17 | "react-native": ">=0.46",
18 | "lottie-react-native": ">=3.0.0",
19 | "deprecated-react-native-prop-types": "^2.3.0"
20 | },
21 | "author": "Vikrant Negi",
22 | "license": "MIT",
23 | "keywords": [
24 | "react-native",
25 | "react-component",
26 | "react-native-loader",
27 | "lottie-react-native",
28 | "react-native-progress",
29 | "lottie",
30 | "modals",
31 | "loaders",
32 | "animations",
33 | "ios",
34 | "android",
35 | "spinners"
36 | ],
37 | "homepage": "https://github.com/vikrantnegi/react-native-animated-loader",
38 | "bugs": {
39 | "url": "https://github.com/vikrantnegi/react-native-animated-loader/issues"
40 | },
41 | "repository": {
42 | "type": "git",
43 | "url": "https://github.com/vikrantnegi/react-native-animated-loader.git"
44 | }
45 | }
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # React Native Animated Loader
2 |
3 | Read more about this package [here](https://www.freecodecamp.org/news/how-to-create-a-beautifully-animated-loader-in-react-native-21da37a8f6b0/).
4 |
5 | [](http://npm-stats.com/~packages/react-native-animated-loader)
6 | [](https://www.npmjs.com/package/react-native-animated-loader)
7 | [](https://github.com/vikrantnegi/react-native-animated-loader/)
8 | [](https://yarnpkg.com/en/package/react-native-animated-loader)
9 |
10 | A React Native Loader Component which uses Airbnb's [Lottie](https://github.com/react-native-community/lottie-react-native) for beautiful loader animations.
11 |
12 |
13 |
14 |
15 |
16 |
17 | ## Prerequisites
18 | ### Using React Native CLI
19 | This library uses [lottie-react-native](https://github.com/react-native-community/lottie-react-native) to render loader animations. Therefore this library need to be installed and linked to your project before installing this package.
20 |
21 | Follow the official instruction and linking guide [here](https://github.com/react-native-community/lottie-react-native/blob/master/README.md#getting-started).
22 |
23 | ### Using Expo
24 | No need to do anything specific, just install the package itself. Expo already has Lottie library API available and it will take care of the rest.
25 |
26 | ## Install
27 |
28 | ```
29 | yarn add react-native-animated-loader
30 | ```
31 | or
32 | ```
33 | npm install react-native-animated-loader --save
34 | ```
35 |
36 | ## Usage
37 | ### Class Component
38 | ```jsx
39 | import React from 'react';
40 | import { StyleSheet,Text } from 'react-native';
41 | import AnimatedLoader from "react-native-animated-loader";
42 |
43 | export default class Loader extends React.Component {
44 | constructor(props) {
45 | super(props);
46 | this.state = { visible: false };
47 | }
48 |
49 | componentDidMount() {
50 | setInterval(() => {
51 | this.setState({
52 | visible: !this.state.visible
53 | });
54 | }, 2000);
55 | }
56 |
57 | render() {
58 | const { visible } = this.state;
59 | return (
60 |
67 | Doing something...
68 |
69 | );
70 | }
71 | }
72 |
73 | const styles = StyleSheet.create({
74 | lottie: {
75 | width: 100,
76 | height: 100
77 | }
78 | });
79 | ```
80 | ### Functional Component
81 |
82 | ```jsx
83 | import React, {useState, useEffect} from 'react';
84 | import {StyleSheet, Text} from 'react-native';
85 | import AnimatedLoader from 'react-native-animated-loader';
86 | export default function App() {
87 | const [visible, setVisible] = useState(false);
88 | useEffect(() => {
89 | setInterval(() => {
90 | setVisible(!visible);
91 | }, 2000);
92 | }, []);
93 |
94 | return (
95 |
100 | Doing something...
101 |
102 | );
103 | }
104 | const styles = StyleSheet.create({
105 | lottie: {
106 | width: 100,
107 | height: 100,
108 | },
109 | });
110 |
111 | ```
112 |
113 | ### Usage in Expo
114 | [Example for expo projects](https://snack.expo.dev/tTSGEcb5J)
115 |
116 | ### Loader files
117 |
118 | You can find free lottie files for your loaders [here](https://lottiefiles.com/search?q=loader).
119 |
120 | ## Props
121 |
122 | | Prop | Description | Default |
123 | |---|---|---|
124 | |**`source`**| The source of animation. Can be referenced as a local asset by a string, or remotely with an object with a `uri` property, or it can be an actual JS object of an animation, obtained (for example) with something like `require('../path/to/animation.json')`. | [Lottie Object](https://lottiefiles.com/1531-loader) |
125 | |**`visible`**| Controls the visibility of the loader. | `false` |
126 | |**`overlayColor`**| Changes the color of the overlay. | `rgba(255,255,255,0.75)` |
127 | |**`animationStyle`**| The style to be applied to the Lottie. | - |
128 | |**`animationType`**| Changes animation on show and hide loader's view. | `none` |
129 | |**`speed`**| The speed the animation will progress. | `1` |
130 | |**`loop`**| A boolean flag indicating whether or not the animation should loop. | `true` |
131 |
132 | ## Work in Progress
133 | - [x] Add expo example
134 | - [ ] Add ability to render text with animations
135 | - [ ] Add test cases
136 |
137 | ## License
138 | Licensed under the [MIT](https://github.com/vikrantnegi/react-native-animated-loader/blob/master/LICENSE).
139 |
140 | ## Donation
141 | If this project helped you reduce time to develop, please consider buying me a cup of coffee :)
142 |
143 |
144 |
145 | [](https://ko-fi.com/E1E6Z0JL)
146 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { StyleSheet, View, Modal } from 'react-native';
3 | import PropTypes from 'prop-types';
4 | import LottieAnimation from 'lottie-react-native';
5 | import { ViewPropTypes } from 'deprecated-react-native-prop-types';
6 |
7 | export default class AnimatedLoader extends React.PureComponent {
8 | static defaultProps = {
9 | visible: false,
10 | overlayColor: 'rgba(0, 0, 0, 0.25)',
11 | animationType: 'none',
12 | source: require('./loader.json'),
13 | animationStyle: {},
14 | speed: 1,
15 | loop: true,
16 | };
17 |
18 | static propTypes = {
19 | visible: PropTypes.bool,
20 | overlayColor: PropTypes.string,
21 | animationType: PropTypes.oneOf(['none', 'slide', 'fade']),
22 | source: PropTypes.object,
23 | animationStyle: ViewPropTypes.style,
24 | speed: PropTypes.number,
25 | loop: PropTypes.bool,
26 | };
27 |
28 | animation = React.createRef();
29 |
30 | componentDidMount() {
31 | if (this.animation.current) {
32 | this.animation.current.play();
33 | }
34 | }
35 |
36 | componentDidUpdate(prevProps) {
37 | const { visible } = this.props;
38 | if (visible !== prevProps.visible) {
39 | if (this.animation.current) {
40 | this.animation.current.play();
41 | }
42 | }
43 | }
44 |
45 | _renderLottie = () => {
46 | const { source, animationStyle, speed, loop } = this.props;
47 | return (
48 |
55 | );
56 | };
57 |
58 | render() {
59 | const { visible, overlayColor, animationType } = this.props;
60 |
61 | return (
62 | {}}
68 | >
69 |
70 | {this._renderLottie()}
71 | {this.props.children}
72 |
73 |
74 | );
75 | }
76 | }
77 |
78 | const styles = StyleSheet.create({
79 | container: {
80 | flex: 1,
81 | backgroundColor: 'transparent',
82 | position: 'absolute',
83 | top: 0,
84 | bottom: 0,
85 | left: 0,
86 | right: 0,
87 | alignItems: 'center',
88 | justifyContent: 'center',
89 | },
90 | animationStyle: {
91 | height: '100%',
92 | width: '100%',
93 | },
94 | });
95 |
--------------------------------------------------------------------------------
/src/loader.json:
--------------------------------------------------------------------------------
1 | {"v":"5.1.7","fr":30,"ip":0,"op":50,"w":80,"h":80,"nm":"loader","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"color01b","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[40,40,0],"ix":2},"a":{"a":0,"k":[-19,-8.286,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":30,"s":[0,0,100],"e":[100,100,100]},{"t":50}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[80,80],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.266666995778,0.266666995778,0.266666995778,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.294117647059,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-19,-8.286],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":50,"st":30,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"color01a","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":25,"s":[100],"e":[0]},{"t":45}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[40,40,0],"ix":2},"a":{"a":0,"k":[-19,-8.286,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":25,"s":[0,0,100],"e":[100,100,100]},{"t":45}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[80,80],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.266666995778,0.266666995778,0.266666995778,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.294117647059,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-19,-8.286],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":25,"op":50,"st":25,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"color01","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[40,40,0],"ix":2},"a":{"a":0,"k":[-19,-8.286,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":0,"s":[100,100,100],"e":[0,0,100]},{"t":20}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[80,80],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.266666995778,0.266666995778,0.266666995778,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.294117647059,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-19,-8.286],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"color02","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[40,40,0],"ix":2},"a":{"a":0,"k":[-19,-8.286,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":5,"s":[100,100,100],"e":[0,0,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[80,80],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.266666995778,0.266666995778,0.266666995778,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.380392156863,0.298039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-19,-8.286],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"color03","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[40,40,0],"ix":2},"a":{"a":0,"k":[-19,-8.286,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":10,"s":[100,100,100],"e":[10,10,100]},{"t":30}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[80,80],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.266666995778,0.266666995778,0.266666995778,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.513725490196,0.450980392157,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-19,-8.286],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0}],"markers":[]}
--------------------------------------------------------------------------------