├── .eslintrc.js ├── .expo-shared └── assets.json ├── .gitignore ├── .prettierrc.js ├── .vscode └── settings.json ├── App.test.tsx ├── App.tsx ├── README.md ├── app.json ├── assets ├── adaptive-icon.png ├── favicon.png ├── icon.png └── splash.png ├── babel.config.js ├── jest.config.js ├── package.json ├── patches └── @metascraper+helpers+5.22.8.patch ├── plan.txt ├── proxy-server ├── package-lock.json ├── package.json ├── proxy.js ├── yarn-error.log └── yarn.lock ├── src ├── Components │ ├── Button.tsx │ ├── Center.tsx │ ├── CreateTweet.tsx │ ├── Foldable.tsx │ ├── Post.tsx │ ├── RightBar.tsx │ ├── SearchBar.tsx │ ├── SideBar.tsx │ └── SideBarItem.tsx ├── assets │ └── SVGs │ │ ├── Bell.tsx │ │ ├── Book.tsx │ │ ├── Calender.tsx │ │ ├── Comment.tsx │ │ ├── Feather.tsx │ │ ├── Flag.tsx │ │ ├── GifSvg.tsx │ │ ├── HappyFace.tsx │ │ ├── Home.tsx │ │ ├── HyperLinkIcon.tsx │ │ ├── ImageSvg.tsx │ │ ├── Love.tsx │ │ ├── Message.tsx │ │ ├── Profile.tsx │ │ ├── Retweet.tsx │ │ ├── Search.tsx │ │ ├── Share.tsx │ │ ├── SleepingChart.tsx │ │ ├── Star.tsx │ │ ├── ThreeDots.tsx │ │ └── Twitter.tsx ├── store │ └── store.ts └── styles │ └── colors.ts ├── tsconfig.json ├── yarn-error.log └── yarn.lock /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: ['react', 'react-native', 'react-hooks', '@typescript-eslint'], 3 | parser: '@typescript-eslint/parser', 4 | root: true, 5 | extends: ['@react-native-community', 'prettier'], 6 | rules: { 7 | // 'no-semi': 1, 8 | 'react-hooks/rules-of-hooks': 'error', 9 | 'react-hooks/exhaustive-deps': 'warn', 10 | 'react-native/no-unused-styles': 1, 11 | 'react-native/split-platform-components': 2, 12 | 'react-native/no-inline-styles': 3, 13 | 'react-native/no-color-literals': 1, 14 | 'react-native/no-raw-text': 1, 15 | 'react-native/no-single-element-style-arrays': 2, 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /.expo-shared/assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true, 3 | "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .expo/ 3 | npm-debug.* 4 | *.jks 5 | *.p8 6 | *.p12 7 | *.key 8 | *.mobileprovision 9 | *.orig.* 10 | web-build/ 11 | .vscode 12 | 13 | # macOS 14 | .DS_Store 15 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: false, 3 | jsxBracketSameLine: true, 4 | singleQuote: true, 5 | trailingComma: 'all', 6 | semi: false 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "launch": { 3 | "configurations": [], 4 | "compounds": [] 5 | }, 6 | "cSpell.words": [ 7 | "metascraper" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import renderer from 'react-test-renderer' 3 | import App from './App' 4 | // snapshot test 5 | it('renders correctly', () => { 6 | const tree = renderer.create().toJSON() 7 | expect(tree).toMatchSnapshot() 8 | }) 9 | -------------------------------------------------------------------------------- /App.tsx: -------------------------------------------------------------------------------- 1 | import '@expo/match-media' 2 | import {StatusBar} from 'expo-status-bar' 3 | import React from 'react' 4 | import {StyleSheet, Text, View} from 'react-native' 5 | import {SideBar} from './src/Components/SideBar' 6 | import {Center} from './src/Components/Center' 7 | import {RightBar} from './src/Components/RightBar' 8 | import {colors} from './src/styles/colors' 9 | // TODO: fix all inline styles 10 | export default function App() { 11 | return ( 12 | 13 | 14 |
15 | 16 | 17 | 18 | ) 19 | } 20 | 21 | const styles = StyleSheet.create({ 22 | container: { 23 | // flex: 1, 24 | backgroundColor: colors.COLOR_BACKGROUND_TWITTER, 25 | // alignItems: 'center', 26 | justifyContent: 'space-between', 27 | flexDirection: 'row', 28 | }, 29 | }) 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## React Native Expo Responsive twitter clone 4 | ## 🦺 work in progress .... 5 | 6 | ## TODO 7 | - [ ] remove all inline styles and use @callstack/react-themeprovider 8 | - [ ] migrate to react-navigation 9 | - [ ] implement other pages 10 | 11 | ## How to run 12 | 13 | install packages in the root and `proxy-server` folder 14 | and then run both expo and proxy-server 15 | ```bash 16 | yarn & yarn start 17 | ``` 18 | and 19 | ```bash 20 | cd proxy-server & yarn & yarn start 21 | ``` 22 | 23 | 24 | ### Responsive UI 25 | 26 | ![Screen Shot 1400-05-05 at 11 55 15 AM](https://user-images.githubusercontent.com/46188784/127113413-8eebd5a0-7301-4ece-b2aa-fdc8aa5ac6ea.png) 27 | ![Screen Shot 2021-06-20 at 12 20 16 AM](https://user-images.githubusercontent.com/46188784/122653960-8f396880-d15d-11eb-8fb0-738726bf198f.png) 28 | ![Screen Shot 2021-06-20 at 12 20 45 AM](https://user-images.githubusercontent.com/46188784/122653965-9a8c9400-d15d-11eb-82a0-10a890148f90.png) 29 | 30 | 31 | ### How to reach me 32 | 33 | #### twitter: [TheEhsanSarshar](https://twitter.com/TheEhsanSarshar) 34 | #### Email: ehsan.herai@gmail.com 35 | #### `I'm available for freelancing or Remote contract jobs` 36 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "twitter", 4 | "slug": "twitter", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/icon.png", 8 | "splash": { 9 | "image": "./assets/splash.png", 10 | "resizeMode": "contain", 11 | "backgroundColor": "#ffffff" 12 | }, 13 | "updates": { 14 | "fallbackToCacheTimeout": 0 15 | }, 16 | "assetBundlePatterns": [ 17 | "**/*" 18 | ], 19 | "ios": { 20 | "supportsTablet": true 21 | }, 22 | "android": { 23 | "adaptiveIcon": { 24 | "foregroundImage": "./assets/adaptive-icon.png", 25 | "backgroundColor": "#FFFFFF" 26 | } 27 | }, 28 | "web": { 29 | "favicon": "./assets/favicon.png" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/byteab/Twitter-React-Native/2b6b45fbe2c6476d1a0c734fb390bda0f6613489/assets/adaptive-icon.png -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/byteab/Twitter-React-Native/2b6b45fbe2c6476d1a0c734fb390bda0f6613489/assets/favicon.png -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/byteab/Twitter-React-Native/2b6b45fbe2c6476d1a0c734fb390bda0f6613489/assets/icon.png -------------------------------------------------------------------------------- /assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/byteab/Twitter-React-Native/2b6b45fbe2c6476d1a0c734fb390bda0f6613489/assets/splash.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | verbose: true, 3 | preset: 'jest-expo', 4 | transformIgnorePatterns: [ 5 | 'node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|@sentry/.*)', 6 | ], 7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], 8 | transform: { 9 | '^.+\\.tsx?$': 'ts-jest', 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "web": "expo start --web", 8 | "eject": "expo eject", 9 | "test": "jest --config ./jest.config.js --watchAll" 10 | }, 11 | "dependencies": { 12 | "@expo/match-media": "^0.1.0", 13 | "@react-native-community/eslint-config": "^2.0.0", 14 | "expo": "~41.0.1", 15 | "expo-status-bar": "~1.0.4", 16 | "get-urls": "^10.0.0", 17 | "react": "16.13.1", 18 | "react-dom": "16.13.1", 19 | "react-native": "https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz", 20 | "react-native-responsive-screen": "^1.4.2", 21 | "react-native-svg": "12.1.0", 22 | "react-native-web": "~0.13.12", 23 | "react-native-web-hover": "^0.2.9", 24 | "react-responsive": "^8.2.0", 25 | "zustand": "^3.5.7" 26 | }, 27 | "devDependencies": { 28 | "@babel/core": "^7.9.0", 29 | "@testing-library/react-native": "^7.2.0", 30 | "@types/jest": "^26.0.24", 31 | "@types/react": "~16.9.35", 32 | "@types/react-native": "~0.63.2", 33 | "@types/react-responsive": "^8.0.2", 34 | "@types/react-test-renderer": "^17.0.1", 35 | "@typescript-eslint/eslint-plugin": "^4.26.0", 36 | "@typescript-eslint/parser": "^4.26.0", 37 | "eslint": "^7.28.0", 38 | "eslint-config-prettier": "^8.3.0", 39 | "eslint-plugin-import": "^2.22.1", 40 | "eslint-plugin-prettier": "^3.4.0", 41 | "eslint-plugin-react": "^7.24.0", 42 | "eslint-plugin-react-hooks": "^4.2.0", 43 | "eslint-plugin-react-native": "^3.11.0", 44 | "jest-expo": "^42.0.1", 45 | "patch-package": "^6.4.7", 46 | "prettier": "^2.3.1", 47 | "react-test-renderer": "^17.0.2", 48 | "ts-node": "^10.1.0", 49 | "typescript": "~4.0.0" 50 | }, 51 | "private": true 52 | } 53 | -------------------------------------------------------------------------------- /patches/@metascraper+helpers+5.22.8.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/@metascraper/helpers/index.js b/node_modules/@metascraper/helpers/index.js 2 | index f3642ce..e6ad717 100644 3 | --- a/node_modules/@metascraper/helpers/index.js 4 | +++ b/node_modules/@metascraper/helpers/index.js 5 | @@ -29,7 +29,7 @@ const fileExtension = require('file-extension') 6 | const _normalizeUrl = require('normalize-url') 7 | const smartquotes = require('smartquotes') 8 | const { decodeHTML } = require('entities') 9 | -const memoizeOne = require('memoize-one') 10 | +const memoizeOne = require('memoize-one').default 11 | const mimeTypes = require('mime-types') 12 | const hasValues = require('has-values') 13 | const chrono = require('chrono-node') 14 | -------------------------------------------------------------------------------- /plan.txt: -------------------------------------------------------------------------------- 1 | use get-url package 2 | use metascraper package for getting metadata -------------------------------------------------------------------------------- /proxy-server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "proxy-server", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.7", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 11 | "requires": { 12 | "mime-types": "~2.1.24", 13 | "negotiator": "0.6.2" 14 | } 15 | }, 16 | "ajv": { 17 | "version": "6.12.6", 18 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 19 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 20 | "requires": { 21 | "fast-deep-equal": "^3.1.1", 22 | "fast-json-stable-stringify": "^2.0.0", 23 | "json-schema-traverse": "^0.4.1", 24 | "uri-js": "^4.2.2" 25 | } 26 | }, 27 | "array-flatten": { 28 | "version": "1.1.1", 29 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 30 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 31 | }, 32 | "asn1": { 33 | "version": "0.2.4", 34 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 35 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 36 | "requires": { 37 | "safer-buffer": "~2.1.0" 38 | } 39 | }, 40 | "assert-plus": { 41 | "version": "1.0.0", 42 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 43 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 44 | }, 45 | "asynckit": { 46 | "version": "0.4.0", 47 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 48 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 49 | }, 50 | "aws-sign2": { 51 | "version": "0.7.0", 52 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 53 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 54 | }, 55 | "aws4": { 56 | "version": "1.11.0", 57 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", 58 | "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" 59 | }, 60 | "bcrypt-pbkdf": { 61 | "version": "1.0.2", 62 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 63 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 64 | "requires": { 65 | "tweetnacl": "^0.14.3" 66 | } 67 | }, 68 | "body-parser": { 69 | "version": "1.19.0", 70 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 71 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 72 | "requires": { 73 | "bytes": "3.1.0", 74 | "content-type": "~1.0.4", 75 | "debug": "2.6.9", 76 | "depd": "~1.1.2", 77 | "http-errors": "1.7.2", 78 | "iconv-lite": "0.4.24", 79 | "on-finished": "~2.3.0", 80 | "qs": "6.7.0", 81 | "raw-body": "2.4.0", 82 | "type-is": "~1.6.17" 83 | } 84 | }, 85 | "bytes": { 86 | "version": "3.1.0", 87 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 88 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 89 | }, 90 | "caseless": { 91 | "version": "0.12.0", 92 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 93 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 94 | }, 95 | "combined-stream": { 96 | "version": "1.0.8", 97 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 98 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 99 | "requires": { 100 | "delayed-stream": "~1.0.0" 101 | } 102 | }, 103 | "content-disposition": { 104 | "version": "0.5.3", 105 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 106 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 107 | "requires": { 108 | "safe-buffer": "5.1.2" 109 | } 110 | }, 111 | "content-type": { 112 | "version": "1.0.4", 113 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 114 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 115 | }, 116 | "cookie": { 117 | "version": "0.4.0", 118 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 119 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 120 | }, 121 | "cookie-signature": { 122 | "version": "1.0.6", 123 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 124 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 125 | }, 126 | "core-util-is": { 127 | "version": "1.0.2", 128 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 129 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 130 | }, 131 | "dashdash": { 132 | "version": "1.14.1", 133 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 134 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 135 | "requires": { 136 | "assert-plus": "^1.0.0" 137 | } 138 | }, 139 | "debug": { 140 | "version": "2.6.9", 141 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 142 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 143 | "requires": { 144 | "ms": "2.0.0" 145 | } 146 | }, 147 | "delayed-stream": { 148 | "version": "1.0.0", 149 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 150 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 151 | }, 152 | "depd": { 153 | "version": "1.1.2", 154 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 155 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 156 | }, 157 | "destroy": { 158 | "version": "1.0.4", 159 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 160 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 161 | }, 162 | "ecc-jsbn": { 163 | "version": "0.1.2", 164 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 165 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 166 | "requires": { 167 | "jsbn": "~0.1.0", 168 | "safer-buffer": "^2.1.0" 169 | } 170 | }, 171 | "ee-first": { 172 | "version": "1.1.1", 173 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 174 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 175 | }, 176 | "encodeurl": { 177 | "version": "1.0.2", 178 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 179 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 180 | }, 181 | "escape-html": { 182 | "version": "1.0.3", 183 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 184 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 185 | }, 186 | "etag": { 187 | "version": "1.8.1", 188 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 189 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 190 | }, 191 | "express": { 192 | "version": "4.17.1", 193 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 194 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 195 | "requires": { 196 | "accepts": "~1.3.7", 197 | "array-flatten": "1.1.1", 198 | "body-parser": "1.19.0", 199 | "content-disposition": "0.5.3", 200 | "content-type": "~1.0.4", 201 | "cookie": "0.4.0", 202 | "cookie-signature": "1.0.6", 203 | "debug": "2.6.9", 204 | "depd": "~1.1.2", 205 | "encodeurl": "~1.0.2", 206 | "escape-html": "~1.0.3", 207 | "etag": "~1.8.1", 208 | "finalhandler": "~1.1.2", 209 | "fresh": "0.5.2", 210 | "merge-descriptors": "1.0.1", 211 | "methods": "~1.1.2", 212 | "on-finished": "~2.3.0", 213 | "parseurl": "~1.3.3", 214 | "path-to-regexp": "0.1.7", 215 | "proxy-addr": "~2.0.5", 216 | "qs": "6.7.0", 217 | "range-parser": "~1.2.1", 218 | "safe-buffer": "5.1.2", 219 | "send": "0.17.1", 220 | "serve-static": "1.14.1", 221 | "setprototypeof": "1.1.1", 222 | "statuses": "~1.5.0", 223 | "type-is": "~1.6.18", 224 | "utils-merge": "1.0.1", 225 | "vary": "~1.1.2" 226 | } 227 | }, 228 | "extend": { 229 | "version": "3.0.2", 230 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 231 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 232 | }, 233 | "extsprintf": { 234 | "version": "1.3.0", 235 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 236 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 237 | }, 238 | "fast-deep-equal": { 239 | "version": "3.1.3", 240 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 241 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" 242 | }, 243 | "fast-json-stable-stringify": { 244 | "version": "2.1.0", 245 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 246 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" 247 | }, 248 | "finalhandler": { 249 | "version": "1.1.2", 250 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 251 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 252 | "requires": { 253 | "debug": "2.6.9", 254 | "encodeurl": "~1.0.2", 255 | "escape-html": "~1.0.3", 256 | "on-finished": "~2.3.0", 257 | "parseurl": "~1.3.3", 258 | "statuses": "~1.5.0", 259 | "unpipe": "~1.0.0" 260 | } 261 | }, 262 | "forever-agent": { 263 | "version": "0.6.1", 264 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 265 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 266 | }, 267 | "form-data": { 268 | "version": "2.3.3", 269 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 270 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 271 | "requires": { 272 | "asynckit": "^0.4.0", 273 | "combined-stream": "^1.0.6", 274 | "mime-types": "^2.1.12" 275 | } 276 | }, 277 | "forwarded": { 278 | "version": "0.2.0", 279 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 280 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 281 | }, 282 | "fresh": { 283 | "version": "0.5.2", 284 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 285 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 286 | }, 287 | "getpass": { 288 | "version": "0.1.7", 289 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 290 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 291 | "requires": { 292 | "assert-plus": "^1.0.0" 293 | } 294 | }, 295 | "har-schema": { 296 | "version": "2.0.0", 297 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 298 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 299 | }, 300 | "har-validator": { 301 | "version": "5.1.5", 302 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", 303 | "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", 304 | "requires": { 305 | "ajv": "^6.12.3", 306 | "har-schema": "^2.0.0" 307 | } 308 | }, 309 | "http-errors": { 310 | "version": "1.7.2", 311 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 312 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 313 | "requires": { 314 | "depd": "~1.1.2", 315 | "inherits": "2.0.3", 316 | "setprototypeof": "1.1.1", 317 | "statuses": ">= 1.5.0 < 2", 318 | "toidentifier": "1.0.0" 319 | } 320 | }, 321 | "http-signature": { 322 | "version": "1.2.0", 323 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 324 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 325 | "requires": { 326 | "assert-plus": "^1.0.0", 327 | "jsprim": "^1.2.2", 328 | "sshpk": "^1.7.0" 329 | } 330 | }, 331 | "iconv-lite": { 332 | "version": "0.4.24", 333 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 334 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 335 | "requires": { 336 | "safer-buffer": ">= 2.1.2 < 3" 337 | } 338 | }, 339 | "inherits": { 340 | "version": "2.0.3", 341 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 342 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 343 | }, 344 | "ipaddr.js": { 345 | "version": "1.9.1", 346 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 347 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 348 | }, 349 | "is-typedarray": { 350 | "version": "1.0.0", 351 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 352 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 353 | }, 354 | "isstream": { 355 | "version": "0.1.2", 356 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 357 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 358 | }, 359 | "jsbn": { 360 | "version": "0.1.1", 361 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 362 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 363 | }, 364 | "json-schema": { 365 | "version": "0.2.3", 366 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 367 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 368 | }, 369 | "json-schema-traverse": { 370 | "version": "0.4.1", 371 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 372 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 373 | }, 374 | "json-stringify-safe": { 375 | "version": "5.0.1", 376 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 377 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 378 | }, 379 | "jsprim": { 380 | "version": "1.4.1", 381 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 382 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 383 | "requires": { 384 | "assert-plus": "1.0.0", 385 | "extsprintf": "1.3.0", 386 | "json-schema": "0.2.3", 387 | "verror": "1.10.0" 388 | } 389 | }, 390 | "media-typer": { 391 | "version": "0.3.0", 392 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 393 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 394 | }, 395 | "merge-descriptors": { 396 | "version": "1.0.1", 397 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 398 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 399 | }, 400 | "methods": { 401 | "version": "1.1.2", 402 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 403 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 404 | }, 405 | "mime": { 406 | "version": "1.6.0", 407 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 408 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 409 | }, 410 | "mime-db": { 411 | "version": "1.48.0", 412 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", 413 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" 414 | }, 415 | "mime-types": { 416 | "version": "2.1.31", 417 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", 418 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", 419 | "requires": { 420 | "mime-db": "1.48.0" 421 | } 422 | }, 423 | "ms": { 424 | "version": "2.0.0", 425 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 426 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 427 | }, 428 | "negotiator": { 429 | "version": "0.6.2", 430 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 431 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 432 | }, 433 | "oauth-sign": { 434 | "version": "0.9.0", 435 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 436 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 437 | }, 438 | "on-finished": { 439 | "version": "2.3.0", 440 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 441 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 442 | "requires": { 443 | "ee-first": "1.1.1" 444 | } 445 | }, 446 | "parseurl": { 447 | "version": "1.3.3", 448 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 449 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 450 | }, 451 | "path-to-regexp": { 452 | "version": "0.1.7", 453 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 454 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 455 | }, 456 | "performance-now": { 457 | "version": "2.1.0", 458 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 459 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 460 | }, 461 | "proxy-addr": { 462 | "version": "2.0.7", 463 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 464 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 465 | "requires": { 466 | "forwarded": "0.2.0", 467 | "ipaddr.js": "1.9.1" 468 | } 469 | }, 470 | "psl": { 471 | "version": "1.8.0", 472 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", 473 | "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" 474 | }, 475 | "punycode": { 476 | "version": "2.1.1", 477 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 478 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 479 | }, 480 | "qs": { 481 | "version": "6.7.0", 482 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 483 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 484 | }, 485 | "range-parser": { 486 | "version": "1.2.1", 487 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 488 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 489 | }, 490 | "raw-body": { 491 | "version": "2.4.0", 492 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 493 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 494 | "requires": { 495 | "bytes": "3.1.0", 496 | "http-errors": "1.7.2", 497 | "iconv-lite": "0.4.24", 498 | "unpipe": "1.0.0" 499 | } 500 | }, 501 | "request": { 502 | "version": "2.88.2", 503 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", 504 | "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", 505 | "requires": { 506 | "aws-sign2": "~0.7.0", 507 | "aws4": "^1.8.0", 508 | "caseless": "~0.12.0", 509 | "combined-stream": "~1.0.6", 510 | "extend": "~3.0.2", 511 | "forever-agent": "~0.6.1", 512 | "form-data": "~2.3.2", 513 | "har-validator": "~5.1.3", 514 | "http-signature": "~1.2.0", 515 | "is-typedarray": "~1.0.0", 516 | "isstream": "~0.1.2", 517 | "json-stringify-safe": "~5.0.1", 518 | "mime-types": "~2.1.19", 519 | "oauth-sign": "~0.9.0", 520 | "performance-now": "^2.1.0", 521 | "qs": "~6.5.2", 522 | "safe-buffer": "^5.1.2", 523 | "tough-cookie": "~2.5.0", 524 | "tunnel-agent": "^0.6.0", 525 | "uuid": "^3.3.2" 526 | }, 527 | "dependencies": { 528 | "qs": { 529 | "version": "6.5.2", 530 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 531 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 532 | } 533 | } 534 | }, 535 | "safe-buffer": { 536 | "version": "5.1.2", 537 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 538 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 539 | }, 540 | "safer-buffer": { 541 | "version": "2.1.2", 542 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 543 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 544 | }, 545 | "send": { 546 | "version": "0.17.1", 547 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 548 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 549 | "requires": { 550 | "debug": "2.6.9", 551 | "depd": "~1.1.2", 552 | "destroy": "~1.0.4", 553 | "encodeurl": "~1.0.2", 554 | "escape-html": "~1.0.3", 555 | "etag": "~1.8.1", 556 | "fresh": "0.5.2", 557 | "http-errors": "~1.7.2", 558 | "mime": "1.6.0", 559 | "ms": "2.1.1", 560 | "on-finished": "~2.3.0", 561 | "range-parser": "~1.2.1", 562 | "statuses": "~1.5.0" 563 | }, 564 | "dependencies": { 565 | "ms": { 566 | "version": "2.1.1", 567 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 568 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 569 | } 570 | } 571 | }, 572 | "serve-static": { 573 | "version": "1.14.1", 574 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 575 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 576 | "requires": { 577 | "encodeurl": "~1.0.2", 578 | "escape-html": "~1.0.3", 579 | "parseurl": "~1.3.3", 580 | "send": "0.17.1" 581 | } 582 | }, 583 | "setprototypeof": { 584 | "version": "1.1.1", 585 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 586 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 587 | }, 588 | "sshpk": { 589 | "version": "1.16.1", 590 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 591 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 592 | "requires": { 593 | "asn1": "~0.2.3", 594 | "assert-plus": "^1.0.0", 595 | "bcrypt-pbkdf": "^1.0.0", 596 | "dashdash": "^1.12.0", 597 | "ecc-jsbn": "~0.1.1", 598 | "getpass": "^0.1.1", 599 | "jsbn": "~0.1.0", 600 | "safer-buffer": "^2.0.2", 601 | "tweetnacl": "~0.14.0" 602 | } 603 | }, 604 | "statuses": { 605 | "version": "1.5.0", 606 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 607 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 608 | }, 609 | "toidentifier": { 610 | "version": "1.0.0", 611 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 612 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 613 | }, 614 | "tough-cookie": { 615 | "version": "2.5.0", 616 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", 617 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", 618 | "requires": { 619 | "psl": "^1.1.28", 620 | "punycode": "^2.1.1" 621 | } 622 | }, 623 | "tunnel-agent": { 624 | "version": "0.6.0", 625 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 626 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 627 | "requires": { 628 | "safe-buffer": "^5.0.1" 629 | } 630 | }, 631 | "tweetnacl": { 632 | "version": "0.14.5", 633 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 634 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 635 | }, 636 | "type-is": { 637 | "version": "1.6.18", 638 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 639 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 640 | "requires": { 641 | "media-typer": "0.3.0", 642 | "mime-types": "~2.1.24" 643 | } 644 | }, 645 | "unpipe": { 646 | "version": "1.0.0", 647 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 648 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 649 | }, 650 | "uri-js": { 651 | "version": "4.4.1", 652 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 653 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 654 | "requires": { 655 | "punycode": "^2.1.0" 656 | } 657 | }, 658 | "utils-merge": { 659 | "version": "1.0.1", 660 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 661 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 662 | }, 663 | "uuid": { 664 | "version": "3.4.0", 665 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", 666 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" 667 | }, 668 | "vary": { 669 | "version": "1.1.2", 670 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 671 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 672 | }, 673 | "verror": { 674 | "version": "1.10.0", 675 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 676 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 677 | "requires": { 678 | "assert-plus": "^1.0.0", 679 | "core-util-is": "1.0.2", 680 | "extsprintf": "^1.2.0" 681 | } 682 | } 683 | } 684 | } 685 | -------------------------------------------------------------------------------- /proxy-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "proxy-server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "proxy.js", 6 | "scripts": { 7 | "start": "node proxy.js" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "apicache": "^1.6.2", 14 | "body-parser": "^1.19.0", 15 | "cors-anywhere": "^0.4.4", 16 | "express": "^4.17.1", 17 | "express-http-proxy": "^1.6.2", 18 | "got": "^11.8.2", 19 | "memoize-one": "^5.2.1", 20 | "metascraper": "^5.22.9", 21 | "metascraper-description": "^5.22.8", 22 | "metascraper-image": "^5.22.8", 23 | "metascraper-title": "^5.22.8", 24 | "request": "^2.88.2" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /proxy-server/proxy.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const app = express() 3 | const bodyParser = require('body-parser') 4 | const got = require('got') 5 | 6 | const metascraper = require('metascraper')([ 7 | require('metascraper-description')(), 8 | require('metascraper-image')(), 9 | require('metascraper-title')(), 10 | ]) 11 | 12 | app.use(bodyParser.urlencoded({extended: false})) 13 | app.use(bodyParser.json()) 14 | app.use('*', (req, res, next) => { 15 | // Set CORS headers: allow all origins, methods, and headers: you may want to lock this down in a production environment 16 | res.header('Access-Control-Allow-Origin', '*') 17 | res.header('Access-Control-Allow-Methods', 'GET, PUT, PATCH, POST, DELETE') 18 | res.header( 19 | 'Access-Control-Allow-Headers', 20 | req.header('access-control-request-headers'), 21 | ) 22 | next() 23 | }) 24 | 25 | app.get('/proxy', async (req, res) => { 26 | let link = req.get('link') 27 | if (link) { 28 | link = 'https://' + link.replace(/"/g, '') 29 | try { 30 | const {body: html, url} = await got(link) 31 | const metadata = await metascraper({ 32 | html, 33 | url, 34 | }) 35 | res.json(metadata) 36 | } catch (error) { 37 | res.send('error on scrapping the link ' + error.message) 38 | console.log('error is', error) 39 | } 40 | } else { 41 | res.status(404) 42 | res.send('link header parameter not provided') 43 | } 44 | }) 45 | 46 | let port = 5000 47 | app.listen(port, () => { 48 | console.log(`proxy server is running at localhost:${port}`) 49 | }) 50 | -------------------------------------------------------------------------------- /proxy-server/yarn-error.log: -------------------------------------------------------------------------------- 1 | Arguments: 2 | /usr/local/bin/node /usr/local/bin/yarn 3 | 4 | PATH: 5 | /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin 6 | 7 | Yarn version: 8 | 1.22.10 9 | 10 | Node version: 11 | 14.17.1 12 | 13 | Platform: 14 | darwin x64 15 | 16 | Trace: 17 | SyntaxError: /Volumes/MyFiles/opensource/twitter/proxy-server/package.json: Unexpected token } in JSON at position 595 18 | at JSON.parse () 19 | at /usr/local/lib/node_modules/yarn/lib/cli.js:1625:59 20 | at Generator.next () 21 | at step (/usr/local/lib/node_modules/yarn/lib/cli.js:310:30) 22 | at /usr/local/lib/node_modules/yarn/lib/cli.js:321:13 23 | 24 | npm manifest: 25 | { 26 | "name": "proxy-server", 27 | "version": "1.0.0", 28 | "description": "", 29 | "main": "proxy.js", 30 | "scripts": { 31 | "test": "echo \"Error: no test specified\" && exit 1" 32 | }, 33 | "keywords": [], 34 | "author": "", 35 | "license": "ISC", 36 | "dependencies": { 37 | "apicache": "^1.6.2", 38 | "body-parser": "^1.19.0", 39 | "cors-anywhere": "^0.4.4", 40 | "express": "^4.17.1", 41 | "express-http-proxy": "^1.6.2", 42 | "request": "^2.88.2", 43 | "memoize-one": "^5.2.1", 44 | "metascraper": "^5.22.9", 45 | "metascraper-description": "^5.22.8", 46 | "metascraper-image": "^5.22.8", 47 | "metascraper-title": "^5.22.8", 48 | } 49 | } 50 | 51 | yarn manifest: 52 | No manifest 53 | 54 | Lockfile: 55 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 56 | # yarn lockfile v1 57 | 58 | 59 | accepts@~1.3.7: 60 | version "1.3.7" 61 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" 62 | integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== 63 | dependencies: 64 | mime-types "~2.1.24" 65 | negotiator "0.6.2" 66 | 67 | ajv@^6.12.3: 68 | version "6.12.6" 69 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 70 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 71 | dependencies: 72 | fast-deep-equal "^3.1.1" 73 | fast-json-stable-stringify "^2.0.0" 74 | json-schema-traverse "^0.4.1" 75 | uri-js "^4.2.2" 76 | 77 | apicache@^1.6.2: 78 | version "1.6.2" 79 | resolved "https://registry.yarnpkg.com/apicache/-/apicache-1.6.2.tgz#a0a3d51024fa2814c4ace7e9e7053ebcb0920ee6" 80 | integrity sha512-3z5e+1E2qwZoqzFVgdx5l9nGhSG0kHv3v2G170vnJSz5uj4mCLVZfRw0o37aWwV8pTPXSkB8OBZz3TIur4H26g== 81 | 82 | array-flatten@1.1.1: 83 | version "1.1.1" 84 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 85 | integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= 86 | 87 | asn1@~0.2.3: 88 | version "0.2.4" 89 | resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" 90 | integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== 91 | dependencies: 92 | safer-buffer "~2.1.0" 93 | 94 | assert-plus@1.0.0, assert-plus@^1.0.0: 95 | version "1.0.0" 96 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" 97 | integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= 98 | 99 | asynckit@^0.4.0: 100 | version "0.4.0" 101 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 102 | integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= 103 | 104 | aws-sign2@~0.7.0: 105 | version "0.7.0" 106 | resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" 107 | integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= 108 | 109 | aws4@^1.8.0: 110 | version "1.11.0" 111 | resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" 112 | integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== 113 | 114 | bcrypt-pbkdf@^1.0.0: 115 | version "1.0.2" 116 | resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" 117 | integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= 118 | dependencies: 119 | tweetnacl "^0.14.3" 120 | 121 | body-parser@1.19.0, body-parser@^1.19.0: 122 | version "1.19.0" 123 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 124 | integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== 125 | dependencies: 126 | bytes "3.1.0" 127 | content-type "~1.0.4" 128 | debug "2.6.9" 129 | depd "~1.1.2" 130 | http-errors "1.7.2" 131 | iconv-lite "0.4.24" 132 | on-finished "~2.3.0" 133 | qs "6.7.0" 134 | raw-body "2.4.0" 135 | type-is "~1.6.17" 136 | 137 | bytes@3.1.0: 138 | version "3.1.0" 139 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" 140 | integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== 141 | 142 | caseless@~0.12.0: 143 | version "0.12.0" 144 | resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" 145 | integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= 146 | 147 | combined-stream@^1.0.6, combined-stream@~1.0.6: 148 | version "1.0.8" 149 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 150 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 151 | dependencies: 152 | delayed-stream "~1.0.0" 153 | 154 | content-disposition@0.5.3: 155 | version "0.5.3" 156 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" 157 | integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== 158 | dependencies: 159 | safe-buffer "5.1.2" 160 | 161 | content-type@~1.0.4: 162 | version "1.0.4" 163 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 164 | integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== 165 | 166 | cookie-signature@1.0.6: 167 | version "1.0.6" 168 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 169 | integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= 170 | 171 | cookie@0.4.0: 172 | version "0.4.0" 173 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" 174 | integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== 175 | 176 | core-util-is@1.0.2: 177 | version "1.0.2" 178 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 179 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 180 | 181 | cors-anywhere@^0.4.4: 182 | version "0.4.4" 183 | resolved "https://registry.yarnpkg.com/cors-anywhere/-/cors-anywhere-0.4.4.tgz#98892fcab55f408fff13a63e125135c18dc22ca8" 184 | integrity sha512-8OBFwnzMgR4mNrAeAyOLB2EruS2z7u02of2bOu7i9kKYlZG+niS7CTHLPgEXKWW2NAOJWRry9RRCaL9lJRjNqg== 185 | dependencies: 186 | http-proxy "1.11.1" 187 | proxy-from-env "0.0.1" 188 | 189 | dashdash@^1.12.0: 190 | version "1.14.1" 191 | resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" 192 | integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= 193 | dependencies: 194 | assert-plus "^1.0.0" 195 | 196 | debug@2.6.9: 197 | version "2.6.9" 198 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 199 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 200 | dependencies: 201 | ms "2.0.0" 202 | 203 | debug@^3.0.1: 204 | version "3.2.7" 205 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" 206 | integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== 207 | dependencies: 208 | ms "^2.1.1" 209 | 210 | delayed-stream@~1.0.0: 211 | version "1.0.0" 212 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 213 | integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= 214 | 215 | depd@~1.1.2: 216 | version "1.1.2" 217 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 218 | integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= 219 | 220 | destroy@~1.0.4: 221 | version "1.0.4" 222 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 223 | integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= 224 | 225 | ecc-jsbn@~0.1.1: 226 | version "0.1.2" 227 | resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" 228 | integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= 229 | dependencies: 230 | jsbn "~0.1.0" 231 | safer-buffer "^2.1.0" 232 | 233 | ee-first@1.1.1: 234 | version "1.1.1" 235 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 236 | integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= 237 | 238 | encodeurl@~1.0.2: 239 | version "1.0.2" 240 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 241 | integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= 242 | 243 | es6-promise@^4.1.1: 244 | version "4.2.8" 245 | resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" 246 | integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== 247 | 248 | escape-html@~1.0.3: 249 | version "1.0.3" 250 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 251 | integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= 252 | 253 | etag@~1.8.1: 254 | version "1.8.1" 255 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 256 | integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= 257 | 258 | eventemitter3@1.x.x: 259 | version "1.2.0" 260 | resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" 261 | integrity sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg= 262 | 263 | express-http-proxy@^1.6.2: 264 | version "1.6.2" 265 | resolved "https://registry.yarnpkg.com/express-http-proxy/-/express-http-proxy-1.6.2.tgz#e87152e45958cee4b91da2fdaa20a1ffd581204a" 266 | integrity sha512-soP7UXySFdLbeeMYL1foBkEoZj6HELq9BDAOCr1sLRpqjPaFruN5o6+bZeC+7U4USWIl4JMKEiIvTeKJ2WQdlQ== 267 | dependencies: 268 | debug "^3.0.1" 269 | es6-promise "^4.1.1" 270 | raw-body "^2.3.0" 271 | 272 | express@^4.17.1: 273 | version "4.17.1" 274 | resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" 275 | integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== 276 | dependencies: 277 | accepts "~1.3.7" 278 | array-flatten "1.1.1" 279 | body-parser "1.19.0" 280 | content-disposition "0.5.3" 281 | content-type "~1.0.4" 282 | cookie "0.4.0" 283 | cookie-signature "1.0.6" 284 | debug "2.6.9" 285 | depd "~1.1.2" 286 | encodeurl "~1.0.2" 287 | escape-html "~1.0.3" 288 | etag "~1.8.1" 289 | finalhandler "~1.1.2" 290 | fresh "0.5.2" 291 | merge-descriptors "1.0.1" 292 | methods "~1.1.2" 293 | on-finished "~2.3.0" 294 | parseurl "~1.3.3" 295 | path-to-regexp "0.1.7" 296 | proxy-addr "~2.0.5" 297 | qs "6.7.0" 298 | range-parser "~1.2.1" 299 | safe-buffer "5.1.2" 300 | send "0.17.1" 301 | serve-static "1.14.1" 302 | setprototypeof "1.1.1" 303 | statuses "~1.5.0" 304 | type-is "~1.6.18" 305 | utils-merge "1.0.1" 306 | vary "~1.1.2" 307 | 308 | extend@~3.0.2: 309 | version "3.0.2" 310 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" 311 | integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== 312 | 313 | extsprintf@1.3.0: 314 | version "1.3.0" 315 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" 316 | integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= 317 | 318 | extsprintf@^1.2.0: 319 | version "1.4.0" 320 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" 321 | integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= 322 | 323 | fast-deep-equal@^3.1.1: 324 | version "3.1.3" 325 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 326 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 327 | 328 | fast-json-stable-stringify@^2.0.0: 329 | version "2.1.0" 330 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 331 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 332 | 333 | finalhandler@~1.1.2: 334 | version "1.1.2" 335 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" 336 | integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== 337 | dependencies: 338 | debug "2.6.9" 339 | encodeurl "~1.0.2" 340 | escape-html "~1.0.3" 341 | on-finished "~2.3.0" 342 | parseurl "~1.3.3" 343 | statuses "~1.5.0" 344 | unpipe "~1.0.0" 345 | 346 | forever-agent@~0.6.1: 347 | version "0.6.1" 348 | resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" 349 | integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= 350 | 351 | form-data@~2.3.2: 352 | version "2.3.3" 353 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" 354 | integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== 355 | dependencies: 356 | asynckit "^0.4.0" 357 | combined-stream "^1.0.6" 358 | mime-types "^2.1.12" 359 | 360 | forwarded@0.2.0: 361 | version "0.2.0" 362 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" 363 | integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== 364 | 365 | fresh@0.5.2: 366 | version "0.5.2" 367 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 368 | integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= 369 | 370 | getpass@^0.1.1: 371 | version "0.1.7" 372 | resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" 373 | integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= 374 | dependencies: 375 | assert-plus "^1.0.0" 376 | 377 | har-schema@^2.0.0: 378 | version "2.0.0" 379 | resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" 380 | integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= 381 | 382 | har-validator@~5.1.3: 383 | version "5.1.5" 384 | resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" 385 | integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== 386 | dependencies: 387 | ajv "^6.12.3" 388 | har-schema "^2.0.0" 389 | 390 | http-errors@1.7.2: 391 | version "1.7.2" 392 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" 393 | integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== 394 | dependencies: 395 | depd "~1.1.2" 396 | inherits "2.0.3" 397 | setprototypeof "1.1.1" 398 | statuses ">= 1.5.0 < 2" 399 | toidentifier "1.0.0" 400 | 401 | http-errors@1.7.3, http-errors@~1.7.2: 402 | version "1.7.3" 403 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" 404 | integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== 405 | dependencies: 406 | depd "~1.1.2" 407 | inherits "2.0.4" 408 | setprototypeof "1.1.1" 409 | statuses ">= 1.5.0 < 2" 410 | toidentifier "1.0.0" 411 | 412 | http-proxy@1.11.1: 413 | version "1.11.1" 414 | resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.11.1.tgz#71df55757e802d58ea810df2244019dda05ae85d" 415 | integrity sha1-cd9VdX6ALVjqgQ3yJEAZ3aBa6F0= 416 | dependencies: 417 | eventemitter3 "1.x.x" 418 | requires-port "0.x.x" 419 | 420 | http-signature@~1.2.0: 421 | version "1.2.0" 422 | resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" 423 | integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= 424 | dependencies: 425 | assert-plus "^1.0.0" 426 | jsprim "^1.2.2" 427 | sshpk "^1.7.0" 428 | 429 | iconv-lite@0.4.24: 430 | version "0.4.24" 431 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 432 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 433 | dependencies: 434 | safer-buffer ">= 2.1.2 < 3" 435 | 436 | inherits@2.0.3: 437 | version "2.0.3" 438 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 439 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 440 | 441 | inherits@2.0.4: 442 | version "2.0.4" 443 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 444 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 445 | 446 | ipaddr.js@1.9.1: 447 | version "1.9.1" 448 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" 449 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== 450 | 451 | is-typedarray@~1.0.0: 452 | version "1.0.0" 453 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 454 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= 455 | 456 | isstream@~0.1.2: 457 | version "0.1.2" 458 | resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" 459 | integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= 460 | 461 | jsbn@~0.1.0: 462 | version "0.1.1" 463 | resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" 464 | integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= 465 | 466 | json-schema-traverse@^0.4.1: 467 | version "0.4.1" 468 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 469 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 470 | 471 | json-schema@0.2.3: 472 | version "0.2.3" 473 | resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" 474 | integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= 475 | 476 | json-stringify-safe@~5.0.1: 477 | version "5.0.1" 478 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 479 | integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= 480 | 481 | jsprim@^1.2.2: 482 | version "1.4.1" 483 | resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" 484 | integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= 485 | dependencies: 486 | assert-plus "1.0.0" 487 | extsprintf "1.3.0" 488 | json-schema "0.2.3" 489 | verror "1.10.0" 490 | 491 | media-typer@0.3.0: 492 | version "0.3.0" 493 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 494 | integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= 495 | 496 | merge-descriptors@1.0.1: 497 | version "1.0.1" 498 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 499 | integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= 500 | 501 | methods@~1.1.2: 502 | version "1.1.2" 503 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 504 | integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= 505 | 506 | mime-db@1.48.0: 507 | version "1.48.0" 508 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" 509 | integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== 510 | 511 | mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: 512 | version "2.1.31" 513 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" 514 | integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== 515 | dependencies: 516 | mime-db "1.48.0" 517 | 518 | mime@1.6.0: 519 | version "1.6.0" 520 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" 521 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== 522 | 523 | ms@2.0.0: 524 | version "2.0.0" 525 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 526 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 527 | 528 | ms@2.1.1: 529 | version "2.1.1" 530 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 531 | integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== 532 | 533 | ms@^2.1.1: 534 | version "2.1.3" 535 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 536 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 537 | 538 | negotiator@0.6.2: 539 | version "0.6.2" 540 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" 541 | integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== 542 | 543 | oauth-sign@~0.9.0: 544 | version "0.9.0" 545 | resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" 546 | integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== 547 | 548 | on-finished@~2.3.0: 549 | version "2.3.0" 550 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 551 | integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= 552 | dependencies: 553 | ee-first "1.1.1" 554 | 555 | parseurl@~1.3.3: 556 | version "1.3.3" 557 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" 558 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== 559 | 560 | path-to-regexp@0.1.7: 561 | version "0.1.7" 562 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 563 | integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= 564 | 565 | performance-now@^2.1.0: 566 | version "2.1.0" 567 | resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" 568 | integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= 569 | 570 | proxy-addr@~2.0.5: 571 | version "2.0.7" 572 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" 573 | integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== 574 | dependencies: 575 | forwarded "0.2.0" 576 | ipaddr.js "1.9.1" 577 | 578 | proxy-from-env@0.0.1: 579 | version "0.0.1" 580 | resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-0.0.1.tgz#b27c4946e9e6d5dbadb7598a6435d3014c4cfd49" 581 | integrity sha1-snxJRunm1dutt1mKZDXTAUxM/Uk= 582 | 583 | psl@^1.1.28: 584 | version "1.8.0" 585 | resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" 586 | integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== 587 | 588 | punycode@^2.1.0, punycode@^2.1.1: 589 | version "2.1.1" 590 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 591 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 592 | 593 | qs@6.7.0: 594 | version "6.7.0" 595 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" 596 | integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== 597 | 598 | qs@~6.5.2: 599 | version "6.5.2" 600 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" 601 | integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== 602 | 603 | range-parser@~1.2.1: 604 | version "1.2.1" 605 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" 606 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== 607 | 608 | raw-body@2.4.0: 609 | version "2.4.0" 610 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" 611 | integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== 612 | dependencies: 613 | bytes "3.1.0" 614 | http-errors "1.7.2" 615 | iconv-lite "0.4.24" 616 | unpipe "1.0.0" 617 | 618 | raw-body@^2.3.0: 619 | version "2.4.1" 620 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" 621 | integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== 622 | dependencies: 623 | bytes "3.1.0" 624 | http-errors "1.7.3" 625 | iconv-lite "0.4.24" 626 | unpipe "1.0.0" 627 | 628 | request@^2.88.2: 629 | version "2.88.2" 630 | resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" 631 | integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== 632 | dependencies: 633 | aws-sign2 "~0.7.0" 634 | aws4 "^1.8.0" 635 | caseless "~0.12.0" 636 | combined-stream "~1.0.6" 637 | extend "~3.0.2" 638 | forever-agent "~0.6.1" 639 | form-data "~2.3.2" 640 | har-validator "~5.1.3" 641 | http-signature "~1.2.0" 642 | is-typedarray "~1.0.0" 643 | isstream "~0.1.2" 644 | json-stringify-safe "~5.0.1" 645 | mime-types "~2.1.19" 646 | oauth-sign "~0.9.0" 647 | performance-now "^2.1.0" 648 | qs "~6.5.2" 649 | safe-buffer "^5.1.2" 650 | tough-cookie "~2.5.0" 651 | tunnel-agent "^0.6.0" 652 | uuid "^3.3.2" 653 | 654 | requires-port@0.x.x: 655 | version "0.0.1" 656 | resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-0.0.1.tgz#4b4414411d9df7c855995dd899a8c78a2951c16d" 657 | integrity sha1-S0QUQR2d98hVmV3YmajHiilRwW0= 658 | 659 | safe-buffer@5.1.2: 660 | version "5.1.2" 661 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 662 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 663 | 664 | safe-buffer@^5.0.1, safe-buffer@^5.1.2: 665 | version "5.2.1" 666 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 667 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 668 | 669 | "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: 670 | version "2.1.2" 671 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 672 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 673 | 674 | send@0.17.1: 675 | version "0.17.1" 676 | resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" 677 | integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== 678 | dependencies: 679 | debug "2.6.9" 680 | depd "~1.1.2" 681 | destroy "~1.0.4" 682 | encodeurl "~1.0.2" 683 | escape-html "~1.0.3" 684 | etag "~1.8.1" 685 | fresh "0.5.2" 686 | http-errors "~1.7.2" 687 | mime "1.6.0" 688 | ms "2.1.1" 689 | on-finished "~2.3.0" 690 | range-parser "~1.2.1" 691 | statuses "~1.5.0" 692 | 693 | serve-static@1.14.1: 694 | version "1.14.1" 695 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" 696 | integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== 697 | dependencies: 698 | encodeurl "~1.0.2" 699 | escape-html "~1.0.3" 700 | parseurl "~1.3.3" 701 | send "0.17.1" 702 | 703 | setprototypeof@1.1.1: 704 | version "1.1.1" 705 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" 706 | integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== 707 | 708 | sshpk@^1.7.0: 709 | version "1.16.1" 710 | resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" 711 | integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== 712 | dependencies: 713 | asn1 "~0.2.3" 714 | assert-plus "^1.0.0" 715 | bcrypt-pbkdf "^1.0.0" 716 | dashdash "^1.12.0" 717 | ecc-jsbn "~0.1.1" 718 | getpass "^0.1.1" 719 | jsbn "~0.1.0" 720 | safer-buffer "^2.0.2" 721 | tweetnacl "~0.14.0" 722 | 723 | "statuses@>= 1.5.0 < 2", statuses@~1.5.0: 724 | version "1.5.0" 725 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 726 | integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= 727 | 728 | toidentifier@1.0.0: 729 | version "1.0.0" 730 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" 731 | integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== 732 | 733 | tough-cookie@~2.5.0: 734 | version "2.5.0" 735 | resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" 736 | integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== 737 | dependencies: 738 | psl "^1.1.28" 739 | punycode "^2.1.1" 740 | 741 | tunnel-agent@^0.6.0: 742 | version "0.6.0" 743 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" 744 | integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= 745 | dependencies: 746 | safe-buffer "^5.0.1" 747 | 748 | tweetnacl@^0.14.3, tweetnacl@~0.14.0: 749 | version "0.14.5" 750 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" 751 | integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= 752 | 753 | type-is@~1.6.17, type-is@~1.6.18: 754 | version "1.6.18" 755 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" 756 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== 757 | dependencies: 758 | media-typer "0.3.0" 759 | mime-types "~2.1.24" 760 | 761 | unpipe@1.0.0, unpipe@~1.0.0: 762 | version "1.0.0" 763 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 764 | integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= 765 | 766 | uri-js@^4.2.2: 767 | version "4.4.1" 768 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 769 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 770 | dependencies: 771 | punycode "^2.1.0" 772 | 773 | utils-merge@1.0.1: 774 | version "1.0.1" 775 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 776 | integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= 777 | 778 | uuid@^3.3.2: 779 | version "3.4.0" 780 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" 781 | integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== 782 | 783 | vary@~1.1.2: 784 | version "1.1.2" 785 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 786 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= 787 | 788 | verror@1.10.0: 789 | version "1.10.0" 790 | resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" 791 | integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= 792 | dependencies: 793 | assert-plus "^1.0.0" 794 | core-util-is "1.0.2" 795 | extsprintf "^1.2.0" 796 | -------------------------------------------------------------------------------- /src/Components/Button.tsx: -------------------------------------------------------------------------------- 1 | import React, {FC, useState} from 'react' 2 | import {StyleProp} from 'react-native' 3 | import {Pressable} from 'react-native-web-hover' 4 | import {useMediaQuery} from 'react-responsive' 5 | type ChildProps = { 6 | renderText: ({ 7 | state, 8 | }: { 9 | state: 'desktop' | 'tablet' 10 | }) => React.ReactElement | null 11 | renderIcon: ({ 12 | state, 13 | }: { 14 | state: 'desktop' | 'tablet' 15 | }) => React.ReactElement | null 16 | containerStyle: ({state}: {state: 'desktop' | 'tablet'}) => StyleProp 17 | } 18 | export const Button: FC = ({ 19 | renderText, 20 | renderIcon, 21 | containerStyle, 22 | }) => { 23 | const isDesktop = useMediaQuery({minWidth: 1266}) 24 | const state = isDesktop ? 'desktop' : 'tablet' 25 | return ( 26 | 27 | {renderIcon ? renderIcon({state}) : null} 28 | {renderText ? renderText({state}) : null} 29 | 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /src/Components/Center.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {View, Text, StyleSheet, FlatList} from 'react-native' 3 | import {CreateTweet, CreateTweetTopRow} from '../Components/CreateTweet' 4 | import {Post} from '../Components/Post' 5 | import {IPost, useStore} from '../store/store' 6 | import {colors} from '../styles/colors' 7 | 8 | export function Center() { 9 | const posts = useStore((state) => state.posts) 10 | 11 | const renderItem = React.useCallback(({item}) => , []) 12 | return ( 13 | 14 | 15 | 16 | 17 | data={posts} 18 | renderItem={renderItem} 19 | style={styles.flatListStyle} 20 | /> 21 | 22 | ) 23 | } 24 | 25 | const styles = StyleSheet.create({ 26 | container: { 27 | flex: 2.2, 28 | }, 29 | createTweet: { 30 | marginBottom: 15, 31 | borderBottomWidth: 0.01, 32 | borderBottomColor: colors.COLOR_BLACK_LIGHT_6, 33 | }, 34 | flatListStyle: { 35 | borderBottomWidth: 0.01, 36 | borderTopWidth: 0.01, 37 | borderColor: colors.COLOR_BLACK_LIGHT_6, 38 | }, 39 | }) 40 | -------------------------------------------------------------------------------- /src/Components/CreateTweet.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | StyleSheet, 4 | Image, 5 | View, 6 | Text, 7 | ViewStyle, 8 | TextInput, 9 | Platform, 10 | } from 'react-native' 11 | import {Pressable} from 'react-native-web-hover' 12 | import ImageSvg from '../assets/SVGs/ImageSvg' 13 | import GifSvg from '../assets/SVGs/GifSvg' 14 | import ChartIcon from '../assets/SVGs/SleepingChart' 15 | import Face from '../assets/SVGs/HappyFace' 16 | import CalenderIcon from '../assets/SVGs/Calender' 17 | import Star from '../assets/SVGs/Star' 18 | import {colors} from '../styles/colors' 19 | import {useState} from 'react' 20 | import {useStore} from '../store/store' 21 | 22 | interface Props { 23 | style?: ViewStyle 24 | } 25 | 26 | export const CreateTweetTopRow: React.FC = ({}) => { 27 | return ( 28 | 29 | Home 30 | 31 | [ 33 | styles.startContainer, 34 | hovered 35 | ? { 36 | backgroundColor: colors.COLOR_BLACK_LIGHT_6, 37 | } 38 | : {}, 39 | ]}> 40 | 41 | 42 | 43 | ) 44 | } 45 | export const CreateTweet: React.FC = ({style}) => { 46 | const [data, setData] = useState('') 47 | const storeTweet = useStore((state) => state.addPost) 48 | const onChange = (text: string) => { 49 | setData(text) 50 | } 51 | const tweet = () => { 52 | if (data) { 53 | storeTweet({ 54 | fullName: 'Ehsan Sarshar', 55 | userNameAndDate: '@TheEhsanSarshar . 10m', 56 | profileUrl: 57 | 'https://pbs.twimg.com/profile_images/1389235685345959942/B1yoUQGj_400x400.jpg', 58 | content: data, 59 | }) 60 | } 61 | } 62 | return ( 63 | 64 | 65 | 71 | 78 | 79 | 80 | 81 | [ 83 | styles.svgWrapper, 84 | hovered 85 | ? { 86 | backgroundColor: colors.primaryLight_1, 87 | } 88 | : {}, 89 | ]}> 90 | 94 | 95 | [ 97 | styles.svgWrapper, 98 | hovered 99 | ? { 100 | backgroundColor: colors.primaryLight_1, 101 | } 102 | : {}, 103 | ]}> 104 | 105 | 106 | [ 108 | styles.svgWrapper, 109 | hovered 110 | ? { 111 | backgroundColor: colors.primaryLight_1, 112 | } 113 | : {}, 114 | ]}> 115 | 119 | 120 | [ 122 | styles.svgWrapper, 123 | hovered 124 | ? { 125 | backgroundColor: colors.primaryLight_1, 126 | } 127 | : {}, 128 | ]}> 129 | 130 | 131 | [ 133 | styles.svgWrapper, 134 | hovered 135 | ? { 136 | backgroundColor: colors.primaryLight_1, 137 | } 138 | : {}, 139 | ]}> 140 | 144 | 145 | 146 | 149 | Tweet 150 | 151 | 152 | 153 | ) 154 | } 155 | 156 | const styles = StyleSheet.create({ 157 | container: { 158 | width: '100%', 159 | backgroundColor: '#fff', 160 | paddingBottom: 10, 161 | }, 162 | topRow: { 163 | flexDirection: 'row', 164 | justifyContent: 'space-between', 165 | alignItems: 'center', 166 | borderBottomWidth: 0.01, 167 | paddingHorizontal: 15, 168 | borderBottomColor: colors.COLOR_BLACK_LIGHT_6, 169 | paddingVertical: 5, 170 | ...Platform.select({ 171 | web: { 172 | position: 'sticky', 173 | }, 174 | }), 175 | top: 0, 176 | backgroundColor: '#fff', 177 | zIndex: 100, 178 | } as ViewStyle, 179 | topRowText: { 180 | fontSize: 20, 181 | color: colors.COLOR_BLACK_LIGHT_4, 182 | fontWeight: '800', 183 | paddingStart: 1, 184 | }, 185 | middleRow: { 186 | flexDirection: 'row', 187 | alignItems: 'center', 188 | paddingTop: 10, 189 | paddingBottom: 20, 190 | paddingHorizontal: 15, 191 | }, 192 | middleRowText: { 193 | fontSize: 20, 194 | color: colors.COLOR_BLACK_LIGHT_4, 195 | fontWeight: '500', 196 | paddingTop: 5, 197 | ...Platform.select({ 198 | web: { 199 | outlineStyle: 'none', 200 | }, 201 | }), 202 | width: '100%', 203 | height: '100%', 204 | flexWrap: 'wrap', 205 | // ...Platform.select({ 206 | // web: { 207 | // input: { 208 | // outline: 'none', 209 | // }, 210 | // }, 211 | // }), 212 | }, 213 | // bottomRow: { 214 | // flexDirection: 'row', 215 | // paddingHorizontal: 15, 216 | // }, 217 | profileImage: { 218 | width: 50, 219 | height: 50, 220 | borderRadius: 100, 221 | marginEnd: 15, 222 | }, 223 | commonSvgStyle: { 224 | width: 23, 225 | height: 23, 226 | }, 227 | iconsContainer: { 228 | flexDirection: 'row', 229 | paddingStart: 65, 230 | justifyContent: 'space-around', 231 | }, 232 | bottomRow: { 233 | flexDirection: 'row', 234 | justifyContent: 'space-between', 235 | width: '100%', 236 | paddingHorizontal: 6, 237 | }, 238 | button: { 239 | borderRadius: 100, 240 | backgroundColor: colors.primaryColor, 241 | paddingVertical: 12, 242 | paddingHorizontal: 15, 243 | marginEnd: 15, 244 | ...Platform.select({ 245 | web: { 246 | cursor: 'pointer', 247 | }, 248 | }), 249 | }, 250 | buttonDisabled: { 251 | borderRadius: 100, 252 | backgroundColor: colors.primaryColor, 253 | opacity: 0.5, 254 | paddingVertical: 12, 255 | paddingHorizontal: 15, 256 | marginEnd: 15, 257 | }, 258 | buttonText: { 259 | fontSize: 15, 260 | color: '#fff', 261 | fontWeight: 'bold', 262 | }, 263 | svgWrapper: { 264 | borderRadius: 100, 265 | justifyContent: 'center', 266 | alignItems: 'center', 267 | width: 40, 268 | height: 40, 269 | }, 270 | startContainer: { 271 | borderRadius: 100, 272 | padding: 10, 273 | }, 274 | }) 275 | -------------------------------------------------------------------------------- /src/Components/Foldable.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {View} from 'react-native' 3 | import {Pressable} from 'react-native-web-hover' 4 | import {colors} from '../styles/colors' 5 | 6 | export const Foldable = ({children, ...values}) => { 7 | return ( 8 | 16 | {children} 17 | 18 | ) 19 | } 20 | 21 | Foldable.Header = ({children, ...values}) => { 22 | return {children} 23 | } 24 | 25 | Foldable.Row = ({children, ...values}) => { 26 | return {children} 27 | } 28 | 29 | Foldable.Footer = ({children, ...values}) => { 30 | return {children} 31 | } 32 | -------------------------------------------------------------------------------- /src/Components/Post.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {View, Text, Image, StyleSheet, Linking, Platform} from 'react-native' 3 | import {Pressable} from 'react-native-web-hover' 4 | // extract urls out of a string 5 | import getUrls from 'get-urls' 6 | import HyperLinkIcon from '../assets/SVGs/HyperLinkIcon' 7 | import {colors} from '../styles/colors' 8 | import Comment from '../assets/SVGs/Comment' 9 | import Retweet from '../assets/SVGs/Retweet' 10 | import Love from '../assets/SVGs/Love' 11 | import Share from '../assets/SVGs/Share' 12 | import Anchor from '../assets/SVGs/HyperLinkIcon' 13 | 14 | interface IData { 15 | image: string 16 | title: string 17 | description: string 18 | } 19 | 20 | interface IPost { 21 | profileUrl: string 22 | fullName: string 23 | userNameAndDate: string 24 | content: string 25 | } 26 | export const Post: React.FC = ({ 27 | profileUrl, 28 | fullName, 29 | userNameAndDate, 30 | content, 31 | }) => { 32 | const urls = Array.from(getUrls(content)) 33 | const [data, setData] = React.useState() 34 | React.useEffect(() => { 35 | if (urls.length) { 36 | ;(async () => { 37 | try { 38 | const link = urls[0].replace(/(^\w+:|^)\/\//, '') 39 | const res = await fetch(`http://localhost:5000/proxy`, { 40 | headers: { 41 | link, 42 | }, 43 | }) 44 | const body = await res.json() 45 | setData(body) 46 | } catch (error) { 47 | console.log('error is', error) 48 | } 49 | })() 50 | } 51 | }, []) 52 | return ( 53 | 54 | 55 | 56 | 57 | {fullName} 58 | {userNameAndDate} 59 | 60 | 61 | {content} 62 | {data?.image ? ( 63 | 64 | 69 | 70 | {data.title} 71 | {data.description} 72 | {urls.length ? ( 73 | 74 | 78 | Linking.openURL(urls[0])} 80 | style={styles.mediaIconLink}> 81 | {urls[0]} 82 | 83 | 84 | ) : null} 85 | 86 | 87 | ) : null} 88 | 89 | 90 | [ 92 | styles.svgWrapper, 93 | hovered 94 | ? { 95 | backgroundColor: colors.primaryLight_1, 96 | } 97 | : {}, 98 | ]}> 99 | 103 | 104 | [ 106 | styles.svgWrapper, 107 | hovered 108 | ? { 109 | backgroundColor: colors.primaryLight_1, 110 | } 111 | : {}, 112 | ]}> 113 | 117 | 118 | [ 120 | styles.svgWrapper, 121 | hovered 122 | ? { 123 | backgroundColor: colors.primaryLight_1, 124 | } 125 | : {}, 126 | ]}> 127 | 131 | 132 | [ 134 | styles.svgWrapper, 135 | hovered 136 | ? { 137 | backgroundColor: colors.primaryLight_1, 138 | } 139 | : {}, 140 | ]}> 141 | 145 | 146 | 147 | 148 | 149 | ) 150 | } 151 | 152 | const LinkContent = () => { 153 | return ( 154 | 155 | 156 | Link title 157 | 158 | link address 159 | 160 | 161 | 162 | ) 163 | } 164 | 165 | const styles = StyleSheet.create({ 166 | container: { 167 | backgroundColor: '#fff', 168 | paddingStart: 20, 169 | paddingEnd: 15, 170 | paddingTop: 15, 171 | flexDirection: 'row', 172 | marginBottom: 4, 173 | }, 174 | allContent: { 175 | paddingStart: 10, 176 | width: '100%', 177 | }, 178 | profileImage: { 179 | width: 50, 180 | height: 50, 181 | borderRadius: 100, 182 | }, 183 | postAuthorInfoContainer: { 184 | flexDirection: 'row', 185 | alignItems: 'center', 186 | }, 187 | fullName: { 188 | fontSize: 18, 189 | fontWeight: '500', 190 | }, 191 | userNameAndTime: { 192 | color: colors.COLOR_BLACK_LIGHT_4, 193 | paddingStart: 7, 194 | }, 195 | actualContent: { 196 | paddingTop: 5, 197 | }, 198 | contentText: { 199 | fontWeight: '400', 200 | fontSize: 15, 201 | }, 202 | linkContent: {}, 203 | linkContentImage: {}, 204 | linkContentTitle: {}, 205 | linkContentLink: {}, 206 | linkContentLinkText: {}, 207 | linkContentSvg: {}, 208 | svgWrapper: { 209 | borderRadius: 100, 210 | justifyContent: 'center', 211 | alignItems: 'center', 212 | width: 40, 213 | height: 40, 214 | marginEnd: '16%', 215 | }, 216 | commonSvgStyle: { 217 | width: 23, 218 | height: 23, 219 | }, 220 | actionListContainer: { 221 | flexDirection: 'row', 222 | paddingVertical: 10, 223 | justifyContent: 'flex-start', 224 | marginLeft: '-1%', 225 | }, 226 | threeTextsInsideMediaView: { 227 | justifyContent: 'center', 228 | alignItems: 'flex-start', 229 | padding: 15, 230 | }, 231 | anchor: { 232 | width: 34, 233 | height: 20, 234 | marginStart: -5, 235 | }, 236 | mediaImage: { 237 | marginStart: 'auto', 238 | borderBottomWidth: 1, 239 | borderColor: 'rgba(0,0,0,0.2)', 240 | width: '100%', 241 | height: 222, 242 | }, 243 | mediaBox: { 244 | borderWidth: 1, 245 | borderColor: 'rgba(0,0,0,0.2)', 246 | width: '90%', 247 | borderRadius: 15, 248 | overflow: 'hidden', 249 | marginTop: 20, 250 | }, 251 | linkContainer: { 252 | flexDirection: 'row', 253 | paddingVertical: 4, 254 | alignItems: 'center', 255 | }, 256 | mediaTitle: { 257 | fontSize: 15, 258 | fontWeight: '500', 259 | marginBottom: 5, 260 | }, 261 | mediaDetails: { 262 | fontSize: 15, 263 | marginBottom: 5, 264 | color: colors.COLOR_BLACK_LIGHT_4, 265 | }, 266 | mediaIconLink: { 267 | color: colors.COLOR_BLACK_LIGHT_3, 268 | ...Platform.select({ 269 | web: { 270 | cursor: 'pointer', 271 | }, 272 | }), 273 | }, 274 | }) 275 | -------------------------------------------------------------------------------- /src/Components/RightBar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {View, Text, StyleSheet, Image, Platform} from 'react-native' 3 | import {useMediaQuery} from 'react-responsive' 4 | import {colors} from '../styles/colors' 5 | import {Ionicons} from '@expo/vector-icons' 6 | import {SearchBar} from './SearchBar' 7 | import {Pressable, ScrollView} from 'react-native-web-hover' 8 | 9 | export function RightBar() { 10 | const isRightBarVisible = useMediaQuery({minWidth: 990}) 11 | if (!isRightBarVisible) return null 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ) 21 | } 22 | 23 | function Trends() { 24 | return ( 25 | 34 | 44 | Trends for you 45 | 46 | 47 | 48 | {Array(4) 49 | .fill(0) 50 | .map(() => { 51 | return ( 52 | 57 | ) 58 | })} 59 | 60 | 61 | [ 63 | hovered 64 | ? { 65 | backgroundColor: colors.COLOR_BLACK_LIGHT_6, 66 | } 67 | : {}, 68 | { 69 | paddingVertical: 20, 70 | paddingHorizontal: 14, 71 | ...Platform.select({ 72 | web: { 73 | cursor: 'pointer', 74 | }, 75 | }), 76 | }, 77 | ]}> 78 | 79 | Show more 80 | 81 | 82 | 83 | 84 | ) 85 | } 86 | 87 | function SuggestedFriends() { 88 | return ( 89 | 98 | 108 | Who to follow 109 | 110 | 111 | {followRecData.map((data) => { 112 | return 113 | })} 114 | 115 | 116 | [ 118 | hovered 119 | ? { 120 | backgroundColor: colors.COLOR_BLACK_LIGHT_6, 121 | } 122 | : {}, 123 | { 124 | paddingVertical: 20, 125 | paddingHorizontal: 14, 126 | ...Platform.select({ 127 | web: { 128 | cursor: 'pointer', 129 | }, 130 | }), 131 | }, 132 | ]}> 133 | 134 | Show more 135 | 136 | 137 | 138 | 139 | ) 140 | } 141 | 142 | const followRecData = [ 143 | { 144 | photo: 145 | 'https://pbs.twimg.com/profile_images/1360004712439767041/phm-6601_400x400.jpg', 146 | name: 'Nicolas', 147 | userName: '@necolas', 148 | }, 149 | { 150 | name: 'Evan Bacon', 151 | photo: 152 | 'https://pbs.twimg.com/profile_images/1308332115919020032/jlqFOD33_400x400.jpg', 153 | userName: '@Baconbrix', 154 | }, 155 | { 156 | name: 'Dan', 157 | photo: 158 | 'https://pbs.twimg.com/profile_images/1336281436685541376/fRSl8uJP_400x400.jpg', 159 | userName: '@dan_abramov', 160 | }, 161 | { 162 | name: 'Krzysztof Magiera', 163 | photo: 164 | 'https://pbs.twimg.com/profile_images/1064786289311010816/zD2FlyxR_400x400.jpg', 165 | userName: '@kzzzf', 166 | }, 167 | ] 168 | const FollowRowComponent = ({name, userName, photo}) => { 169 | return ( 170 | [ 172 | hovered 173 | ? { 174 | backgroundColor: colors.COLOR_BLACK_LIGHT_6, 175 | } 176 | : {}, 177 | { 178 | flexDirection: 'row', 179 | justifyContent: 'space-between', 180 | alignItems: 'center', 181 | borderBottomWidth: 0.01, 182 | borderBottomColor: colors.COLOR_BLACK_LIGHT_6, 183 | paddingVertical: 13, 184 | paddingHorizontal: 15, 185 | ...Platform.select({ 186 | web: { 187 | cursor: 'pointer', 188 | }, 189 | }), 190 | }, 191 | ]}> 192 | 203 | 208 | {name} 209 | 210 | {userName} 211 | 212 | 213 | [ 215 | hovered ? {backgroundColor: colors.primaryLight_1} : {}, 216 | { 217 | borderRadius: 100, 218 | borderColor: colors.primaryColor, 219 | borderWidth: 1.5, 220 | paddingVertical: 5, 221 | paddingHorizontal: 15, 222 | justifyContent: 'center', 223 | alignItems: 'center', 224 | }, 225 | ]}> 226 | 227 | Follow 228 | 229 | 230 | 231 | ) 232 | } 233 | const TrendComponent = ({ 234 | topHeader, 235 | mainTitle, 236 | numberOfTweets, 237 | }: { 238 | topHeader: string 239 | mainTitle: string 240 | numberOfTweets: string 241 | }) => { 242 | return ( 243 | [ 245 | hovered 246 | ? { 247 | backgroundColor: colors.COLOR_BLACK_LIGHT_6, 248 | } 249 | : {}, 250 | { 251 | flexDirection: 'row', 252 | justifyContent: 'space-between', 253 | alignItems: 'center', 254 | paddingHorizontal: 15, 255 | paddingVertical: 13, 256 | borderBottomWidth: 0.01, 257 | borderBottomColor: colors.COLOR_BLACK_LIGHT_6, 258 | ...Platform.select({ 259 | web: { 260 | cursor: 'pointer', 261 | }, 262 | }), 263 | }, 264 | ]}> 265 | 269 | 270 | {topHeader} 271 | 272 | 273 | {mainTitle} 274 | 275 | 276 | {numberOfTweets} 277 | 278 | 279 | [ 281 | hovered 282 | ? { 283 | backgroundColor: colors.COLOR_BLACK_LIGHT_6, 284 | } 285 | : {}, 286 | { 287 | borderRadius: 100, 288 | width: 40, 289 | height: 40, 290 | justifyContent: 'center', 291 | alignItems: 'center', 292 | marginTop: -20, 293 | }, 294 | ]}> 295 | 302 | 303 | 304 | ) 305 | } 306 | 307 | const styles = StyleSheet.create({ 308 | container: { 309 | flex: 1.7, 310 | height: '100%', 311 | backgroundColor: '#fff', 312 | borderColor: colors.COLOR_BLACK_LIGHT_6, 313 | borderLeftWidth: 0.1, 314 | alignItems: 'flex-start', 315 | // marginTop: 30, 316 | paddingStart: 20, 317 | }, 318 | }) 319 | -------------------------------------------------------------------------------- /src/Components/SearchBar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {View, Text, Platform, ViewStyle} from 'react-native' 3 | import SearchSVG from '../assets/SVGs/Search' 4 | import {colors} from '../styles/colors' 5 | 6 | export const SearchBar = () => { 7 | return ( 8 | 27 | 38 | 39 | 45 | Search Twitter 46 | 47 | 48 | 49 | ) 50 | } 51 | -------------------------------------------------------------------------------- /src/Components/SideBar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Dimensions, Platform, Text, View, ViewStyle} from 'react-native' 3 | import {useMediaQuery} from 'react-responsive' 4 | import {widthPercentageToDP as wp} from 'react-native-responsive-screen' 5 | import {SideBarItem} from './SideBarItem' 6 | import TwitterIcon from '../assets/SVGs/Twitter' 7 | import {colors} from '../styles/colors' 8 | import {Button} from './Button' 9 | import Profile from '../assets/SVGs/Profile' 10 | import {Pressable} from 'react-native-web-hover' 11 | const WindowHeight = Dimensions.get('window').height 12 | const sideBarData = [ 13 | { 14 | title: 'Home', 15 | iconName: 'home', 16 | }, 17 | { 18 | title: 'Explore', 19 | iconName: 'search', 20 | }, 21 | { 22 | title: 'Notifications', 23 | iconName: 'bell', 24 | }, 25 | { 26 | title: 'Messages', 27 | iconName: 'message', 28 | }, 29 | { 30 | title: 'Bookmarks', 31 | iconName: 'flag', 32 | }, 33 | { 34 | title: 'Lists', 35 | iconName: 'book', 36 | }, 37 | { 38 | title: 'More', 39 | iconName: 'threeDots', 40 | }, 41 | // { 42 | // title: 'Profile', 43 | // iconName: 'profile', 44 | // }, 45 | ] 46 | 47 | export function SideBar() { 48 | const isSideBarVisible = useMediaQuery({minWidth: 500}) 49 | const isFullSideBar = useMediaQuery({minWidth: 1266}) 50 | const isRightBarVisible = useMediaQuery({minWidth: 990}) 51 | 52 | if (!isSideBarVisible) return null 53 | 54 | if (isSideBarVisible) { 55 | return ( 56 | 77 | 83 | [ 85 | { 86 | borderRadius: 100, 87 | marginStart: 4, 88 | marginTop: 5, 89 | ...Platform.select({ 90 | web: { 91 | cursor: 'pointer', 92 | }, 93 | }), 94 | }, 95 | hovered 96 | ? { 97 | backgroundColor: colors.COLOR_BLACK_LIGHT_6, 98 | } 99 | : {}, 100 | ]}> 101 | 112 | 113 | {sideBarData.map(({title, iconName}) => { 114 | return 115 | })} 116 |