diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -81,4 +81,4 @@
contrib/devtools/split-debug.sh
# Ignore node_modules at every level
-node_modules/
+node_modules/
\ No newline at end of file
diff --git a/web/cashtab/.gitignore b/web/cashtab/.gitignore
--- a/web/cashtab/.gitignore
+++ b/web/cashtab/.gitignore
@@ -26,4 +26,10 @@
*.crx
*.zip
*.pem
-dist/
\ No newline at end of file
+dist/
+
+# Ignore fbt generated files
+.source_strings.json
+.src_manifest.json
+.enum_manifest.json
+src/translatedFbts.json
diff --git a/web/cashtab/config/paths.js b/web/cashtab/config/paths.js
--- a/web/cashtab/config/paths.js
+++ b/web/cashtab/config/paths.js
@@ -70,6 +70,8 @@
appBuild: resolveApp('build'),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
+ appI18nJs: resolveApp('src/i18n/init.js'),
+ appI18n: resolveApp('src/i18n'),
appIndexJs: resolveModule(resolveApp, 'src/index'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
diff --git a/web/cashtab/config/webpack.config.js b/web/cashtab/config/webpack.config.js
--- a/web/cashtab/config/webpack.config.js
+++ b/web/cashtab/config/webpack.config.js
@@ -269,9 +269,11 @@
// the line below with these two lines if you prefer the stock client:
// require.resolve('webpack-dev-server/client') + '?/',
// require.resolve('webpack/hot/dev-server'),
+
isEnvDevelopment &&
require.resolve('react-dev-utils/webpackHotDevClient'),
// Finally, this is your app's code:
+ paths.appI18nJs,
paths.appIndexJs,
// We include the app code last so that if there is a runtime error during
// initialization, it doesn't blow up the WebpackDevServer client, and
@@ -395,9 +397,11 @@
// We placed these paths second because we want `node_modules` to "win"
// if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebook/create-react-app/issues/253
- modules: ['node_modules', paths.appNodeModules].concat(
- modules.additionalModulePaths || [],
- ),
+ modules: [
+ 'node_modules',
+ paths.appI18n,
+ paths.appNodeModules,
+ ].concat(modules.additionalModulePaths || []),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
@@ -498,6 +502,17 @@
},
},
],
+ [
+ 'babel-plugin-fbt',
+ {
+ fbtEnumPath: path.join(
+ paths.appPath,
+ '.enum_manifest.json',
+ ),
+ extraOptions: { __self: true },
+ },
+ ],
+ 'babel-plugin-fbt-runtime',
],
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
diff --git a/web/cashtab/package-lock.json b/web/cashtab/package-lock.json
--- a/web/cashtab/package-lock.json
+++ b/web/cashtab/package-lock.json
@@ -9,7 +9,6 @@
"dependencies": {
"@ant-design/dark-theme": "^1.0.3",
"@ant-design/icons": "^4.2.2",
- "@babel/core": "7.6.0",
"@fortawesome/fontawesome-free": "^5.15.1",
"@psf/bch-js": "^3.9.1",
"@svgr/webpack": "4.3.2",
@@ -41,6 +40,7 @@
"eslint-plugin-react": "7.14.3",
"eslint-plugin-react-hooks": "^1.6.1",
"ethereum-blockies-base64": "^1.0.2",
+ "fbt": "^0.16.0",
"file-loader": "3.0.1",
"fs-extra": "7.0.1",
"gh-pages": "^2.1.1",
@@ -91,7 +91,12 @@
"webpack-manifest-plugin": "2.0.4"
},
"devDependencies": {
+ "@babel/core": "^7.6.0",
+ "@babel/node": "^7.12.6",
"@testing-library/react": "^11.1.0",
+ "babel-plugin-fbt": "^0.16.0",
+ "babel-plugin-fbt-runtime": "^0.9.12",
+ "fbt-generate-translations": "^0.0.4",
"less": "^3.10.3",
"less-loader": "^5.0.0",
"react-test-renderer": "^17.0.0",
@@ -492,6 +497,61 @@
"js-tokens": "^4.0.0"
}
},
+ "node_modules/@babel/node": {
+ "version": "7.12.6",
+ "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.12.6.tgz",
+ "integrity": "sha512-A1TpW2X05ZkI5+WV7Aa24QX4LyGwrGUQPflG1CyBdr84jUuH0mhkE2BQWSQAlfRnp4bMLjeveMJIhS20JaOfVQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/register": "^7.12.1",
+ "commander": "^4.0.1",
+ "core-js": "^3.2.1",
+ "lodash": "^4.17.19",
+ "node-environment-flags": "^1.0.5",
+ "regenerator-runtime": "^0.13.4",
+ "resolve": "^1.13.1",
+ "v8flags": "^3.1.1"
+ },
+ "bin": {
+ "babel-node": "bin/babel-node.js"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/node/node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@babel/node/node_modules/core-js": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.0.tgz",
+ "integrity": "sha512-W2VYNB0nwQQE7tKS7HzXd7r2y/y2SVJl4ga6oH/dnaLFzM0o2lB2P3zCkWj5Wc/zyMYjtgd5Hmhk0ObkQFZOIA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/@babel/node/node_modules/resolve": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
+ "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.1.0",
+ "path-parse": "^1.0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/@babel/parser": {
"version": "7.12.7",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz",
@@ -1511,6 +1571,44 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/register": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.12.1.tgz",
+ "integrity": "sha512-XWcmseMIncOjoydKZnWvWi0/5CUCD+ZYKhRwgYlWOrA8fGZ/FjuLRpqtIhLOVD/fvR1b9DQHtZPn68VvhpYf+Q==",
+ "dev": true,
+ "dependencies": {
+ "find-cache-dir": "^2.0.0",
+ "lodash": "^4.17.19",
+ "make-dir": "^2.1.0",
+ "pirates": "^4.0.0",
+ "source-map-support": "^0.5.16"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/register/node_modules/make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "dependencies": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@babel/register/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
"node_modules/@babel/runtime": {
"version": "7.12.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
@@ -5632,6 +5730,174 @@
"object.assign": "^4.1.0"
}
},
+ "node_modules/babel-plugin-fbt": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-fbt/-/babel-plugin-fbt-0.16.0.tgz",
+ "integrity": "sha512-A38Gy+OuPh6g3wXKeR1rSqLUbLzRnF9CkrQN8482xNjlMAbt1M76zePx7j+6H9QYSuyUqMC4HDHmOSaAHHi5oA==",
+ "dependencies": {
+ "@babel/core": "^7.0.0",
+ "@babel/generator": "^7.0.0",
+ "@babel/plugin-syntax-object-rest-spread": "^7.2.0",
+ "@babel/plugin-transform-flow-strip-types": "^7.2.0",
+ "@babel/plugin-transform-modules-commonjs": "^7.8.3",
+ "@babel/types": "^7.2.2",
+ "fb-babel-plugin-utils": "^0.11.0",
+ "glob": "^7.1.6",
+ "invariant": "^2.2.4",
+ "jest-docblock": "^26.0.0",
+ "nullthrows": "^1.1.1",
+ "shelljs": "^0.8.4",
+ "yargs": "^15.3.1"
+ },
+ "bin": {
+ "fbt-collect": "bin/collectFBT.bin.js",
+ "fbt-manifest": "bin/manifest.bin.js",
+ "fbt-translate": "bin/translate.bin.js"
+ }
+ },
+ "node_modules/babel-plugin-fbt-runtime": {
+ "version": "0.9.12",
+ "resolved": "https://registry.npmjs.org/babel-plugin-fbt-runtime/-/babel-plugin-fbt-runtime-0.9.12.tgz",
+ "integrity": "sha512-YbSWgNzNBoRF6golLWvpSg2HA0SwKCUSoI0Syl0y846cYfq5ZzFKuCQt9zRFkmaWFQ1ncuI4wHRznchFreQi9g==",
+ "dependencies": {
+ "@babel/core": "^7.0.0",
+ "fbjs": "^1.0.0"
+ },
+ "peerDependencies": {
+ "babel-plugin-fbt": "^0.14.2"
+ }
+ },
+ "node_modules/babel-plugin-fbt-runtime/node_modules/fbjs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-1.0.0.tgz",
+ "integrity": "sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==",
+ "dependencies": {
+ "core-js": "^2.4.1",
+ "fbjs-css-vars": "^1.0.0",
+ "isomorphic-fetch": "^2.1.1",
+ "loose-envify": "^1.0.0",
+ "object-assign": "^4.1.0",
+ "promise": "^7.1.1",
+ "setimmediate": "^1.0.5",
+ "ua-parser-js": "^0.7.18"
+ }
+ },
+ "node_modules/babel-plugin-fbt/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/babel-plugin-fbt/node_modules/cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "node_modules/babel-plugin-fbt/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/babel-plugin-fbt/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/babel-plugin-fbt/node_modules/detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-fbt/node_modules/jest-docblock": {
+ "version": "26.0.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz",
+ "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==",
+ "dependencies": {
+ "detect-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 10.14.2"
+ }
+ },
+ "node_modules/babel-plugin-fbt/node_modules/strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dependencies": {
+ "ansi-regex": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-fbt/node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-fbt/node_modules/yargs": {
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "dependencies": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-fbt/node_modules/yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "dependencies": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/babel-plugin-istanbul": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz",
@@ -7291,6 +7557,25 @@
"node": "*"
}
},
+ "node_modules/cli-color": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-0.1.7.tgz",
+ "integrity": "sha1-rcMgD6RxzCEbDaf1ZrcemLnWc0c=",
+ "dependencies": {
+ "es5-ext": "0.8.x"
+ },
+ "engines": {
+ "node": ">=0.1.103"
+ }
+ },
+ "node_modules/cli-color/node_modules/es5-ext": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.8.2.tgz",
+ "integrity": "sha1-q6jZ4ZQ6iVrJaDemKjmz9V7NlKs=",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
"node_modules/cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -8723,6 +9008,17 @@
"randombytes": "^2.0.0"
}
},
+ "node_modules/difflib": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz",
+ "integrity": "sha1-teMDYabbAjF21WKJLbhZQKcY9H4=",
+ "dependencies": {
+ "heap": ">= 0.2.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/dijkstrajs": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz",
@@ -8954,6 +9250,17 @@
"node": ">=0.10"
}
},
+ "node_modules/dreamopt": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/dreamopt/-/dreamopt-0.6.0.tgz",
+ "integrity": "sha1-2BPM2sjTnYrVJndVFKE92mZNa0s=",
+ "dependencies": {
+ "wordwrap": ">=0.0.2"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@@ -10471,6 +10778,25 @@
"node": ">=0.8.0"
}
},
+ "node_modules/fb-babel-plugin-utils": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/fb-babel-plugin-utils/-/fb-babel-plugin-utils-0.11.0.tgz",
+ "integrity": "sha512-xJ9j9hlFjbbH0yrkVCZTHpmd9EN46+rxEwZLrg+TbF1DegwXnNFT5MF/U+iQgeMhQVGWmhkR1ez0AGOBwX/cKA==",
+ "dependencies": {
+ "@babel/core": "^7.0.0",
+ "@babel/generator": "^7.0.0",
+ "@babel/parser": "^7.7.4",
+ "@babel/plugin-syntax-class-properties": "^7.0.0",
+ "@babel/plugin-syntax-flow": "^7.7.4",
+ "@babel/plugin-syntax-jsx": "^7.0.0",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0",
+ "@babel/plugin-syntax-numeric-separator": "^7.2.0",
+ "@babel/plugin-syntax-object-rest-spread": "^7.0.0",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.0.0",
+ "@babel/plugin-syntax-optional-chaining": "^7.0.0",
+ "json-diff": "^0.5.4"
+ }
+ },
"node_modules/fb-watchman": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
@@ -10493,12 +10819,40 @@
"ua-parser-js": "^0.7.18"
}
},
+ "node_modules/fbjs-css-vars": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
+ "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="
+ },
"node_modules/fbjs/node_modules/core-js": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=",
"deprecated": "core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3."
},
+ "node_modules/fbt": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/fbt/-/fbt-0.16.0.tgz",
+ "integrity": "sha512-QT5K+aF2b/7CH4takZeYIBAqH9cATV2IXV5kCmI5lWfPMssv34sDbBYJjoWNEV3nU/kDBogCr3QOahuOh8hPMw==",
+ "dependencies": {
+ "invariant": "^2.2.4"
+ },
+ "peerDependencies": {
+ "babel-plugin-fbt": "^0.10.x",
+ "babel-plugin-fbt-runtime": "^0.9.x",
+ "react": "0.12.0 - 16.x.x"
+ }
+ },
+ "node_modules/fbt-generate-translations": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/fbt-generate-translations/-/fbt-generate-translations-0.0.4.tgz",
+ "integrity": "sha512-j+1+ZE6Ce1hl2GQHfyYNEIRN2gtFyukRafKPtdghiSmXB7jOPJxGIF+Jsm+JcZQYAQexdoX4nvSZqZBI84dc0Q==",
+ "dev": true,
+ "dependencies": {
+ "assert": "^2.0.0",
+ "yargs": "^13.3.0"
+ }
+ },
"node_modules/fecha": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz",
@@ -11748,6 +12102,11 @@
"he": "bin/he"
}
},
+ "node_modules/heap": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz",
+ "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw="
+ },
"node_modules/hex-color-regex": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
@@ -11789,6 +12148,18 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "node_modules/homedir-polyfill": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+ "dev": true,
+ "dependencies": {
+ "parse-passwd": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/hosted-git-info": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
@@ -12523,6 +12894,14 @@
"node": ">=6"
}
},
+ "node_modules/interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@@ -16617,6 +16996,22 @@
"node": ">=4"
}
},
+ "node_modules/json-diff": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/json-diff/-/json-diff-0.5.4.tgz",
+ "integrity": "sha512-q5Xmx9QXNOzOzIlMoYtLrLiu4Jl/Ce2bn0CNcv54PhyH89CI4GWlGVDye8ei2Ijt9R3U+vsWPsXpLUNob8bs8Q==",
+ "dependencies": {
+ "cli-color": "~0.1.6",
+ "difflib": "~0.2.1",
+ "dreamopt": "~0.6.0"
+ },
+ "bin": {
+ "json-diff": "bin/json-diff.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/json-parse-better-errors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@@ -18232,6 +18627,25 @@
"lodash.toarray": "^4.4.0"
}
},
+ "node_modules/node-environment-flags": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
+ "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
+ "dev": true,
+ "dependencies": {
+ "object.getownpropertydescriptors": "^2.0.3",
+ "semver": "^5.7.0"
+ }
+ },
+ "node_modules/node-environment-flags/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
"node_modules/node-fetch": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
@@ -18492,6 +18906,11 @@
"boolbase": "~1.0.0"
}
},
+ "node_modules/nullthrows": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
+ "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="
+ },
"node_modules/num2fraction": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
@@ -19445,6 +19864,15 @@
"node": ">=4"
}
},
+ "node_modules/parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/parse5": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
@@ -23266,6 +23694,17 @@
"node": ">=4"
}
},
+ "node_modules/rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+ "dependencies": {
+ "resolve": "^1.1.6"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/recursive-readdir": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
@@ -24554,6 +24993,22 @@
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
"integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg=="
},
+ "node_modules/shelljs": {
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
+ "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
+ "dependencies": {
+ "glob": "^7.0.0",
+ "interpret": "^1.0.0",
+ "rechoir": "^0.6.2"
+ },
+ "bin": {
+ "shjs": "bin/shjs"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/shellwords": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
@@ -27224,6 +27679,18 @@
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz",
"integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q=="
},
+ "node_modules/v8flags": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz",
+ "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==",
+ "dev": true,
+ "dependencies": {
+ "homedir-polyfill": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -28030,6 +28497,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
+ },
"node_modules/workbox-background-sync": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz",
@@ -28825,6 +29297,46 @@
"js-tokens": "^4.0.0"
}
},
+ "@babel/node": {
+ "version": "7.12.6",
+ "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.12.6.tgz",
+ "integrity": "sha512-A1TpW2X05ZkI5+WV7Aa24QX4LyGwrGUQPflG1CyBdr84jUuH0mhkE2BQWSQAlfRnp4bMLjeveMJIhS20JaOfVQ==",
+ "dev": true,
+ "requires": {
+ "@babel/register": "^7.12.1",
+ "commander": "^4.0.1",
+ "core-js": "^3.2.1",
+ "lodash": "^4.17.19",
+ "node-environment-flags": "^1.0.5",
+ "regenerator-runtime": "^0.13.4",
+ "resolve": "^1.13.1",
+ "v8flags": "^3.1.1"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true
+ },
+ "core-js": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.0.tgz",
+ "integrity": "sha512-W2VYNB0nwQQE7tKS7HzXd7r2y/y2SVJl4ga6oH/dnaLFzM0o2lB2P3zCkWj5Wc/zyMYjtgd5Hmhk0ObkQFZOIA==",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
+ "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.1.0",
+ "path-parse": "^1.0.6"
+ }
+ }
+ }
+ },
"@babel/parser": {
"version": "7.12.7",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz",
@@ -29599,6 +30111,37 @@
"@babel/plugin-transform-typescript": "^7.9.0"
}
},
+ "@babel/register": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.12.1.tgz",
+ "integrity": "sha512-XWcmseMIncOjoydKZnWvWi0/5CUCD+ZYKhRwgYlWOrA8fGZ/FjuLRpqtIhLOVD/fvR1b9DQHtZPn68VvhpYf+Q==",
+ "dev": true,
+ "requires": {
+ "find-cache-dir": "^2.0.0",
+ "lodash": "^4.17.19",
+ "make-dir": "^2.1.0",
+ "pirates": "^4.0.0",
+ "source-map-support": "^0.5.16"
+ },
+ "dependencies": {
+ "make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "requires": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ }
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ }
+ }
+ },
"@babel/runtime": {
"version": "7.12.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
@@ -32905,6 +33448,143 @@
"object.assign": "^4.1.0"
}
},
+ "babel-plugin-fbt": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-fbt/-/babel-plugin-fbt-0.16.0.tgz",
+ "integrity": "sha512-A38Gy+OuPh6g3wXKeR1rSqLUbLzRnF9CkrQN8482xNjlMAbt1M76zePx7j+6H9QYSuyUqMC4HDHmOSaAHHi5oA==",
+ "requires": {
+ "@babel/core": "^7.0.0",
+ "@babel/generator": "^7.0.0",
+ "@babel/plugin-syntax-object-rest-spread": "^7.2.0",
+ "@babel/plugin-transform-flow-strip-types": "^7.2.0",
+ "@babel/plugin-transform-modules-commonjs": "^7.8.3",
+ "@babel/types": "^7.2.2",
+ "fb-babel-plugin-utils": "^0.11.0",
+ "glob": "^7.1.6",
+ "invariant": "^2.2.4",
+ "jest-docblock": "^26.0.0",
+ "nullthrows": "^1.1.1",
+ "shelljs": "^0.8.4",
+ "yargs": "^15.3.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA=="
+ },
+ "jest-docblock": {
+ "version": "26.0.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz",
+ "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==",
+ "requires": {
+ "detect-newline": "^3.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "yargs": {
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "requires": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
+ "babel-plugin-fbt-runtime": {
+ "version": "0.9.12",
+ "resolved": "https://registry.npmjs.org/babel-plugin-fbt-runtime/-/babel-plugin-fbt-runtime-0.9.12.tgz",
+ "integrity": "sha512-YbSWgNzNBoRF6golLWvpSg2HA0SwKCUSoI0Syl0y846cYfq5ZzFKuCQt9zRFkmaWFQ1ncuI4wHRznchFreQi9g==",
+ "requires": {
+ "@babel/core": "^7.0.0",
+ "fbjs": "^1.0.0"
+ },
+ "dependencies": {
+ "fbjs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-1.0.0.tgz",
+ "integrity": "sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==",
+ "requires": {
+ "core-js": "^2.4.1",
+ "fbjs-css-vars": "^1.0.0",
+ "isomorphic-fetch": "^2.1.1",
+ "loose-envify": "^1.0.0",
+ "object-assign": "^4.1.0",
+ "promise": "^7.1.1",
+ "setimmediate": "^1.0.5",
+ "ua-parser-js": "^0.7.18"
+ }
+ }
+ }
+ },
"babel-plugin-istanbul": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz",
@@ -34307,6 +34987,21 @@
"resolved": "https://registry.npmjs.org/clear/-/clear-0.1.0.tgz",
"integrity": "sha512-qMjRnoL+JDPJHeLePZJuao6+8orzHMGP04A8CdwCNsKhRbOnKRjefxONR7bwILT3MHecxKBjHkKL/tkZ8r4Uzw=="
},
+ "cli-color": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-0.1.7.tgz",
+ "integrity": "sha1-rcMgD6RxzCEbDaf1ZrcemLnWc0c=",
+ "requires": {
+ "es5-ext": "0.8.x"
+ },
+ "dependencies": {
+ "es5-ext": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.8.2.tgz",
+ "integrity": "sha1-q6jZ4ZQ6iVrJaDemKjmz9V7NlKs="
+ }
+ }
+ },
"cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -35498,6 +36193,14 @@
"randombytes": "^2.0.0"
}
},
+ "difflib": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz",
+ "integrity": "sha1-teMDYabbAjF21WKJLbhZQKcY9H4=",
+ "requires": {
+ "heap": ">= 0.2.0"
+ }
+ },
"dijkstrajs": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz",
@@ -35694,6 +36397,14 @@
"create-hmac": "^1.1.4"
}
},
+ "dreamopt": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/dreamopt/-/dreamopt-0.6.0.tgz",
+ "integrity": "sha1-2BPM2sjTnYrVJndVFKE92mZNa0s=",
+ "requires": {
+ "wordwrap": ">=0.0.2"
+ }
+ },
"duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@@ -36944,6 +37655,25 @@
"websocket-driver": ">=0.5.1"
}
},
+ "fb-babel-plugin-utils": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/fb-babel-plugin-utils/-/fb-babel-plugin-utils-0.11.0.tgz",
+ "integrity": "sha512-xJ9j9hlFjbbH0yrkVCZTHpmd9EN46+rxEwZLrg+TbF1DegwXnNFT5MF/U+iQgeMhQVGWmhkR1ez0AGOBwX/cKA==",
+ "requires": {
+ "@babel/core": "^7.0.0",
+ "@babel/generator": "^7.0.0",
+ "@babel/parser": "^7.7.4",
+ "@babel/plugin-syntax-class-properties": "^7.0.0",
+ "@babel/plugin-syntax-flow": "^7.7.4",
+ "@babel/plugin-syntax-jsx": "^7.0.0",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0",
+ "@babel/plugin-syntax-numeric-separator": "^7.2.0",
+ "@babel/plugin-syntax-object-rest-spread": "^7.0.0",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.0.0",
+ "@babel/plugin-syntax-optional-chaining": "^7.0.0",
+ "json-diff": "^0.5.4"
+ }
+ },
"fb-watchman": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
@@ -36973,6 +37703,29 @@
}
}
},
+ "fbjs-css-vars": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
+ "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="
+ },
+ "fbt": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/fbt/-/fbt-0.16.0.tgz",
+ "integrity": "sha512-QT5K+aF2b/7CH4takZeYIBAqH9cATV2IXV5kCmI5lWfPMssv34sDbBYJjoWNEV3nU/kDBogCr3QOahuOh8hPMw==",
+ "requires": {
+ "invariant": "^2.2.4"
+ }
+ },
+ "fbt-generate-translations": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/fbt-generate-translations/-/fbt-generate-translations-0.0.4.tgz",
+ "integrity": "sha512-j+1+ZE6Ce1hl2GQHfyYNEIRN2gtFyukRafKPtdghiSmXB7jOPJxGIF+Jsm+JcZQYAQexdoX4nvSZqZBI84dc0Q==",
+ "dev": true,
+ "requires": {
+ "assert": "^2.0.0",
+ "yargs": "^13.3.0"
+ }
+ },
"fecha": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz",
@@ -37969,6 +38722,11 @@
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
},
+ "heap": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz",
+ "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw="
+ },
"hex-color-regex": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
@@ -38012,6 +38770,15 @@
}
}
},
+ "homedir-polyfill": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+ "dev": true,
+ "requires": {
+ "parse-passwd": "^1.0.0"
+ }
+ },
"hosted-git-info": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
@@ -38603,6 +39370,11 @@
"ipaddr.js": "^1.9.0"
}
},
+ "interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="
+ },
"invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@@ -41852,6 +42624,16 @@
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
},
+ "json-diff": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/json-diff/-/json-diff-0.5.4.tgz",
+ "integrity": "sha512-q5Xmx9QXNOzOzIlMoYtLrLiu4Jl/Ce2bn0CNcv54PhyH89CI4GWlGVDye8ei2Ijt9R3U+vsWPsXpLUNob8bs8Q==",
+ "requires": {
+ "cli-color": "~0.1.6",
+ "difflib": "~0.2.1",
+ "dreamopt": "~0.6.0"
+ }
+ },
"json-parse-better-errors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@@ -43163,6 +43945,24 @@
"lodash.toarray": "^4.4.0"
}
},
+ "node-environment-flags": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
+ "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
+ "dev": true,
+ "requires": {
+ "object.getownpropertydescriptors": "^2.0.3",
+ "semver": "^5.7.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ }
+ }
+ },
"node-fetch": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
@@ -43398,6 +44198,11 @@
"boolbase": "~1.0.0"
}
},
+ "nullthrows": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
+ "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="
+ },
"num2fraction": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
@@ -44131,6 +44936,12 @@
"json-parse-better-errors": "^1.0.1"
}
},
+ "parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+ "dev": true
+ },
"parse5": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
@@ -47342,6 +48153,14 @@
"util.promisify": "^1.0.0"
}
},
+ "rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+ "requires": {
+ "resolve": "^1.1.6"
+ }
+ },
"recursive-readdir": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
@@ -48361,6 +49180,16 @@
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
"integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg=="
},
+ "shelljs": {
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
+ "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
+ "requires": {
+ "glob": "^7.0.0",
+ "interpret": "^1.0.0",
+ "rechoir": "^0.6.2"
+ }
+ },
"shellwords": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
@@ -50590,6 +51419,15 @@
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz",
"integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q=="
},
+ "v8flags": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz",
+ "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==",
+ "dev": true,
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
"validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -51248,6 +52086,11 @@
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
},
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
+ },
"workbox-background-sync": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz",
diff --git a/web/cashtab/package.json b/web/cashtab/package.json
--- a/web/cashtab/package.json
+++ b/web/cashtab/package.json
@@ -6,7 +6,6 @@
"dependencies": {
"@ant-design/dark-theme": "^1.0.3",
"@ant-design/icons": "^4.2.2",
- "@babel/core": "7.6.0",
"@fortawesome/fontawesome-free": "^5.15.1",
"@psf/bch-js": "^3.9.1",
"@svgr/webpack": "4.3.2",
@@ -38,6 +37,7 @@
"eslint-plugin-react": "7.14.3",
"eslint-plugin-react-hooks": "^1.6.1",
"ethereum-blockies-base64": "^1.0.2",
+ "fbt": "^0.16.0",
"file-loader": "3.0.1",
"fs-extra": "7.0.1",
"gh-pages": "^2.1.1",
@@ -94,12 +94,22 @@
]
},
"scripts": {
+ "manifest-fbts": "NODE_ENV=production node node_modules/babel-plugin-fbt/bin/manifest --src src",
+ "collect-fbts": "NODE_ENV=production node node_modules/babel-plugin-fbt/bin/collectFBT --pretty --manifest < .src_manifest.json > .source_strings.json",
+ "translate-fbts": "NODE_ENV=production node node_modules/babel-plugin-fbt/bin/translate.js --pretty --translations translations/*.json --jenkins > src/translatedFbts.json",
+ "translate-fbts-single-file": "NODE_ENV=production node node_modules/babel-plugin-fbt/bin/translate.js --pretty --jenkins --stdin < translation_input.json > src/translatedFbts.json",
+ "clean-fbts": "rm .enum_manifest.json .src_manifest.json .source_strings.json src/translatedFbts.json 2&> /dev/null || exit 0",
+ "fbt-generate-translations": "NODE_ENV=production node node_modules/fbt-generate-translations --locales src/i18n/locales.js --multi-files translations",
+ "fbt-generate-translations-single-file": "NODE_ENV=production node node_modules/fbt-generate-translations --locales src/i18n/locales.js",
+ "prepare-fbts": "NODE_ENV=production npm run manifest-fbts && npm run collect-fbts && npm run fbt-generate-translations && npm run translate-fbts",
+ "prestart": "npm run prepare-fbts",
+ "prebuild": "npm run prepare-fbts",
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"extension": "./scripts/extension.sh",
"predeploy": "npm run build",
"test": "node scripts/test.js",
- "test:coverage": "yarn test --coverage --watchAll=false",
+ "test:coverage": "npm run test --coverage --watchAll=false",
"debug": "node --inspect-brk=9229 scripts/start.js"
},
"eslintConfig": {
@@ -179,7 +189,12 @@
]
},
"devDependencies": {
+ "@babel/core": "^7.6.0",
+ "@babel/node": "^7.12.6",
"@testing-library/react": "^11.1.0",
+ "babel-plugin-fbt": "^0.16.0",
+ "babel-plugin-fbt-runtime": "^0.9.12",
+ "fbt-generate-translations": "^0.0.4",
"less": "^3.10.3",
"less-loader": "^5.0.0",
"react-test-renderer": "^17.0.0",
diff --git a/web/cashtab/src/components/App.js b/web/cashtab/src/components/App.js
--- a/web/cashtab/src/components/App.js
+++ b/web/cashtab/src/components/App.js
@@ -20,6 +20,7 @@
useHistory,
} from 'react-router-dom';
+import fbt from 'fbt';
const { Footer } = Layout;
const { TabPane } = Tabs;
@@ -216,7 +217,9 @@
type="folder-open"
theme="filled"
/>
- Wallet
+
+ Wallet
+
}
key="wallet"
@@ -232,7 +235,9 @@
type="caret-right"
theme="filled"
/>
- Send
+
+ Send
+
}
key="send"
@@ -249,7 +254,9 @@
type="setting"
theme="filled"
/>
- Settings
+
+ Settings
+
}
key="configure"
diff --git a/web/cashtab/src/i18n/init.js b/web/cashtab/src/i18n/init.js
new file mode 100644
--- /dev/null
+++ b/web/cashtab/src/i18n/init.js
@@ -0,0 +1,15 @@
+import { init } from 'fbt';
+import translations from '../translatedFbts.json';
+import locales from './locales';
+const viewerContext = {
+ locale: navigator.language.replace('-', '_'),
+};
+
+init({
+ translations,
+ hooks: {
+ getViewerContext: () => viewerContext,
+ },
+ locales,
+ defaultLocale: navigator.language,
+});
diff --git a/web/cashtab/src/i18n/locales.js b/web/cashtab/src/i18n/locales.js
new file mode 100644
--- /dev/null
+++ b/web/cashtab/src/i18n/locales.js
@@ -0,0 +1,14 @@
+module.exports = {
+ en_US: {
+ bcp47: 'en-US',
+ displayName: 'English (US)',
+ englishName: 'English (US)',
+ rtl: false,
+ },
+ pt_BR: {
+ bcp47: 'pt-BR',
+ displayName: 'Português (Brasil)',
+ englishName: 'Portuguese (Brazilian)',
+ rtl: false,
+ },
+};
diff --git a/web/cashtab/translations/en_US.json b/web/cashtab/translations/en_US.json
new file mode 100644
--- /dev/null
+++ b/web/cashtab/translations/en_US.json
@@ -0,0 +1,26 @@
+{
+ "fb-locale": "en_US",
+ "translations": {
+ "t+5SwD1ho9xhYy5PlfAPGg==": {
+ "translations": [
+ {
+ "translation": "Wallet"
+ }
+ ]
+ },
+ "fXmXHZxGc0NA87a+A1ppng==": {
+ "translations": [
+ {
+ "translation": "Send"
+ }
+ ]
+ },
+ "M8PvPwXAFjS9vGdEg8xnWw==": {
+ "translations": [
+ {
+ "translation": "Settings"
+ }
+ ]
+ }
+ }
+}
diff --git a/web/cashtab/translations/pt_BR.json b/web/cashtab/translations/pt_BR.json
new file mode 100644
--- /dev/null
+++ b/web/cashtab/translations/pt_BR.json
@@ -0,0 +1,26 @@
+{
+ "fb-locale": "pt_BR",
+ "translations": {
+ "t+5SwD1ho9xhYy5PlfAPGg==": {
+ "translations": [
+ {
+ "translation": "Carteira"
+ }
+ ]
+ },
+ "fXmXHZxGc0NA87a+A1ppng==": {
+ "translations": [
+ {
+ "translation": "Enviar"
+ }
+ ]
+ },
+ "M8PvPwXAFjS9vGdEg8xnWw==": {
+ "translations": [
+ {
+ "translation": "Opções"
+ }
+ ]
+ }
+ }
+}