├── .npmrc ├── .gitattributes ├── static └── favicon.png ├── .gitignore ├── vite.config.ts ├── .eslintignore ├── .prettierignore ├── .prettierrc ├── src ├── app.html ├── app.d.ts ├── lib │ ├── types │ │ └── spinner.type.ts │ ├── utils.ts │ ├── Circle.svelte │ ├── ScaleOut.svelte │ ├── Firework.svelte │ ├── ArrowDown.svelte │ ├── ArrowUp.svelte │ ├── Square.svelte │ ├── Rainbow.svelte │ ├── Stretch.svelte │ ├── Jumper.svelte │ ├── index.ts │ ├── Clock.svelte │ ├── DoubleBounce.svelte │ ├── Diamonds.svelte │ ├── Pulse.svelte │ ├── Moon.svelte │ ├── RingLoader.svelte │ ├── Wave.svelte │ ├── Jellyfish.svelte │ ├── Chasing.svelte │ ├── Puff.svelte │ ├── SyncLoader.svelte │ ├── SpinLine.svelte │ ├── BarLoader.svelte │ ├── Circle2.svelte │ ├── Shadow.svelte │ ├── Plane.svelte │ ├── Circle3.svelte │ └── GoogleSpin.svelte └── routes │ └── +page.svelte ├── scripts └── patch-package.ts ├── svelte.config.js ├── .eslintrc.cjs ├── tsconfig.json ├── LICENSE ├── package.json └── README.md /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schum123/svelte-loading-spinners/HEAD/static/favicon.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | debug.log 10 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite'; 2 | import type { UserConfig } from 'vite'; 3 | 4 | const config: UserConfig = { 5 | plugins: [sveltekit()] 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | 10 | # Ignore files for PNPM, NPM and YARN 11 | pnpm-lock.yaml 12 | package-lock.json 13 | yarn.lock 14 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | 10 | # Ignore files for PNPM, NPM and YARN 11 | pnpm-lock.yaml 12 | package-lock.json 13 | yarn.lock 14 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "singleQuote": true, 4 | "trailingComma": "none", 5 | "printWidth": 100, 6 | "plugins": ["prettier-plugin-svelte"], 7 | "pluginSearchDirs": ["."], 8 | "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }] 9 | } 10 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/app.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // See https://kit.svelte.dev/docs/types#app 4 | // for information about these interfaces 5 | // and what to do when importing types 6 | declare namespace App { 7 | // interface Locals {} 8 | // interface PageData {} 9 | // interface Error {} 10 | // interface Platform {} 11 | } 12 | -------------------------------------------------------------------------------- /scripts/patch-package.ts: -------------------------------------------------------------------------------- 1 | import { writeFile } from 'node:fs/promises'; 2 | import packageJson from '../package/package.json'; 3 | 4 | const json = { 5 | ...packageJson, 6 | svelte: undefined, 7 | exports: { 8 | ...packageJson.exports, 9 | '.': { 10 | svelte: './index.js', 11 | default: './index.js' 12 | } 13 | } 14 | }; 15 | 16 | await writeFile('package/package.json', JSON.stringify(json, null, 2)); 17 | -------------------------------------------------------------------------------- /svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-auto'; 2 | import preprocess from 'svelte-preprocess'; 3 | 4 | /** @type {import('@sveltejs/kit').Config} */ 5 | const config = { 6 | // Consult https://github.com/sveltejs/svelte-preprocess 7 | // for more information about preprocessors 8 | preprocess: preprocess(), 9 | 10 | kit: { 11 | adapter: adapter() 12 | } 13 | }; 14 | 15 | export default config; 16 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: '@typescript-eslint/parser', 4 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], 5 | plugins: ['svelte3', '@typescript-eslint'], 6 | ignorePatterns: ['*.cjs'], 7 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], 8 | settings: { 9 | 'svelte3/typescript': () => require('typescript') 10 | }, 11 | parserOptions: { 12 | sourceType: 'module', 13 | ecmaVersion: 2020 14 | }, 15 | env: { 16 | browser: true, 17 | es2017: true, 18 | node: true 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /src/lib/types/spinner.type.ts: -------------------------------------------------------------------------------- 1 | export type SpinnerTypes = { 2 | size: string | number; 3 | color: string; 4 | unit: string; 5 | duration: string; 6 | pause: boolean; 7 | }; 8 | 9 | export type Circle2Types = { 10 | colorOuter: string; 11 | colorCenter: string; 12 | colorInner: string; 13 | durationMultiplier: number; 14 | durationOuter: string; 15 | durationInner: string; 16 | durationCenter: string; 17 | } & SpinnerTypes; 18 | 19 | export type Circle3Types = { 20 | ballTopLeft: string; 21 | ballTopRight: string; 22 | ballBottomLeft: string; 23 | ballBottomRight: string; 24 | } & SpinnerTypes; 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true 12 | } 13 | // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias 14 | // 15 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes 16 | // from the referenced tsconfig.json - TypeScript does not merge them in 17 | } 18 | -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | type HEX = string; 2 | 3 | export const durationUnitRegex = /[a-zA-Z]/; 4 | 5 | export const calculateRgba = (color: HEX, opacity: number): string => { 6 | if (color[0] === '#') { 7 | color = color.slice(1); 8 | } 9 | 10 | if (color.length === 3) { 11 | let res = ''; 12 | color.split('').forEach((c: string) => { 13 | res += c; 14 | res += c; 15 | }); 16 | color = res; 17 | } 18 | 19 | const rgbValues = (color.match(/.{2}/g) || []).map((hex: HEX) => parseInt(hex, 16)).join(', '); 20 | 21 | return `rgba(${rgbValues}, ${opacity})`; 22 | }; 23 | 24 | export const range = (size: number, startAt = 0) => [...Array(size).keys()].map((i) => i + startAt); 25 | 26 | // export const characterRange = (startChar, endChar) => 27 | // String.fromCharCode( 28 | // ...range( 29 | // endChar.charCodeAt(0) - startChar.charCodeAt(0), 30 | // startChar.charCodeAt(0) 31 | // ) 32 | // ); 33 | 34 | // export const zip = (arr, ...arrs) => 35 | // arr.map((val, i) => arrs.reduce((list, curr) => [...list, curr[i]], [val])); 36 | -------------------------------------------------------------------------------- /src/lib/Circle.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
15 | 16 | 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 eric 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. 22 | -------------------------------------------------------------------------------- /src/lib/ScaleOut.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
14 |
15 |
16 | 17 | 44 | -------------------------------------------------------------------------------- /src/lib/Firework.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |
12 |
13 | 14 | 47 | -------------------------------------------------------------------------------- /src/lib/ArrowDown.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
15 | 16 | 50 | -------------------------------------------------------------------------------- /src/lib/ArrowUp.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
15 | 16 | 51 | -------------------------------------------------------------------------------- /src/lib/Square.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
15 | 16 | 48 | -------------------------------------------------------------------------------- /src/lib/Rainbow.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |
12 |
13 | 14 | 55 | -------------------------------------------------------------------------------- /src/lib/Stretch.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | {#each range(5, 1) as version} 15 |
20 | {/each} 21 |
22 | 23 | 54 | -------------------------------------------------------------------------------- /src/lib/Jumper.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | {#each range(3, 1) as version} 15 |
20 | {/each} 21 |
22 | 23 | 55 | -------------------------------------------------------------------------------- /src/lib/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Circle } from './Circle.svelte'; 2 | export { default as Circle2 } from './Circle2.svelte'; 3 | export { default as Circle3 } from './Circle3.svelte'; 4 | export { default as DoubleBounce } from './DoubleBounce.svelte'; 5 | export { default as GoogleSpin } from './GoogleSpin.svelte'; 6 | export { default as ScaleOut } from './ScaleOut.svelte'; 7 | export { default as SpinLine } from './SpinLine.svelte'; 8 | export { default as Stretch } from './Stretch.svelte'; 9 | export { default as BarLoader } from './BarLoader.svelte'; 10 | export { default as Jumper } from './Jumper.svelte'; 11 | export { default as RingLoader } from './RingLoader.svelte'; 12 | export { default as SyncLoader } from './SyncLoader.svelte'; 13 | export { default as Rainbow } from './Rainbow.svelte'; 14 | export { default as Firework } from './Firework.svelte'; 15 | export { default as Pulse } from './Pulse.svelte'; 16 | export { default as Jellyfish } from './Jellyfish.svelte'; 17 | export { default as Chasing } from './Chasing.svelte'; 18 | export { default as Square } from './Square.svelte'; 19 | export { default as Shadow } from './Shadow.svelte'; 20 | export { default as Moon } from './Moon.svelte'; 21 | export { default as Plane } from './Plane.svelte'; 22 | export { default as Diamonds } from './Diamonds.svelte'; 23 | export { default as Clock } from './Clock.svelte'; 24 | export { default as Wave } from './Wave.svelte'; 25 | export { default as Puff } from './Puff.svelte'; 26 | export { default as ArrowDown } from './ArrowDown.svelte'; 27 | export { default as ArrowUp } from './ArrowUp.svelte'; 28 | -------------------------------------------------------------------------------- /src/lib/Clock.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
14 | 15 | 57 | -------------------------------------------------------------------------------- /src/lib/DoubleBounce.svelte: -------------------------------------------------------------------------------- 1 | 13 | 14 |
15 | {#each range(2, 1) as version} 16 |
23 | {/each} 24 |
25 | 26 | 57 | -------------------------------------------------------------------------------- /src/lib/Diamonds.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 | 14 |
15 |
16 |
17 | 18 | 19 | 61 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-loading-spinners", 3 | "version": "0.3.6", 4 | "repository": { 5 | "type": "git", 6 | "url": "git+https://github.com/schum123/svelte-loading-spinners.git" 7 | }, 8 | "bugs": { 9 | "url": "https://github.com/schum123/svelte-loading-spinners/issues" 10 | }, 11 | "homepage": "https://github.com/schum123/svelte-loading-spinners#readme", 12 | "description": "Loading spinners using the svelte framework.", 13 | "license": "MIT", 14 | "author": "Eric Schumertl", 15 | "keywords": [ 16 | "svelte" 17 | ], 18 | "scripts": { 19 | "dev": "vite dev", 20 | "build": "svelte-kit sync && svelte-package && npm run patch", 21 | "patch": "npx tsx scripts/patch-package.ts", 22 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 23 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 24 | "lint": "prettier --plugin-search-dir . --check . && eslint .", 25 | "format": "prettier --plugin-search-dir . --write ." 26 | }, 27 | "devDependencies": { 28 | "@sveltejs/adapter-auto": "next", 29 | "@sveltejs/kit": "next", 30 | "@sveltejs/package": "next", 31 | "@types/node": "^20.11.20", 32 | "@typescript-eslint/eslint-plugin": "^5.27.0", 33 | "@typescript-eslint/parser": "^5.27.0", 34 | "eslint": "^8.16.0", 35 | "eslint-config-prettier": "^8.3.0", 36 | "eslint-plugin-svelte3": "^4.0.0", 37 | "prettier": "^2.6.2", 38 | "prettier-plugin-svelte": "^2.7.0", 39 | "svelte": "^3.44.0", 40 | "svelte-check": "^2.7.1", 41 | "svelte-preprocess": "^4.10.6", 42 | "tslib": "^2.3.1", 43 | "typescript": "^4.7.4", 44 | "vite": "^3.1.0" 45 | }, 46 | "type": "module" 47 | } 48 | -------------------------------------------------------------------------------- /src/lib/Pulse.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | {#each range(3, 0) as version} 15 |
22 | {/each} 23 |
24 | 25 | 57 | -------------------------------------------------------------------------------- /src/lib/Moon.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 |
17 |
18 |
19 |
20 | 21 | 58 | -------------------------------------------------------------------------------- /src/lib/RingLoader.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 |
12 | {#each range(2, 1) as version} 13 |
14 | {/each} 15 |
16 | 17 | 64 | -------------------------------------------------------------------------------- /src/lib/Wave.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | {#each range(10, 0) as version} 15 |
21 | {/each} 22 |
23 | 24 | 60 | -------------------------------------------------------------------------------- /src/lib/Jellyfish.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
19 | {#each range(6, 0) as version} 20 |
27 | {/each} 28 |
29 | 30 | 61 | -------------------------------------------------------------------------------- /src/lib/Chasing.svelte: -------------------------------------------------------------------------------- 1 | 13 | 14 |
15 |
16 | {#each range(2, 0) as version} 17 |
24 | {/each} 25 |
26 |
27 | 28 | 70 | -------------------------------------------------------------------------------- /src/lib/Puff.svelte: -------------------------------------------------------------------------------- 1 | 14 | 15 | 19 | {#each range(2, 1) as version} 20 | 27 | {/each} 28 | 29 | 30 | 75 | -------------------------------------------------------------------------------- /src/lib/SyncLoader.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | {#each range(3, 1) as i} 15 |
21 | {/each} 22 |
23 | 24 | 75 | -------------------------------------------------------------------------------- /src/lib/SpinLine.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 |
15 |
16 |
17 | 18 | 94 | -------------------------------------------------------------------------------- /src/lib/BarLoader.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | {#each range(2, 1) as version} 15 |
20 | {/each} 21 |
22 | 23 | 87 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # svelte-loading-spinners 2 | 3 | > collection of loading spinners with Svelte.js 4 | 5 | ## Installation 6 | 7 | ```bash 8 | npm i --save-dev svelte-loading-spinners 9 | ``` 10 | 11 | or 12 | 13 | ```bash 14 | yarn add -D svelte-loading-spinners 15 | ``` 16 | 17 | ## Usage 18 | 19 | Import `navigating` from `$app/stores`. 20 | When navigating starts, it's value is a Navigation object with from, to, type and (if type === 'popstate') delta properties. When navigating finishes, its value reverts to null. 21 | 22 | Read More: [Sveltekit Docs](https://kit.svelte.dev/docs/modules#$app-stores-navigating) and [Stackoverflow](https://stackoverflow.com/questions/70218035/sveltekit-loading-indicator-when-a-page-load-time-threshold-is-exceeded) 23 | 24 | 25 | By using an `{#if $navigating}` this allows us to show the loading animation when the page is loading and stop once it's fully rendered. 26 | 27 | ```svelte 28 | 32 | 33 | {#if $navigating} 34 | 35 | {/if} 36 | ``` 37 | 38 | ## List of available spinners 39 | 40 | Props: `size`, `color`, `unit`, `duration` and `pause`. 41 | The default props; `unit` is `px`, `color` is `#FF3E00` and `size` `60px`. 42 | 43 | Notes: 44 | 45 | `Circle2` instead of the `color` and `duration` props has `colorOuter`, `colorCenter`, `colorInner`, `durationOuter`, `durationCenter`, `durationInner` props. 46 | 47 | `Circle3` has `ballTopLeft`, `ballTopRight`, `ballBottomLeft` and `ballBottomRight` as props aswell. 48 | 49 | | Loaders | 50 | | -----------: | 51 | | BarLoader | 52 | | Chasing | 53 | | Circle | 54 | | Circle2 | 55 | | Circle3 | 56 | | DoubleBounce | 57 | | Firework | 58 | | Jellyfish | 59 | | Jumper | 60 | | Pulse | 61 | | Rainbow | 62 | | RingLoader | 63 | | ScaleOut | 64 | | Shadow | 65 | | SpinLine | 66 | | Stretch | 67 | | SyncLoader | 68 | | Wave | 69 | | Square | 70 | | Moon | 71 | 72 | ## Demo 73 | 74 | List of all spinner: [Demo](https://schum123.github.io/svelte-loading-spinners/) 75 | 76 | ## Development Setup 77 | -------------------------------------------------------------------------------- /src/lib/Circle2.svelte: -------------------------------------------------------------------------------- 1 | 14 | 15 |
20 | 21 | 71 | -------------------------------------------------------------------------------- /src/lib/Shadow.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |
12 |
13 | 14 | 75 | -------------------------------------------------------------------------------- /src/lib/Plane.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | 30 | 131 | -------------------------------------------------------------------------------- /src/lib/Circle3.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
17 |
18 |
19 |
20 |
 
21 |
22 |
23 |
 
24 |
25 |
26 |
 
27 |
28 |
29 |
 
30 |
31 |
32 |
33 |
34 | 35 | 116 | -------------------------------------------------------------------------------- /src/lib/GoogleSpin.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 |
13 | 14 | 221 | -------------------------------------------------------------------------------- /src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 | 41 | 42 |
43 |

svelte-loading-spinners

44 | Github 45 |
46 |
47 | Color: {color} 48 | 49 | 50 |
51 |
52 |
53 | 54 |
Spinline
55 |
56 | 57 |
58 | 59 |
Circle2
60 |
61 |
62 | 63 |
DoubleBounce
64 |
65 |
66 | 67 |
Circle
68 |
69 |
70 | 71 |
Stretch
72 |
73 |
74 | 82 |
Circle3
83 |
84 |
85 | 86 |
BarLoader
87 |
88 |
89 | 90 |
SyncLoader
91 |
92 |
93 | 94 |
Jumper
95 |
96 |
97 | 98 |
GoogleSpin
99 |
100 |
101 | 102 |
ScaleOut
103 |
104 |
105 | 106 |
RingLoader
107 |
108 |
109 | 110 |
Rainbow
111 |
112 |
113 | 114 |
Wave
115 |
116 |
117 | 118 |
Firework
119 |
120 |
121 | 122 |
Pulse
123 |
124 |
125 | 126 |
Jellyfish
127 |
128 |
129 | 130 |
Chasing
131 |
132 |
133 | 134 |
Shadow
135 |
136 |
137 | 138 |
Square
139 |
140 |
141 | 142 |
Moon
143 |
144 |
145 | 146 |
Plane
147 |
148 |
149 | 150 |
Diamonds
151 |
152 |
153 | 154 |
Clock
155 |
156 |
157 | 158 |
Puff
159 |
160 |
161 | 162 |
ArrowDown
163 |
164 |
165 | 166 |
ArrowUp
167 |
168 |
169 | 170 | 236 | --------------------------------------------------------------------------------