[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2.0\njobs:\n  test:\n    docker:\n      - image: circleci/node:12-browsers\n    steps:\n      - checkout\n      - run: npm ci\n      - run: npm run lint\n      - run: npm test\n      - store_artifacts:\n          path: coverage\n  integration_tests:\n    docker:\n      - image: circleci/node:12-browsers\n    steps:\n      - checkout\n      - run: npm ci\n      - run:\n          name: Run integration test\n          command: ./scripts/bin/run-integration-test-circleci.sh\n  deploy_dev:\n    docker:\n      - image: circleci/node:12\n    steps:\n      - checkout\n      - setup_remote_docker\n      - run: docker login -u $DOCKER_USER -p $DOCKER_PASS\n      - run: docker build -t mozilla/send:latest .\n      - run: docker push mozilla/send:latest\n  deploy_vnext:\n    docker:\n      - image: circleci/node:12\n    steps:\n      - checkout\n      - setup_remote_docker\n      - run: docker login -u $DOCKER_USER -p $DOCKER_PASS\n      - run: docker build -t mozilla/send:vnext .\n      - run: docker push mozilla/send:vnext\n  deploy_stage:\n    docker:\n      - image: circleci/node:12\n    steps:\n      - checkout\n      - setup_remote_docker\n      - run: docker login -u $DOCKER_USER -p $DOCKER_PASS\n      - run: docker build -t mozilla/send:$CIRCLE_TAG .\n      - run: docker push mozilla/send:$CIRCLE_TAG\nworkflows:\n  version: 2\n  test_pr:\n    jobs:\n      - test:\n          filters:\n            branches:\n              ignore:\n                - master\n                - vnext\n      - integration_tests:\n          filters:\n            branches:\n              ignore: master\n  build_and_deploy_dev:\n    jobs:\n      - deploy_dev:\n          filters:\n            branches:\n              only: master\n            tags:\n              ignore: /^v.*/\n      - deploy_vnext:\n          filters:\n            branches:\n              only: vnext\n            tags:\n              ignore: /^v.*/\n  build_and_deploy_stage:\n    jobs:\n      - test:\n          filters:\n            branches:\n              ignore: /.*/\n            tags:\n              only: /^v.*/\n      - integration_tests:\n          filters:\n            branches:\n              ignore: /.*/\n            tags:\n              only: /^v.*/\n      - deploy_stage:\n          requires:\n            - test\n            - integration_tests\n          filters:\n            branches:\n              ignore: /.*/\n            tags:\n              only: /^v.*/\n"
  },
  {
    "path": ".dockerignore",
    "content": ".circleci\n.nyc_output\n.vscode\n.DS_Store\ncoverage\ndocs\nfirefox\nnode_modules"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\n\n[*.{js,html,yml,json,handlebars}]\nindent_style = space\nindent_size = 2\n\n[*.toml]\nindent_style = space\nindent_size = 4\n"
  },
  {
    "path": ".eslintignore",
    "content": "dist\nassets\nfirefox\ncoverage\nandroid/app/build\napp/locale.js\napp/capabilities.js"
  },
  {
    "path": ".eslintrc.yml",
    "content": "env:\n  es6: true\n  node: true\n\nextends:\n  - eslint:recommended\n  - prettier\n  - plugin:node/recommended\n  - plugin:security/recommended\n\nplugins:\n  - node\n  - security\n\nroot: true\n\nrules:\n  node/no-deprecated-api: off\n  node/no-unsupported-features/es-syntax: off\n  node/no-unsupported-features/node-builtins: off\n  node/no-unpublished-require: off\n  node/no-unpublished-import: off\n\n  security/detect-non-literal-fs-filename: off\n  security/detect-object-injection: off\n\n  no-unused-vars: [error, {argsIgnorePattern: \"^_|err|event|next|reject\"}]\n  require-atomic-updates: warn\n"
  },
  {
    "path": ".gitattributes",
    "content": "public/locales/* linguist-documentation\ndocs/* linguist-documentation\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\ncoverage\ndist\n.idea\n.DS_Store\n.nyc_output\n.tox\n.pytest_cache\n*.iml\nandroid/app/src/main/assets\nios/send-ios/assets/ios.js\nios/send-ios/assets/vendor.js\nios/send-ios.xcodeproj/project.xcworkspace/xcuserdata/*\nios/send-ios.xcodeproj/xcuserdata/*\ntest/integration/downloads\n"
  },
  {
    "path": ".htmllintrc",
    "content": "{\n  \"attr-name-style\": \"dash\",\n  \"id-class-style\": \"dash\",\n  \"indent-width\": 2\n}\n"
  },
  {
    "path": ".prettierignore",
    "content": "dist\nandroid/app/src/main/assets\nandroid/app/build\ncoverage"
  },
  {
    "path": ".stylelintrc",
    "content": "extends: stylelint-config-standard\n\nplugins:\n  - stylelint-no-unsupported-browser-features\n\nrules:\n  plugin/no-unsupported-browser-features: [true, {severity: warning}]\n\n  color-hex-case: lower\n  declaration-colon-newline-after: null\n  selector-list-comma-newline-after: null\n  value-list-comma-newline-after: null\n  at-rule-no-unknown: null\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n}"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## Change Log\n\n### v2.5.1 (2018/03/12 19:26 +00:00)\n- [#789](https://github.com/mozilla/send/pull/789) Fixed #775 : Made text not-selectable (@RCMainak)\n\n### v2.5.0 (2018/03/08 19:31 +00:00)\n- [#782](https://github.com/mozilla/send/pull/782) updated docs (@dannycoates)\n- [#781](https://github.com/mozilla/send/pull/781) Don't translate URL-safe chars, b64 is doing it for us (@timvisee)\n- [#779](https://github.com/mozilla/send/pull/779) implemented crypto polyfills for ms edge (@dannycoates)\n\n### v2.4.1 (2018/02/28 17:05 +00:00)\n- [#777](https://github.com/mozilla/send/pull/777) use a separate circle in the progress svg for indefinite progress (@dannycoates)\n\n### v2.4.0 (2018/02/27 01:55 +00:00)\n- [#769](https://github.com/mozilla/send/pull/769) removed unsafe-inline styles via svgo-loader (@dannycoates)\n- [#767](https://github.com/mozilla/send/pull/767) added coverage artifact to circleci (@dannycoates)\n- [#766](https://github.com/mozilla/send/pull/766) Some frontend unit tests [WIP] (@dannycoates)\n- [#761](https://github.com/mozilla/send/pull/761) added maxPasswordLength and passwordError messages (@dannycoates)\n- [#764](https://github.com/mozilla/send/pull/764) added indefinite progress mode (@dannycoates)\n- [#760](https://github.com/mozilla/send/pull/760) refactored css: phase 1 (@dannycoates)\n- [#759](https://github.com/mozilla/send/pull/759) Switch en-US FTL file to new syntax (@flodolo)\n- [#758](https://github.com/mozilla/send/pull/758) refactored server (@dannycoates)\n- [#757](https://github.com/mozilla/send/pull/757) Update to fluent 0.4.3 (@stasm)\n\n### v2.3.0 (2018/02/01 23:27 +00:00)\n- [#536](https://github.com/mozilla/send/pull/536) use redis expire event to delete stored data immediately (@ehuggett)\n- [#744](https://github.com/mozilla/send/pull/744) Gradient experiment (@dannycoates)\n- [#739](https://github.com/mozilla/send/pull/739) added /api/info/:id route (@dannycoates)\n- [#737](https://github.com/mozilla/send/pull/737) big refactor (@dannycoates)\n- [#722](https://github.com/mozilla/send/pull/722) Add localization note to 'Time' and 'Downloads' string (@flodolo)\n- [#721](https://github.com/mozilla/send/pull/721) show download Limits on page; Fixes #661 (@shikhar-scs)\n- [#694](https://github.com/mozilla/send/pull/694) Passwords can now be changed (#687) (@himanish-star)\n- [#702](https://github.com/mozilla/send/pull/702) Restricted the banner from showing on unsupported browsers (@himanish-star)\n- [#701](https://github.com/mozilla/send/pull/701) improved popup for mobile display; Fixes #699 (@shikhar-scs)\n- [#683](https://github.com/mozilla/send/pull/683) API changes to accommodate 3rd party clients (@ehuggett)\n- [#698](https://github.com/mozilla/send/pull/698) Popup for delete button attached (@himanish-star)\n- [#695](https://github.com/mozilla/send/pull/695) Show Warning, Cancel and Redirect on size > 2GB ; fixes #578 (@shikhar-scs)\n- [#684](https://github.com/mozilla/send/pull/684) delete btn popup attached (@himanish-star)\n- [#686](https://github.com/mozilla/send/pull/686) Hide password while Typing and after Entering: Fixes #670 (@shikhar-scs)\n- [#679](https://github.com/mozilla/send/pull/679) changed font to sans sherif: Solves #676 (@shikhar-scs)\n- [#693](https://github.com/mozilla/send/pull/693) README: Fix query link for \"good first bugs\" (@jspam)\n- [#685](https://github.com/mozilla/send/pull/685) checkbox now has a hover effect: fixes #635 (@himanish-star)\n- [#668](https://github.com/mozilla/send/pull/668) Add possibility to bind to a specific IP address (@TwizzyDizzy)\n- [#682](https://github.com/mozilla/send/pull/682) [Docs] - README.md - minor spelling fixes (@tmm2018)\n- [#672](https://github.com/mozilla/send/pull/672) Use EXPIRE_SECONDS to calculate file ttl for static content (@derektamsen)\n- [#680](https://github.com/mozilla/send/pull/680) adjusted line height of label : fixes #609 (@himanish-star)\n\n### v2.2.2 (2017/12/19 18:06 +00:00)\n- [#667](https://github.com/mozilla/send/pull/667) Make develop the default NODE_ENV (@claudijd)\n\n### v2.2.1 (2017/12/08 18:00 +00:00)\n- [#665](https://github.com/mozilla/send/pull/665) stop drag target from flickering when dragging over children (@ericawright)\n\n### v2.2.0 (2017/12/06 23:57 +00:00)\n- [#654](https://github.com/mozilla/send/pull/654) Multiple download UI (@dannycoates)\n- [#650](https://github.com/mozilla/send/pull/650) #634: overwrite appearance of password submit input (@ovlb)\n- [#649](https://github.com/mozilla/send/pull/649) #609 share interface: align text in input and button (@ovlb)\n\n### v2.1.2 (2017/11/16 19:03 +00:00)\n- [#645](https://github.com/mozilla/send/pull/645) Remove the leak of the password into the console (@laurentj)\n\n### v2.1.0 (2017/11/15 03:07 +00:00)\n- [#641](https://github.com/mozilla/send/pull/641) Added experiment for firefox download promo (@dannycoates)\n- [#640](https://github.com/mozilla/send/pull/640) use fluent-langneg for subtag support (@dannycoates)\n- [#639](https://github.com/mozilla/send/pull/639) wrap number localization in try/catch (@dannycoates)\n\n### v2.0.0 (2017/11/08 05:31 +00:00)\n- [#633](https://github.com/mozilla/send/pull/633) Keyboard navigation/visual feedback regression (@ehuggett)\n- [#632](https://github.com/mozilla/send/pull/632) display the 'add password' button only when the input field isn't empty (@dannycoates)\n- [#626](https://github.com/mozilla/send/pull/626) Partial fix for #623 (@ehuggett)\n- [#624](https://github.com/mozilla/send/pull/624) set a default MIME type in file metadata (@ehuggett)\n- [#612](https://github.com/mozilla/send/pull/612) Password UI nits (@dannycoates, @ericawright)\n- [#617](https://github.com/mozilla/send/pull/617) allow drag and drop if navigating from shared page (@ericawright)\n- [#608](https://github.com/mozilla/send/pull/608) disable copying link when password not completed (@ericawright)\n- [#605](https://github.com/mozilla/send/pull/605) align the \"Password\" and \"Copy to clipboard\" fields. (@ericawright)\n- [#582](https://github.com/mozilla/send/pull/582) Add optional password to the download url (@dannycoates)\n\n### v1.2.4 (2017/10/10 17:34 +00:00)\n- [#583](https://github.com/mozilla/send/pull/583) Promote the beefy UI to default (@dannycoates)\n- [#581](https://github.com/mozilla/send/pull/581) introducing ToC to README.md (@tmm2018)\n- [#579](https://github.com/mozilla/send/pull/579) Hide cancel button when upload reaches 100% (@ericawright)\n- [#580](https://github.com/mozilla/send/pull/580) Change Favicon in to look better in a variety of cases (@ericawright)\n- [#571](https://github.com/mozilla/send/pull/571) Centre logo (@ehuggett)\n- [#574](https://github.com/mozilla/send/pull/574) Make upload button focusable (accessibility/tab navigation) (@ehuggett)\n\n### v1.2.0 (2017/09/12 22:42 +00:00)\n- [#559](https://github.com/mozilla/send/pull/559) added first A/B experiment (@dannycoates)\n- [#542](https://github.com/mozilla/send/pull/542) fix docker link typo (@ehuggett)\n- [#541](https://github.com/mozilla/send/pull/541) removed .title and .alt attributes from ftl (@dannycoates)\n- [#537](https://github.com/mozilla/send/pull/537) a few changes to make A/B testing easier (@dannycoates)\n- [#533](https://github.com/mozilla/send/pull/533) minor UI fixes (@youwenliang)\n- [#531](https://github.com/mozilla/send/pull/531) Add CHANGELOG script (@pdehaan)\n- [#535](https://github.com/mozilla/send/pull/535) Fixed minimum NodeJS version in README (@LuFlo)\n- [#528](https://github.com/mozilla/send/pull/528) adding separators to README (@tmm2018)\n\n### v1.1.1 (2017/08/17 01:29 +00:00)\n- [#516](https://github.com/mozilla/send/pull/516) cache assets (@dannycoates)\n- [#520](https://github.com/mozilla/send/pull/520) fix drag & drop (@dannycoates)\n- [#515](https://github.com/mozilla/send/pull/515) removed jquery from upload.js (@dannycoates)\n- [#514](https://github.com/mozilla/send/pull/514) use async and removed jquery from download.js (@dannycoates)\n- [#513](https://github.com/mozilla/send/pull/513) use svg for progress (@dannycoates)\n- [#510](https://github.com/mozilla/send/pull/510) added precommit hook for format (@dannycoates)\n- [#502](https://github.com/mozilla/send/pull/502) extracted filelist into its own file (@dannycoates)\n- [#428](https://github.com/mozilla/send/pull/428) add twitter and open graph cards (@dannycoates, @johngruen)\n- [#506](https://github.com/mozilla/send/pull/506) 404 page (@varghesethomase)\n- [#508](https://github.com/mozilla/send/pull/508) fixes 478 (@abhinadduri)\n- [#504](https://github.com/mozilla/send/pull/504) fix japanese browse button (@johngruen)\n- [#503](https://github.com/mozilla/send/pull/503) Added editorconfig (@skystar-p)\n- [#499](https://github.com/mozilla/send/pull/499) use import/export in the frontend code (@dannycoates)\n- [#500](https://github.com/mozilla/send/pull/500) fixed build:css on windows (@dannycoates)\n- [#481](https://github.com/mozilla/send/pull/481) Cater for mobile and desktop (@pdehaan, @hubdotcom)\n- [#493](https://github.com/mozilla/send/pull/493) added webpack-dev-middleware (@dannycoates)\n- [#491](https://github.com/mozilla/send/pull/491) added missing exit event cases (@dannycoates)\n- [#492](https://github.com/mozilla/send/pull/492) make the site mostly work when cookies (localStorage) are disabled (@dannycoates)\n- [#490](https://github.com/mozilla/send/pull/490) set the mime type in the download blob (@dannycoates)\n- [#485](https://github.com/mozilla/send/pull/485) added progress to tab title when not in focus (@dannycoates)\n- [#474](https://github.com/mozilla/send/pull/474) Fixing bug #438 by adding role attribute to anchor tags and alt attribute images (@varghesethomase)\n- [#480](https://github.com/mozilla/send/pull/480) Increase font weight to 500 on <button>s and <label>s (@pdehaan)\n- [#419](https://github.com/mozilla/send/pull/419) Add autoprefixer and cssnano support (@pdehaan)\n\n### v1.1.0 (2017/08/08 03:59 +00:00)\n- [#473](https://github.com/mozilla/send/pull/473) Sort contributors alphabetically to prevent churn (@pdehaan)\n- [#472](https://github.com/mozilla/send/pull/472) removed references to checksums in frontend tests (@abhinadduri)\n- [#470](https://github.com/mozilla/send/pull/470) removed the file sha256 hash (@dannycoates)\n- [#469](https://github.com/mozilla/send/pull/469) Increase mimimum node version to 8.2.0 (@ehuggett)\n- [#468](https://github.com/mozilla/send/pull/468) attach delete-file handler only after upload (@dannycoates)\n- [#466](https://github.com/mozilla/send/pull/466) added webpack (@dannycoates)\n- [#427](https://github.com/mozilla/send/pull/427) Extended system font list fixes:#408 (@gautamkrishnar)\n- [#448](https://github.com/mozilla/send/pull/448) Migrate width attribute to CSS (Fixes #436) (@nskins)\n- [#457](https://github.com/mozilla/send/pull/457) factored out progress into progress.js (@dannycoates)\n- [#452](https://github.com/mozilla/send/pull/452) refactored metrics (@dannycoates)\n- [#455](https://github.com/mozilla/send/pull/455) Add a few missing strings from es-CL and tr locales (@pdehaan)\n- [#444](https://github.com/mozilla/send/pull/444) Chain jQuery calls, do not use events alias and store selectors (@Johann-S)\n- [#416](https://github.com/mozilla/send/pull/416) WIP: use webcrypto-liner to support Safari 10 (@dannycoates)\n- [#451](https://github.com/mozilla/send/pull/451) Add rel noopener noreferrer to target='_blank' anchor elements (Fixes #439) (@boopeshmahendran)\n- [#449](https://github.com/mozilla/send/pull/449) Add X-UA-Compatible meta tag (@kenrick95)\n- [#433](https://github.com/mozilla/send/pull/433) Prevent download button from being clicked multiple times (@pdehaan)\n- [#432](https://github.com/mozilla/send/pull/432) Add contributors script (@pdehaan)\n- [#409](https://github.com/mozilla/send/pull/409) Handle copy clipboard disabled (@Johann-S)\n\n### v1.0.4 (2017/08/03 23:05 +00:00)\n- [#418](https://github.com/mozilla/send/pull/418) _blank all footer links (@dannycoates)\n- [#386](https://github.com/mozilla/send/pull/386) fix percentage view on mobile layout (@ariestiyansyah)\n- [#414](https://github.com/mozilla/send/pull/414) Add link to FAQ in unsupported view (@pdehaan)\n- [#415](https://github.com/mozilla/send/pull/415) Only include Fira CSS on /unsupported/* route (@pdehaan)\n- [#412](https://github.com/mozilla/send/pull/412) throw key errors before download begins (@dannycoates)\n- [#404](https://github.com/mozilla/send/pull/404) Use async function instead of promise (#325) (@weihanglo)\n- [#406](https://github.com/mozilla/send/pull/406) Add noscript tag (@pdehaan)\n- [#325](https://github.com/mozilla/send/pull/325) Use async function instead of promise (#325) (@weihanglo)\n- [#325](https://github.com/mozilla/send/pull/325) Use async function instead of promise (#325) (@weihanglo)\n\n### v1.0.3 (2017/08/02 23:59 +00:00)\n- [#402](https://github.com/mozilla/send/pull/402) filter the hash from error reports (@dannycoates)\n- [#400](https://github.com/mozilla/send/pull/400) fix link that breaks download by opening in new tab (@johngruen)\n- [#369](https://github.com/mozilla/send/pull/369) Add ESLint no-alert shame rule (@pdehaan)\n- [#396](https://github.com/mozilla/send/pull/396) add babel-polyfill (@dannycoates)\n- [#394](https://github.com/mozilla/send/pull/394) catch JSON.parse errors of storage metadata (@dannycoates)\n- [#367](https://github.com/mozilla/send/pull/367) Generate production locales using 'compare-locales' (@pdehaan)\n- [#392](https://github.com/mozilla/send/pull/392) Adjust hover behavior on send-logo (#382)\r Fixes: #382. (@weihanglo)\n- [#382](https://github.com/mozilla/send/pull/382) Adjust hover behavior on send-logo (#382) (@weihanglo)\n- [#382](https://github.com/mozilla/send/pull/382) Adjust hover behavior on send-logo (#382) (@weihanglo)\n- [#380](https://github.com/mozilla/send/pull/380) Add Pontoon URL to README (@pdehaan)\n\n### v1.0.2 (2017/07/31 18:58 +00:00)\n- [#365](https://github.com/mozilla/send/pull/365) revert the IE fix to fix footer on chrome (@dannycoates)\n\n### v1.0.1 (2017/07/31 17:28 +00:00)\n- [#353](https://github.com/mozilla/send/pull/353) redirect ie to /unsupported (@abhinadduri, @dannycoates)\n- [#360](https://github.com/mozilla/send/pull/360) Fix some linting nits (@pdehaan)\n- [#362](https://github.com/mozilla/send/pull/362) Adjusts category of unsupported event (fixes #350). (@chuckharmston)\n- [#355](https://github.com/mozilla/send/pull/355) Make order of uploaded files in list consistent (@pdehaan)\n- [#356](https://github.com/mozilla/send/pull/356) Get rid of console.log statements (@pdehaan)\n- [#358](https://github.com/mozilla/send/pull/358) Fix some missing .title attributes in dev-only locales (@pdehaan)\n- [#354](https://github.com/mozilla/send/pull/354) Remove /en-US/ from cookies link in footer (@pdehaan)\n- [#339](https://github.com/mozilla/send/pull/339) Show error page on firefox v49 and below (@ericawright, @abhinadduri)\n- [#346](https://github.com/mozilla/send/pull/346) Add docs/CODEOWNERS file (@pdehaan)\n- [#345](https://github.com/mozilla/send/pull/345) wrap long file names (@dnarcese)\n- [#344](https://github.com/mozilla/send/pull/344) don't wrap file list headers (@dnarcese)\n- [#327](https://github.com/mozilla/send/pull/327) Modify popup delete dialog (@youwenliang)\n- [#341](https://github.com/mozilla/send/pull/341) center percentage text on all browser versions (@dnarcese)\n- [#340](https://github.com/mozilla/send/pull/340) Remove duplicate entities in localized FTL files (@flodolo)\n- [#337](https://github.com/mozilla/send/pull/337) support v 50 and 51 by not allowing const in loops (@ericawright)\n- [#338](https://github.com/mozilla/send/pull/338) Remove duplicated strings in en-US, fix nn-NO file (@flodolo)\n- [#336](https://github.com/mozilla/send/pull/336) German(de): Fixed missing value for deleteFileButton (#336) (@flodolo)\n- [#334](https://github.com/mozilla/send/pull/334) fix functionality on firefox 50 and 51 (@dnarcese)\n\n### v1.0.0 (2017/07/26 19:08 +00:00)\n- [#323](https://github.com/mozilla/send/pull/323) disable upload/download notifications (@dannycoates)\n- [#322](https://github.com/mozilla/send/pull/322) fix feedback button jump (@dnarcese)\n- [#320](https://github.com/mozilla/send/pull/320) fix German footer (@dnarcese)\n\n### v0.2.2 (2017/07/26 04:50 +00:00)\n- [#314](https://github.com/mozilla/send/pull/314) added L10N_DEV environment variable for making all languages available (@dannycoates)\n- [#313](https://github.com/mozilla/send/pull/313) removing timeout limit for front end tests (@abhinadduri)\n- [#311](https://github.com/mozilla/send/pull/311) expired ids should reject instead of returning null (@dannycoates)\n- [#302](https://github.com/mozilla/send/pull/302) UX Refine WIP (@youwenliang)\n- [#310](https://github.com/mozilla/send/pull/310) if the download card is pressed, the expired card shows up properly (@abhinadduri)\n- [#269](https://github.com/mozilla/send/pull/269) refactored ftl file (@abhinadduri)\n- [#291](https://github.com/mozilla/send/pull/291) added legal page (@dannycoates)\n- [#307](https://github.com/mozilla/send/pull/307) don't show error page on upload cancel (@dnarcese)\n- [#299](https://github.com/mozilla/send/pull/299) use CIRCLE_TAG as version.json version if present (@dannycoates)\n\n### v0.2.1 (2017/07/24 23:34 +00:00)\n- [#296](https://github.com/mozilla/send/pull/296) restyle delete popup (@dnarcese)\n- [#295](https://github.com/mozilla/send/pull/295) renamed environment variables to remove P2P_ prefix (@dannycoates)\n- [#294](https://github.com/mozilla/send/pull/294) dealing with invalid drag and drops (@abhinadduri)\n- [#297](https://github.com/mozilla/send/pull/297) added environment variable for expire time (@dannycoates)\n- [#292](https://github.com/mozilla/send/pull/292) Fixes289 (@abhinadduri)\n- [#288](https://github.com/mozilla/send/pull/288) fix: Don`t allow upload when not on the upload page. (@ericawright)\n- [#285](https://github.com/mozilla/send/pull/285) added messages for processing phases (@dannycoates)\n- [#267](https://github.com/mozilla/send/pull/267) make site responsive and add feedback link (@johngruen)\n- [#286](https://github.com/mozilla/send/pull/286) Update download progress bar color (@pdehaan)\n- [#281](https://github.com/mozilla/send/pull/281) Stop ESLint from linting the /public/ directory (@pdehaan)\n- [#280](https://github.com/mozilla/send/pull/280) created /unsupported page and added gcmCompliant to /download page (@dannycoates)\n- [#279](https://github.com/mozilla/send/pull/279) create separate js bundles for upload/download pages (@dannycoates)\n- [#268](https://github.com/mozilla/send/pull/268) Testpilot ga (@abhinadduri)\n\n### v0.2.0 (2017/07/21 19:27 +00:00)\n- [#266](https://github.com/mozilla/send/pull/266) abort uploads over maxfilesize (@dannycoates)\n- [#264](https://github.com/mozilla/send/pull/264) Remove duplicate custom metric. (@chuckharmston)\n- [#259](https://github.com/mozilla/send/pull/259) add alert when uploading multiple files (@dnarcese)\n- [#262](https://github.com/mozilla/send/pull/262) sync download progress bar with percentage (@dnarcese)\n- [#258](https://github.com/mozilla/send/pull/258) better sync percent with progress bar (@dnarcese)\n- [#257](https://github.com/mozilla/send/pull/257) add a dynamic js script for page config (@dannycoates)\n- [#256](https://github.com/mozilla/send/pull/256) add file size limit message (@dnarcese)\n- [#253](https://github.com/mozilla/send/pull/253) Add favicon.ico version of the Send logo (@pdehaan)\n- [#254](https://github.com/mozilla/send/pull/254) Add nsp check to circle ci (@pdehaan)\n- [#245](https://github.com/mozilla/send/pull/245) Localization (@abhinadduri)\n- [#252](https://github.com/mozilla/send/pull/252) only allow drag and drop on upload page (@dnarcese)\n- [#250](https://github.com/mozilla/send/pull/250) make footer not overlap (@dnarcese)\n- [#251](https://github.com/mozilla/send/pull/251) minify all images (@ericawright)\n- [#249](https://github.com/mozilla/send/pull/249) change how the file upload box expands (@dnarcese)\n- [#246](https://github.com/mozilla/send/pull/246) remove P2P references.  Fixes #224 (@clouserw)\n- [#242](https://github.com/mozilla/send/pull/242) Make only icons clickable in file list (@dnarcese)\n- [#236](https://github.com/mozilla/send/pull/236) add FAQ. Fixes #186 (@clouserw)\n- [#235](https://github.com/mozilla/send/pull/235) allow send another file link to open in new tab (@dnarcese)\n- [#234](https://github.com/mozilla/send/pull/234) fix download svg (@dnarcese)\n- [#232](https://github.com/mozilla/send/pull/232) escape filename in the ui (@dannycoates)\n- [#226](https://github.com/mozilla/send/pull/226) added functionality to cancel uploads (@abhinadduri)\n- [#231](https://github.com/mozilla/send/pull/231) move head and html tags to main template (@dnarcese)\n- [#228](https://github.com/mozilla/send/pull/228) add send logo (@dnarcese)\n- [#229](https://github.com/mozilla/send/pull/229) change learn more and github links (@dnarcese)\n- [#201](https://github.com/mozilla/send/pull/201) Adds metrics documentation (closes #5). (@chuckharmston)\n- [#223](https://github.com/mozilla/send/pull/223) change size of send another file links (@dnarcese)\n- [#222](https://github.com/mozilla/send/pull/222) add footer (@dnarcese)\n- [#197](https://github.com/mozilla/send/pull/197) fixes issues 195 and 192 (@abhinadduri)\n- [#204](https://github.com/mozilla/send/pull/204) added HSTS header (@dannycoates)\n- [#193](https://github.com/mozilla/send/pull/193) Frontend tests (@abhinadduri)\n- [#191](https://github.com/mozilla/send/pull/191) New ui! (@dnarcese)\n\n### v0.1.4 (2017/07/12 18:21 +00:00)\n- [#189](https://github.com/mozilla/send/pull/189) Add CSP directives (@dannycoates)\n- [#188](https://github.com/mozilla/send/pull/188) fixes delete button error (@abhinadduri)\n- [#185](https://github.com/mozilla/send/pull/185) added loading, hashing, and encrypting events for uploader; decryptin… (@abhinadduri)\n- [#183](https://github.com/mozilla/send/pull/183) rename to 'Send' (@dannycoates)\n- [#184](https://github.com/mozilla/send/pull/184) Server tests (@abhinadduri)\n- [#178](https://github.com/mozilla/send/pull/178) fixed issues in branch title (@abhinadduri)\n- [#177](https://github.com/mozilla/send/pull/177) Gcm compliance (@abhinadduri)\n- [#106](https://github.com/mozilla/send/pull/106) Gcm (@abhinadduri, @dannycoates)\n- [#168](https://github.com/mozilla/send/pull/168) Show error page if upload fails (@dnarcese)\n- [#148](https://github.com/mozilla/send/pull/148) WIP: Add basic contribute.json (@pdehaan)\n- [#162](https://github.com/mozilla/send/pull/162) Fix dev server URL in README.md file (@pdehaan)\n- [#167](https://github.com/mozilla/send/pull/167) build docker image with new name (@relud)\n- [#164](https://github.com/mozilla/send/pull/164) Add word wraps to table (@dnarcese)\n- [#149](https://github.com/mozilla/send/pull/149) Add robots.txt (@pdehaan)\n- [#161](https://github.com/mozilla/send/pull/161) Hide table header on empty list (@dnarcese)\n- [#154](https://github.com/mozilla/send/pull/154) Remove expired uploads (@dnarcese)\n- [#146](https://github.com/mozilla/send/pull/146) Update README with some more details (@pdehaan)\n\n### v0.1.2 (2017/06/24 03:38 +00:00)\n- [#138](https://github.com/mozilla/send/pull/138) remove notLocalHost (@dannycoates)\n\n### v0.1.0 (2017/06/24 01:24 +00:00)\n- [#137](https://github.com/mozilla/send/pull/137) refactored docker build (@dannycoates)\n- [#132](https://github.com/mozilla/send/pull/132) Add /__version__ route (@pdehaan)\n- [#135](https://github.com/mozilla/send/pull/135) make dockerfile more dockerflowy (@dannycoates)\n- [#134](https://github.com/mozilla/send/pull/134) Load previous uploads (@dannycoates, @dnarcese)\n- [#131](https://github.com/mozilla/send/pull/131) added __heartbeat__ (@dannycoates)\n- [#133](https://github.com/mozilla/send/pull/133) Add LICENSE file (@pdehaan)\n- [#130](https://github.com/mozilla/send/pull/130) added sentry to server code (@abhinadduri)\n- [#124](https://github.com/mozilla/send/pull/124) Remove unused [dev]dependencies (@pdehaan)\n- [#119](https://github.com/mozilla/send/pull/119) Move cross-env to a dep (@pdehaan)\n- [#123](https://github.com/mozilla/send/pull/123) removed bitly integration (@abhinadduri)\n- [#122](https://github.com/mozilla/send/pull/122) fix docker build (@dannycoates)\n- [#121](https://github.com/mozilla/send/pull/121) added docker service to circle.yml (@dannycoates)\n- [#120](https://github.com/mozilla/send/pull/120) added sentry (@abhinadduri)\n- [#118](https://github.com/mozilla/send/pull/118) change docker image name and add builds for tags (@relud)\n- [#116](https://github.com/mozilla/send/pull/116) add /__lbheartbeat__ endpoint (@relud)\n- [#79](https://github.com/mozilla/send/pull/79) Optimize/minimize bundle.js for production (@pdehaan)\n- [#104](https://github.com/mozilla/send/pull/104) Fix a bunch of ESLint and HTMLLint errors (@pdehaan)\n- [#105](https://github.com/mozilla/send/pull/105) Progress bars (@dnarcese)\n- [#111](https://github.com/mozilla/send/pull/111) added in anonmyized ip google analytics (@abhinadduri)\n- [#110](https://github.com/mozilla/send/pull/110) added notifications (@abhinadduri)\n- [#103](https://github.com/mozilla/send/pull/103) added Dockerfile (@dannycoates)\n- [#100](https://github.com/mozilla/send/pull/100) Added Helmet Middleware (@abhinadduri)\n- [#99](https://github.com/mozilla/send/pull/99) Testing (@abhinadduri)\n- [#77](https://github.com/mozilla/send/pull/77) Fix the linter errors (@pdehaan)\n- [#54](https://github.com/mozilla/send/pull/54) Adding basic ESLint config (@pdehaan)\n- [#71](https://github.com/mozilla/send/pull/71) Drag & drop (@dnarcese)\n- [#72](https://github.com/mozilla/send/pull/72) Logging (@abhinadduri, @dannycoates)\n- [#45](https://github.com/mozilla/send/pull/45) S3 integration (@abhinadduri, @dannycoates)\n- [#46](https://github.com/mozilla/send/pull/46) Download page and share link UI (@dnarcese)\n- [#41](https://github.com/mozilla/send/pull/41) Added upload page and file list UI (@dnarcese)\n- [#40](https://github.com/mozilla/send/pull/40) Tweak the package.json file (@pdehaan)\n- [#43](https://github.com/mozilla/send/pull/43) added return (@abhinadduri)\n- [#42](https://github.com/mozilla/send/pull/42) changed to handle 404 during download, also removing progress listene… (@abhinadduri)\n- [#39](https://github.com/mozilla/send/pull/39) Refactor riff (@abhinadduri, @dannycoates)\n- [#36](https://github.com/mozilla/send/pull/36) added prettier for js formatting (@dannycoates)\n- [#28](https://github.com/mozilla/send/pull/28) Added a UI for the uploader end, made stylistic changes, implemented deleting (@abhinadduri)\n- [#25](https://github.com/mozilla/send/pull/25) Changed naming for some pages, no longer stores files by name on server (@abhinadduri)\n- [#17](https://github.com/mozilla/send/pull/17) changed from using input fields for keys to getting from url (#17) (@abhinadduri)"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Community Participation Guidelines\n\nThis repository is governed by Mozilla's code of conduct and etiquette guidelines. \nFor more details, please read the\n[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/). \n\n## How to Report\nFor more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.\n\n<!--\n## Project Specific Etiquette\n\nIn some cases, there will be additional project etiquette i.e.: (https://bugzilla.mozilla.org/page.cgi?id=etiquette.html).\nPlease update for your project.\n-->\n"
  },
  {
    "path": "CONTRIBUTORS",
    "content": "Abdalrahman Hwoij\nAbhinav Adduri\nAdnan Kičin\nAdolfo Jayme Barrientos\nAlberto Castro\nAlexander Slovesnik\nAlfredos-Panagiotis Damkalis\nAman Alam\nAmin Mahmudian\nAnder Elortondo\nAndreas Pettersson\nAnesu Chiodza\nAnika Dorn\nAnish Sheela\nArash Mousavi\nArtem Polivanchuk\nAshikur Rahman\nAshok kumar\nBalasankar C\nBalázs Meskó\nBelayet Hossain\nBenjamin Forehand Jr\nBesnik Bleta\nBjörn I\nBjørn I\nBoopesh Mahendran\nBrahim Essaidi\nBrainlulz\nBreana Gonzales\nChristian Elbrianno\nChristoph Kührer\nChristopher Ramírez\nChuck Harmston\nCloney 173741\nCláudio Esperança\nCristian Silaghi\nCynthia Pereira\nDaniel Thorn\nDaniela Arcese\nDanny Coates\nDavide\nDerek Tamsen\nDhyey Thakore\nDonovan Preston\nEdi Santoso\nEdmund Huggett\nElisa X\nEmily\nEmily Hou\nEmin Mastizada\nEnol\nErica\nErica Wright\nFauzan Alfi\nFilip Hruška\nFjoerfoks\nFrancesco Lodolo\nFrancesco Lodolo [:flod]\nFrederick Villaluna\nG12r\nGabriela\nGautam krishna.R\nGeorge Raptis\nGeorgianizator\nGonçalo Matos\nGwenn\nHampus\nHugo\nHugo Abreu\nHyeonseok Shin\nHåvar Henriksen\nIan Neal\nItielMaN\nJae Hyeon Park\nJakob Kappel\nJakub Rychlý\nJamie\nJarmo\nJim Spentzos\nJiri Grönroos\nJobava\nJoe Becher\nJoe ST\nJoergen\nJohann-S\nJohn Gruen\nJon Buckley\nJon Vadillo\nJonathan Claudius\nJordi Cuevas\nJordi Serratosa\nJuan Esteban Ajsivinac Sián\nJuan Sián\nJuraj Cigáň\nKerim Kalamujić\nKhaled Hosny\nKim Ludvigsen\nKim Younggeon\nKohei Yoshino\nLan Glad\nLasse Liehu\nLaurent Jouanneau\nLobodzets\nLuFlo\nLuis A. Sánchez\nLuiz Carlos de Morais\nLuiz Felipe F M Costa\nLuna Jernberg\nMahay Alam Khan\nMarcelo Ghelman\nMarcelo Poli\nMarco Aurélio\nMark Heijl\nMark Liang\nMark Liang (You-Wen)\nMarko Andrejić\nMartijn Dekker\nMarwan Mohamad\nMatjaž Horvat\nMaykon Chagas\nMelo46\nMerike Sell\nMichael Köhler\nMichael Wolf\nMichal Stanke\nMichal Vašíček\nMikeyy\nMiro Rauhala\nMozilla Pontoon\nMozilla-GitHub-Standards\nMozinet\nMoḥend Belqasem\nMuhend Belkacem\nMuḥend Belqasem\nMyungjae Won\nNicholas Skinsacos\nNihad\nNihad Suljić\nNiksend Mizuhara\nOscar\nPaulius\nPedro Burlamaqui Bendahan\nPeter deHaan\nPierre Neter\nPin-guang Chen\nPiotr Drąg\nQuentí\nQuế Tùng\nRachel Tublitz\nRadu Popescu\nRhoslyn Prys\nRickieES\nRimas Kudelis\nRizky Ariestiyansyah\nRob Powell\nRobert\nRoberto Alvarado\nRodrigo\nRodrigo Guerra\nRok Žerdin\nRomi Hardiyanto\nRongjian Zhang\nRuba\nSahithi\nSairam Raavi\nSander Lepik\nSandro\nSara Todaro\nSav22999\nSchieck :)\nSelim Şumlu\nSelyan Sliman Amiri\nSidak Singh Aulakh\nSlimane Amiri\nSlimane Selyan AMIRI\nSoumya Himanish Mohapatra\nStaś Małolepszy\nSuriyaa ✌️️\nTema\nThomas Dalichow\nThéo Chevalier\nTiago Morais Morgado\nTim Visée\nTomer Cohen\nTomáš Zelina\nTon\nTop\nTymur Faradzhev\nUccen Marzuq\nVarghese Thomas\nVictor Bychek\nVimal Raghubir\nVitaliy Krutko\nWeihang Lo\nWiktor Furman\nWil Clouser\nYFdyh000\nYassine Aït-El-Mouden\nYongmin H\nYou-Wen Liang (Mark)\naaaaalbert\naefgh39622\nalamanda\nalbertdcastro\nalex_mayorga\nariestiyansyah\navelper\nchilledfrogs\nclouserw-mozilla-owner\ndgadelha\ndskmori\nehuggett\neljuno\nemily-hou1\nerdem cobanoglu\ngautamkrishnar\ngmontagu\ngoofy\nhello\nhi\nivan.pompa\njesferman1993\njlG\njosotrix\njspam\njulen\njulenx\nkenrick95\nkumincir\nleo.toneff\nm4hdi.pdroid\nmail\nmanxmensch\nmarigalicer\nmarsf\nmerianosnikos\nmirzet.omerovic.1992\nmujeebcpy\np.sanroman.bengoetxea\npassionforlife\npaul.trevor\npyup.io bot\nravmn\nrcmainak\nreza.habibi2008\nrgpublic\nrisger\nrobbp\nruikunai\nsavemore99.sm\nsergio\nshikhar-scs\nsiparon\nskystar-p\nstripTM\ntatalmondmush\ntiagomoraismorgado\ntimvisee\nvictor.gonzalezro\nxcffl\nybouhamam\nyoshimitsu002\nyusup.ramdani\nΜιχάλης\nМарко Костић (Marko Kostić)\nРатко Вујановић\nصفا الفليج\nవీవెన్\nജോയ്സ്\n张无忌\n新垣结衣松冈茉优长泽雅美门胁麦上野树里石原里美\n莫非前世那一眼\n"
  },
  {
    "path": "Dockerfile",
    "content": "##\n# Firefox Send - Mozilla\n#\n# License https://github.com/mozilla/send/blob/master/LICENSE\n##\n\n\n# Build project\nFROM node:12 AS builder\nRUN set -x \\\n    # Add user\n    && addgroup --gid 10001 app \\\n    && adduser --disabled-password \\\n        --gecos '' \\\n        --gid 10001 \\\n        --home /app \\\n        --uid 10001 \\\n        app\nCOPY --chown=app:app . /app\nUSER app\nWORKDIR /app\nRUN set -x \\\n    # Build\n    && PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm ci \\\n    && npm run build\n\n\n# Main image\nFROM node:12-slim\nRUN set -x \\\n    # Add user\n    && addgroup --gid 10001 app \\\n    && adduser --disabled-password \\\n        --gecos '' \\\n        --gid 10001 \\\n        --home /app \\\n        --uid 10001 \\\n        app\nRUN apt-get update && apt-get -y install \\\n    git-core \\\n    && rm -rf /var/lib/apt/lists/*\nUSER app\nWORKDIR /app\nCOPY --chown=app:app package*.json ./\nCOPY --chown=app:app app app\nCOPY --chown=app:app common common\nCOPY --chown=app:app public/locales public/locales\nCOPY --chown=app:app server server\nCOPY --chown=app:app --from=builder /app/dist dist\n\nRUN npm ci --production && npm cache clean --force\nRUN mkdir -p /app/.config/configstore\nRUN ln -s dist/version.json version.json\n\nENV PORT=1443\n\nEXPOSE ${PORT}\n\nCMD [\"node\", \"server/bin/prod.js\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\n    means each individual or legal entity that creates, contributes to\n    the creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n    means the combination of the Contributions of others (if any) used\n    by a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n    means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n    means Source Code Form to which the initial Contributor has attached\n    the notice in Exhibit A, the Executable Form of such Source Code\n    Form, and Modifications of such Source Code Form, in each case\n    including portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n    means\n\n    (a) that the initial Contributor has attached the notice described\n        in Exhibit B to the Covered Software; or\n\n    (b) that the Covered Software was made available under the terms of\n        version 1.1 or earlier of the License, but not also under the\n        terms of a Secondary License.\n\n1.6. \"Executable Form\"\n    means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n    means a work that combines Covered Software with other material, in \n    a separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n    means this document.\n\n1.9. \"Licensable\"\n    means having the right to grant, to the maximum extent possible,\n    whether at the time of the initial grant or subsequently, any and\n    all of the rights conveyed by this License.\n\n1.10. \"Modifications\"\n    means any of the following:\n\n    (a) any file in Source Code Form that results from an addition to,\n        deletion from, or modification of the contents of Covered\n        Software; or\n\n    (b) any new file in Source Code Form that contains any Covered\n        Software.\n\n1.11. \"Patent Claims\" of a Contributor\n    means any patent claim(s), including without limitation, method,\n    process, and apparatus claims, in any patent Licensable by such\n    Contributor that would be infringed, but for the grant of the\n    License, by the making, using, selling, offering for sale, having\n    made, import, or transfer of either its Contributions or its\n    Contributor Version.\n\n1.12. \"Secondary License\"\n    means either the GNU General Public License, Version 2.0, the GNU\n    Lesser General Public License, Version 2.1, the GNU Affero General\n    Public License, Version 3.0, or any later versions of those\n    licenses.\n\n1.13. \"Source Code Form\"\n    means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n    means an individual or a legal entity exercising rights under this\n    License. For legal entities, \"You\" includes any entity that\n    controls, is controlled by, or is under common control with You. For\n    purposes of this definition, \"control\" means (a) the power, direct\n    or indirect, to cause the direction or management of such entity,\n    whether by contract or otherwise, or (b) ownership of more than\n    fifty percent (50%) of the outstanding shares or beneficial\n    ownership of such entity.\n\n2. License Grants and Conditions\n--------------------------------\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than patent or trademark)\n    Licensable by such Contributor to use, reproduce, make available,\n    modify, display, perform, distribute, and otherwise exploit its\n    Contributions, either on an unmodified basis, with Modifications, or\n    as part of a Larger Work; and\n\n(b) under Patent Claims of such Contributor to make, use, sell, offer\n    for sale, have made, import, and otherwise transfer either its\n    Contributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\n(a) for any code that a Contributor has removed from Covered Software;\n    or\n\n(b) for infringements caused by: (i) Your and any other third party's\n    modifications of Covered Software, or (ii) the combination of its\n    Contributions with other software (except as part of its Contributor\n    Version); or\n\n(c) under Patent Claims infringed by Covered Software in the absence of\n    its Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights\nto grant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted\nin Section 2.1.\n\n3. Responsibilities\n-------------------\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\n(a) such Covered Software must also be made available in Source Code\n    Form, as described in Section 3.1, and You must inform recipients of\n    the Executable Form how they can obtain a copy of such Source Code\n    Form by reasonable means in a timely manner, at a charge no more\n    than the cost of distribution to the recipient; and\n\n(b) You may distribute such Executable Form under the terms of this\n    License, or sublicense it under different terms, provided that the\n    license for the Executable Form does not attempt to limit or alter\n    the recipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty,\nor limitations of liability) contained within the Source Code Form of\nthe Covered Software, except that You may alter any license notices to\nthe extent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n---------------------------------------------------\n\nIf it is impossible for You to comply with any of the terms of this\nLicense with respect to some or all of the Covered Software due to\nstatute, judicial order, or regulation then You must: (a) comply with\nthe terms of this License to the maximum extent possible; and (b)\ndescribe the limitations and the code they affect. Such description must\nbe placed in a text file included with all distributions of the Covered\nSoftware under this License. Except to the extent prohibited by statute\nor regulation, such description must be sufficiently detailed for a\nrecipient of ordinary skill to be able to understand it.\n\n5. Termination\n--------------\n\n5.1. The rights granted under this License will terminate automatically\nif You fail to comply with any of its terms. However, if You become\ncompliant, then the rights granted under this License from a particular\nContributor are reinstated (a) provisionally, unless and until such\nContributor explicitly and finally terminates Your grants, and (b) on an\nongoing basis, if such Contributor fails to notify You of the\nnon-compliance by some reasonable means prior to 60 days after You have\ncome back into compliance. Moreover, Your grants from a particular\nContributor are reinstated on an ongoing basis if such Contributor\nnotifies You of the non-compliance by some reasonable means, this is the\nfirst time You have received notice of non-compliance with this License\nfrom such Contributor, and You become compliant prior to 30 days after\nYour receipt of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all\nend user license agreements (excluding distributors and resellers) which\nhave been validly granted by You or Your distributors under this License\nprior to termination shall survive termination.\n\n************************************************************************\n*                                                                      *\n*  6. Disclaimer of Warranty                                           *\n*  -------------------------                                           *\n*                                                                      *\n*  Covered Software is provided under this License on an \"as is\"       *\n*  basis, without warranty of any kind, either expressed, implied, or  *\n*  statutory, including, without limitation, warranties that the       *\n*  Covered Software is free of defects, merchantable, fit for a        *\n*  particular purpose or non-infringing. The entire risk as to the     *\n*  quality and performance of the Covered Software is with You.        *\n*  Should any Covered Software prove defective in any respect, You     *\n*  (not any Contributor) assume the cost of any necessary servicing,   *\n*  repair, or correction. This disclaimer of warranty constitutes an   *\n*  essential part of this License. No use of any Covered Software is   *\n*  authorized under this License except under this disclaimer.         *\n*                                                                      *\n************************************************************************\n\n************************************************************************\n*                                                                      *\n*  7. Limitation of Liability                                          *\n*  --------------------------                                          *\n*                                                                      *\n*  Under no circumstances and under no legal theory, whether tort      *\n*  (including negligence), contract, or otherwise, shall any           *\n*  Contributor, or anyone who distributes Covered Software as          *\n*  permitted above, be liable to You for any direct, indirect,         *\n*  special, incidental, or consequential damages of any character      *\n*  including, without limitation, damages for lost profits, loss of    *\n*  goodwill, work stoppage, computer failure or malfunction, or any    *\n*  and all other commercial damages or losses, even if such party      *\n*  shall have been informed of the possibility of such damages. This   *\n*  limitation of liability shall not apply to liability for death or   *\n*  personal injury resulting from such party's negligence to the       *\n*  extent applicable law prohibits such limitation. Some               *\n*  jurisdictions do not allow the exclusion or limitation of           *\n*  incidental or consequential damages, so this exclusion and          *\n*  limitation may not apply to You.                                    *\n*                                                                      *\n************************************************************************\n\n8. Litigation\n-------------\n\nAny litigation relating to this License may be brought only in the\ncourts of a jurisdiction where the defendant maintains its principal\nplace of business and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions.\nNothing in this Section shall prevent a party's ability to bring\ncross-claims or counter-claims.\n\n9. Miscellaneous\n----------------\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides\nthat the language of a contract shall be construed against the drafter\nshall not be used to construe this License against a Contributor.\n\n10. Versions of the License\n---------------------------\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses\n\nIf You choose to distribute Source Code Form that is Incompatible With\nSecondary Licenses under the terms of this version of the License, the\nnotice described in Exhibit B of this License must be attached.\n\nExhibit A - Source Code Form License Notice\n-------------------------------------------\n\n  This Source Code Form is subject to the terms of the Mozilla Public\n  License, v. 2.0. If a copy of the MPL was not distributed with this\n  file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular\nfile, then You may include the notice in a location (such as a LICENSE\nfile in a relevant directory) where a recipient would be likely to look\nfor such a notice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n---------------------------------------------------------\n\n  This Source Code Form is \"Incompatible With Secondary Licenses\", as\n  defined by the Mozilla Public License, v. 2.0.\n"
  },
  {
    "path": "README.md",
    "content": "# Firefox Send\n\n[![CircleCI](https://img.shields.io/circleci/project/github/mozilla/send.svg)](https://circleci.com/gh/mozilla/send)\n\n## NOTICE - May 2021\n\nMozilla discontinued the Firefox Send service in September 2021. For more information about this, please see the [Mozilla Blog](https://blog.mozilla.org/blog/2020/09/17/update-on-firefox-send-and-firefox-notes/).\n\nPlease note that the [Mozilla Public License 2.0](https://www.mozilla.org/en-US/MPL/2.0/) does not \"grant any rights in the trademarks, service marks, or logos of any Contributor.\" You may fork and modify the source code for Firefox Send pursuant to the Mozilla Public License, but you may not create a version of the service that uses Mozilla trademarks or logos.\n\nThis repository is archived. In May 2021, Mozilla removed Mozilla trademarks from some of the files in this repository so that developers using this code are less likely to inadvertently infringe Mozilla's trademarks and confuse users. You are welcome to copy and modify this code under its open source license, but please ensure that all use complies with [Mozilla's trademark policy](https://www.mozilla.org/en-US/foundation/trademarks/policy/). In other words, if you create a new version of Firefox Send you must remove all \"Mozilla\" and \"Firefox\" branding to ensure that users are not confused about who is providing the service.\n\n**Docs:** [FAQ](docs/faq.md), [Encryption](docs/encryption.md), [Build](docs/build.md), [Docker](docs/docker.md), [Metrics](docs/metrics.md), [More](docs/)\n\n---\n\n## Table of Contents\n\n* [What it does](#what-it-does)\n* [Requirements](#requirements)\n* [Development](#development)\n* [Commands](#commands)\n* [Configuration](#configuration)\n* [Localization](#localization)\n* [Contributing](#contributing)\n* [Testing](#testing)\n* [Deployment](#deployment)\n* [Android](#android)\n* [License](#license)\n\n---\n\n## What it does\n\nA file sharing experiment which allows you to send encrypted files to other users.\n\n---\n\n## Requirements\n\n- [Node.js 12.x](https://nodejs.org/)\n- [Redis server](https://redis.io/) (optional for development)\n- [AWS S3](https://aws.amazon.com/s3/) or compatible service (optional)\n\n---\n\n## Development\n\nTo start an ephemeral development server, run:\n\n```sh\nnpm install\nnpm start\n```\n\nThen, browse to http://localhost:8080\n\n---\n\n## Commands\n\n| Command          | Description |\n|------------------|-------------|\n| `npm run format` | Formats the frontend and server code using **prettier**.\n| `npm run lint`   | Lints the CSS and JavaScript code.\n| `npm test`       | Runs the suite of mocha tests.\n| `npm start`      | Runs the server in development configuration.\n| `npm run build`  | Builds the production assets.\n| `npm run prod`   | Runs the server in production configuration.\n\n---\n\n## Configuration\n\nThe server is configured with environment variables. See [server/config.js](server/config.js) for all options and [docs/docker.md](docs/docker.md) for examples.\n\n---\n\n## Localization\n\nFirefox Send localization is managed via [Pontoon](https://pontoon.mozilla.org/projects/test-pilot-firefox-send/), not direct pull requests to the repository. If you want to fix a typo, add a new language, or simply know more about localization, please get in touch with the [existing localization team](https://pontoon.mozilla.org/teams/) for your language or Mozilla’s [l10n-drivers](https://wiki.mozilla.org/L10n:Mozilla_Team#Mozilla_Corporation) for guidance.\n\nsee also [docs/localization.md](docs/localization.md)\n\n---\n\n## Contributing\n\nPull requests are always welcome! Feel free to check out the list of [\"good first issues\"](https://github.com/mozilla/send/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22).\n\n---\n\n## Testing\n\n| ENVIRONMENT | URL\n|-------------|-----\n| Production  | <https://send.firefox.com/>\n| Stage       | <https://stage.send.nonprod.cloudops.mozgcp.net/>\n| Development | <https://send2.dev.lcip.org/>\n\n---\n\n## Deployment\n\nsee also [docs/deployment.md](docs/deployment.md)\n\n---\n\n## Android\n\nThe android implementation is contained in the `android` directory, and can be viewed locally for easy testing and editing by running `ANDROID=1 npm start` and then visiting <http://localhost:8080>. CSS and image files are located in the `android/app/src/main/assets` directory.\n\n---\n\n## License\n\n[Mozilla Public License Version 2.0](LICENSE)\n\n---\n"
  },
  {
    "path": "android/.eslintrc.yaml",
    "content": "env:\n  browser: true\n\nparserOptions:\n  sourceType: module\n\n"
  },
  {
    "path": "android/.gitignore",
    "content": "local.properties\n.gradle\nbuild\n\n"
  },
  {
    "path": "android/README.md",
    "content": "Readme\n=====\n\nThe Send Android app allows you to choose any file from your android device, encrypt it with a password, and get a URL which will allow secure download of the file. By default, this URL will expire after one download or 24 hours.\n\nBuilding the Send Android app.\n=====\n\nFirst, install Android Studio. Open the `android` directory in Android Studio, plug in your android phone, and press the run button."
  },
  {
    "path": "android/android.js",
    "content": "import 'intl-pluralrules';\nimport choo from 'choo';\nimport html from 'choo/html';\nimport * as Sentry from '@sentry/browser';\n\nimport { setApiUrlPrefix, getConstants } from '../app/api';\nimport metrics from '../app/metrics';\n//import assets from '../common/assets';\nimport Archive from '../app/archive';\nimport Header from '../app/ui/header';\nimport storage from '../app/storage';\nimport controller from '../app/controller';\nimport User from './user';\nimport intents from './stores/intents';\nimport home from './pages/home';\nimport upload from './pages/upload';\nimport share from './pages/share';\nimport preferences from './pages/preferences';\nimport error from './pages/error';\nimport { getTranslator } from '../app/locale';\nimport { setTranslate } from '../app/utils';\n\nimport { delay } from '../app/utils';\n\nif (navigator.userAgent === 'Send Android') {\n  setApiUrlPrefix('https://send.firefox.com');\n}\n\nconst app = choo();\n//app.use(state);\napp.use(controller);\napp.use(intents);\n\nwindow.finishLogin = async function(accountInfo) {\n  while (!(app.state && app.state.user)) {\n    await delay();\n  }\n  await app.state.user.finishLogin(accountInfo);\n  await app.state.user.syncFileList();\n  app.emitter.emit('replaceState', '/');\n};\n\nfunction body(main) {\n  return function(state, emit) {\n    /*\n      Disable the preferences menu for now since it is ugly and isn't\n      relevant to the beta\n    function clickPreferences(event) {\n      event.preventDefault();\n      emit('pushState', '/preferences');\n    }\n\n    const menu = html`<a\n        id=\"hamburger\"\n        class=\"absolute top-0 right-0 z-50\"\n        href=\"#\"\n        onclick=\"${clickPreferences}\"\n      >\n        <img src=\"${assets.get('preferences.png')}\" />\n      </a>`;\n    */\n    return html`\n      <body class=\"flex flex-col items-center font-sans bg-grey-10 h-screen\">\n        ${state.cache(Header, 'header').render()} ${main(state, emit)}\n      </body>\n    `;\n  };\n}\n(async function start() {\n  const translate = await getTranslator('en-US');\n  setTranslate(translate);\n  const { LIMITS, DEFAULTS } = await getConstants();\n  app.use(state => {\n    state.LIMITS = LIMITS;\n    state.DEFAULTS = DEFAULTS;\n    state.translate = translate;\n    state.capabilities = {\n      account: true\n    }; //TODO\n    state.archive = new Archive([], DEFAULTS.EXPIRE_SECONDS);\n    state.storage = storage;\n    state.user = new User(storage, LIMITS);\n    state.sentry = Sentry;\n  });\n  app.use(metrics);\n  app.route('/', body(home));\n  app.route('/upload', upload);\n  app.route('/share/:id', share);\n  app.route('/preferences', preferences);\n  app.route('/error', error);\n  //app.route('/debugging', require('./pages/debugging').default);\n  // add /api/filelist\n  app.mount('body');\n})();\n\nwindow.app = app;\n"
  },
  {
    "path": "android/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "android/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-android-extensions'\n\nandroid {\n    compileSdkVersion 27\n    defaultConfig {\n        applicationId \"org.mozilla.firefoxsend\"\n        minSdkVersion 26\n        targetSdkVersion 27\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    implementation\"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version\"\n    implementation 'com.android.support:appcompat-v7:27.1.1'\n    implementation 'com.android.support.constraint:constraint-layout:1.1.3'\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'com.android.support.test:runner:1.0.2'\n    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'\n    implementation 'com.github.delight-im:Android-AdvancedWebView:v3.0.0'\n    implementation \"org.mozilla.components:service-firefox-accounts:$android_components_version\"\n}\n\ntask generateAndLinkBundle(type: Exec, description: 'Generate the android.js bundle and link it into the assets directory') {\n    commandLine './buildAssets.sh'\n}\n\ntasks.withType(JavaCompile) {\n    compileTask -> compileTask.dependsOn generateAndLinkBundle\n}\n"
  },
  {
    "path": "android/app/buildAssets.sh",
    "content": "#!/usr/bin/env bash\nif [ -d \"../../node_modules\" ]\nthen\n  echo \"node_modules already present.\"\nelse\n  echo \"node_modules not present, running npm install.\"\n  npm install\nfi\nnpm run build\nrm -rf src/main/assets\nmkdir -p src/main/assets\ncp -R ../../dist/* src/main/assets\n"
  },
  {
    "path": "android/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "android/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"org.mozilla.firefoxsend\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <meta-data android:name=\"android.webkit.WebView.EnableSafeBrowsing\" android:value=\"false\" />\n        <activity android:name=\"org.mozilla.firefoxsend.MainActivity\" android:screenOrientation=\"portrait\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.SEND\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <data android:mimeType=\"image/*\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.SEND\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <data android:mimeType=\"text/plain\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "android/app/src/main/java/org/mozilla/firefoxsend/MainActivity.kt",
    "content": "package org.mozilla.firefoxsend\n\nimport android.annotation.SuppressLint\nimport android.content.ComponentName\nimport android.content.Intent\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport android.os.Bundle\nimport android.support.v7.app.AppCompatActivity\nimport android.util.Base64\nimport android.util.Log\nimport android.view.View\nimport android.webkit.*\nimport im.delight.android.webview.AdvancedWebView\nimport kotlinx.android.synthetic.main.activity_main.*\nimport mozilla.components.service.fxa.Config\nimport mozilla.components.service.fxa.FirefoxAccount\nimport mozilla.components.service.fxa.FxaResult\nimport org.json.JSONObject\n\ninternal class LoggingWebChromeClient : WebChromeClient() {\n    override fun onConsoleMessage(cm: ConsoleMessage): Boolean {\n        Log.d(TAG, String.format(\"%s @ %d: %s\",\n                cm.message(), cm.lineNumber(), cm.sourceId()))\n        return true\n    }\n\n    companion object {\n        private const val TAG = \"CONTENT\"\n    }\n}\n\nclass WebAppInterface(private val mContext: MainActivity) {\n    @JavascriptInterface\n    fun beginOAuthFlow() {\n        mContext.beginOAuthFlow()\n    }\n\n    @JavascriptInterface\n    fun shareUrl(url: String) {\n        mContext.shareUrl(url)\n    }\n}\n\nclass MainActivity : AppCompatActivity(), AdvancedWebView.Listener {\n\n    private var mToShare: String? = null\n    private var mToCall: String? = null\n    private var mAccount: FirefoxAccount? = null\n\n    @SuppressLint(\"SetJavaScriptEnabled\")\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_main)\n\n        WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG)\n        webView.apply {\n            setListener(this@MainActivity, this@MainActivity)\n            addJavascriptInterface(WebAppInterface(this@MainActivity), JS_INTERFACE_NAME)\n            setLayerType(View.LAYER_TYPE_HARDWARE, null)\n            webChromeClient = LoggingWebChromeClient()\n\n            settings.apply {\n                userAgentString = \"Send Android\"\n                allowUniversalAccessFromFileURLs = true\n                javaScriptEnabled = true\n            }\n        }\n\n        val type = intent.type\n        if (Intent.ACTION_SEND == intent.action && type != null) {\n            if (type == \"text/plain\") {\n                val sharedText = intent.getStringExtra(Intent.EXTRA_TEXT)\n                // Log.d(TAG_INTENT, \"text/plain $sharedText\")\n                mToShare = \"data:text/plain;base64,\" + Base64.encodeToString(sharedText.toByteArray(), 16).trim()\n            } else if (type.startsWith(\"image/\")) {\n                val imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM) as Uri\n                // Log.d(TAG_INTENT, \"image/ $imageUri\")\n                mToShare = \"data:text/plain;base64,\" + Base64.encodeToString(imageUri.path.toByteArray(), 16).trim()\n            }\n        }\n        webView.loadUrl(\"file:///android_asset/android.html\")\n    }\n\n    fun beginOAuthFlow() {\n        Config.release().then { value ->\n            mAccount = FirefoxAccount(value, \"20f7931c9054d833\", \"https://send.firefox.com/fxa/android-redirect.html\")\n            mAccount?.beginOAuthFlow(arrayOf(\"profile\", \"https://identity.mozilla.com/apps/send\"), true)\n                    ?.then { url ->\n                        // Log.d(TAG_CONFIG, \"GOT A URL $url\")\n                        this@MainActivity.runOnUiThread {\n                            webView.loadUrl(url)\n                        }\n                        FxaResult.fromValue(Unit)\n                    }\n            // Log.d(TAG_CONFIG, \"CREATED FIREFOXACCOUNT\")\n            FxaResult.fromValue(Unit)\n        }\n    }\n\n    fun shareUrl(url: String) {\n        val shareIntent = Intent().apply {\n            action = Intent.ACTION_SEND\n            type = \"text/plain\"\n            putExtra(Intent.EXTRA_TEXT, url)\n        }\n\n        val components = arrayOf(ComponentName(applicationContext, MainActivity::class.java))\n        val chooser = Intent.createChooser(shareIntent, \"\")\n                .putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, components)\n\n        startActivity(chooser)\n    }\n\n    override fun onResume() {\n        super.onResume()\n        webView.onResume()\n    }\n\n    override fun onPause() {\n        webView.onPause()\n        super.onPause()\n    }\n\n    override fun onDestroy() {\n        webView.onDestroy()\n        super.onDestroy()\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {\n        super.onActivityResult(requestCode, resultCode, intent)\n        webView.onActivityResult(requestCode, resultCode, intent)\n    }\n\n    override fun onBackPressed() {\n        if (!webView.onBackPressed()) {\n            return\n        }\n        super.onBackPressed()\n    }\n\n    override fun onPageStarted(url: String, favicon: Bitmap?) {\n        if (url.startsWith(\"https://send.firefox.com/fxa/android-redirect.html\")) {\n            // We load this here so the user doesn't see the android-redirect.html page\n            webView.loadUrl(\"file:///android_asset/android.html\")\n\n            val uri = Uri.parse(url)\n            uri.getQueryParameter(\"code\")?.let { code ->\n                uri.getQueryParameter(\"state\")?.let { state ->\n                    mAccount?.completeOAuthFlow(code, state)?.whenComplete { info ->\n                        mAccount?.getProfile(false)?.then { profile ->\n                            val profileJsonPayload = JSONObject()\n                                    .put(\"accessToken\", info.accessToken)\n                                    .put(\"keys\", info.keys)\n                                    .put(\"avatar\", profile.avatar)\n                                    .put(\"displayName\", profile.displayName)\n                                    .put(\"email\", profile.email)\n                                    .put(\"uid\", profile.uid).toString()\n                            mToCall = \"finishLogin($profileJsonPayload)\"\n                            this@MainActivity.runOnUiThread {\n                                // Clear the history so that the user can't use the back button to see broken pages\n                                // that were inserted into the history by the login process.\n                                webView.clearHistory()\n\n                                // We also reload this here because we need to make sure onPageFinished runs after mToCall has been set.\n                                // We can't guarantee that onPageFinished wasn't already called at this point.\n                                webView.loadUrl(\"file:///android_asset/android.html\")\n                            }\n                            FxaResult.fromValue(Unit)\n                        }\n                    }\n                }\n            }\n        }\n        if (!url.startsWith(\"file:///android_asset/\") && !url.startsWith(\"https://accounts.firefox.com/\")) {\n            // Don't allow loading anything other than the app in our webview\n            // It should be possible to do this with shouldOverrideUrlLoading\n            // but it didn't seem to be working, so this works as a hack.\n            webView.loadUrl(\"file:///android_asset/android.html\")\n            Log.d(TAG_MAIN, \"BAD URL \" + url)\n        } else {\n            // Log.d(TAG_MAIN, \"onPageStarted \" + url)\n        }\n    }\n\n    override fun onPageFinished(url: String) {\n        // Log.d(TAG_MAIN, \"onPageFinished\")\n        if (mToShare != null) {\n            // Log.d(TAG_INTENT, mToShare)\n\n            webView.postWebMessage(WebMessage(mToShare), Uri.EMPTY)\n            mToShare = null\n        }\n        if (mToCall != null) {\n            this@MainActivity.runOnUiThread {\n                webView.evaluateJavascript(mToCall) {\n                    mToCall = null\n                }\n            }\n        }\n    }\n\n    override fun onPageError(errorCode: Int, description: String, failingUrl: String) {\n        Log.d(TAG_MAIN, \"onPageError($errorCode, $description, $failingUrl)\")\n    }\n\n    override fun onDownloadRequested(url: String,\n                                     suggestedFilename: String,\n                                     mimeType: String,\n                                     contentLength: Long,\n                                     contentDisposition: String,\n                                     userAgent: String) {\n        // Log.d(TAG_MAIN, \"onDownloadRequested\")\n    }\n\n    override fun onExternalPageRequest(url: String) {\n        // Log.d(TAG_MAIN, \"onExternalPageRequest($url)\")\n    }\n\n    companion object {\n        private const val TAG_MAIN = \"MAIN\"\n        private const val TAG_INTENT = \"INTENT\"\n        private const val TAG_CONFIG = \"CONFIG\"\n        private const val JS_INTERFACE_NAME = \"Android\"\n    }\n}\n"
  },
  {
    "path": "android/app/src/main/res/drawable/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"92.5\"\n    android:viewportHeight=\"92.5\">\n  <group android:translateX=\"27.75\"\n      android:translateY=\"28.25\">\n    <path\n        android:pathData=\"M18.1313,0.0003C8.1363,0.0003 0.0003,7.9743 0.0003,17.7673C0.0003,18.8133 0.8523,19.6643 1.8983,19.6643L16.2333,19.6643L16.2333,29.1093L11.7773,24.6963C11.0413,23.9613 9.8403,23.9613 9.0653,24.6963C8.3293,25.4323 8.3293,26.6323 9.0653,27.4063L16.7753,35.1093C16.8143,35.1483 16.8533,35.1873 16.9303,35.2253L16.9693,35.2253C17.0083,35.2643 17.0463,35.3033 17.0853,35.3033L17.1243,35.3033C17.1633,35.3423 17.2013,35.3423 17.2403,35.3803L17.2793,35.3803C17.3183,35.4193 17.3953,35.4193 17.4343,35.4583C17.4733,35.4963 17.5503,35.4963 17.5893,35.4963C17.6283,35.4963 17.7053,35.5353 17.7443,35.5353L17.7823,35.5353C17.8213,35.5353 17.8603,35.5353 17.9373,35.5743L18.3253,35.5743C18.3643,35.5743 18.4023,35.5743 18.4803,35.5353L18.5193,35.5353C18.5573,35.5353 18.6353,35.4963 18.6743,35.4963C18.7123,35.4963 18.7903,35.4583 18.8293,35.4193C18.8673,35.3803 18.9453,35.3803 18.9843,35.3423C19.0223,35.3033 19.0613,35.3033 19.1003,35.2643L19.1383,35.2643C19.1773,35.2253 19.2163,35.1873 19.2553,35.1873L19.2933,35.1873C19.3323,35.1483 19.3713,35.1093 19.4483,35.0713L27.1583,27.3673C27.8943,26.6323 27.8943,25.4323 27.1583,24.6583C26.4223,23.9223 25.2213,23.9223 24.4463,24.6583L20.0303,29.1093L20.0303,19.7033L34.3643,19.7033C35.4103,19.7033 36.2633,18.8513 36.2633,17.8063C36.2633,7.9743 28.1273,0.0003 18.1313,0.0003ZM3.9133,15.8713C4.8813,9.0963 10.8863,3.8323 18.1313,3.8323C25.3763,3.8323 31.3423,9.0963 32.3113,15.8713L3.9133,15.8713Z\"\n        android:fillType=\"nonZero\">\n      <aapt:attr name=\"android:fillColor\">\n        <gradient \n            android:startY=\"2.9809632\"\n            android:startX=\"25.805717\"\n            android:endY=\"31.687763\"\n            android:endX=\"8.569217\"\n            android:type=\"linear\">\n          <item android:offset=\"0\" android:color=\"#FFFF980E\"/>\n          <item android:offset=\"0.21\" android:color=\"#FFFF7139\"/>\n          <item android:offset=\"0.36\" android:color=\"#FFFF5854\"/>\n          <item android:offset=\"0.46\" android:color=\"#FFFF4F5E\"/>\n          <item android:offset=\"0.69\" android:color=\"#FFFF3750\"/>\n          <item android:offset=\"0.86\" android:color=\"#FFF92261\"/>\n          <item android:offset=\"1\" android:color=\"#FFF5156C\"/>\n        </gradient>\n      </aapt:attr>\n    </path>\n    <path\n        android:pathData=\"M18.1313,0.0003C8.1363,0.0003 0.0003,7.9743 0.0003,17.7673C0.0003,18.8133 0.8523,19.6643 1.8983,19.6643L16.2333,19.6643L16.2333,29.1093L11.7773,24.6963C11.0413,23.9613 9.8403,23.9613 9.0653,24.6963C8.3293,25.4323 8.3293,26.6323 9.0653,27.4063L16.7753,35.1093C16.8143,35.1483 16.8533,35.1873 16.9303,35.2253L16.9693,35.2253C17.0083,35.2643 17.0463,35.3033 17.0853,35.3033L17.1243,35.3033C17.1633,35.3423 17.2013,35.3423 17.2403,35.3803L17.2793,35.3803C17.3183,35.4193 17.3953,35.4193 17.4343,35.4583C17.4733,35.4963 17.5503,35.4963 17.5893,35.4963C17.6283,35.4963 17.7053,35.5353 17.7443,35.5353L17.7823,35.5353C17.8213,35.5353 17.8603,35.5353 17.9373,35.5743L18.3253,35.5743C18.3643,35.5743 18.4023,35.5743 18.4803,35.5353L18.5193,35.5353C18.5573,35.5353 18.6353,35.4963 18.6743,35.4963C18.7123,35.4963 18.7903,35.4583 18.8293,35.4193C18.8673,35.3803 18.9453,35.3803 18.9843,35.3423C19.0223,35.3033 19.0613,35.3033 19.1003,35.2643L19.1383,35.2643C19.1773,35.2253 19.2163,35.1873 19.2553,35.1873L19.2933,35.1873C19.3323,35.1483 19.3713,35.1093 19.4483,35.0713L27.1583,27.3673C27.8943,26.6323 27.8943,25.4323 27.1583,24.6583C26.4223,23.9223 25.2213,23.9223 24.4463,24.6583L20.0303,29.1093L20.0303,19.7033L34.3643,19.7033C35.4103,19.7033 36.2633,18.8513 36.2633,17.8063C36.2633,7.9743 28.1273,0.0003 18.1313,0.0003ZM3.9133,15.8713C4.8813,9.0963 10.8863,3.8323 18.1313,3.8323C25.3763,3.8323 31.3423,9.0963 32.3113,15.8713L3.9133,15.8713Z\"\n        android:fillType=\"nonZero\">\n      <aapt:attr name=\"android:fillColor\">\n        <gradient \n            android:startY=\"2.9809632\"\n            android:startX=\"25.805717\"\n            android:endY=\"31.687763\"\n            android:endX=\"8.569217\"\n            android:type=\"linear\">\n          <item android:offset=\"0\" android:color=\"#CCFFF44F\"/>\n          <item android:offset=\"0.75\" android:color=\"#00FFF44F\"/>\n          <item android:offset=\"1\" android:color=\"#00FFF44F\"/>\n        </gradient>\n      </aapt:attr>\n    </path>\n    <path\n        android:pathData=\"M20.0303,3.9483C26.3833,4.8003 31.4203,9.6773 32.3113,15.8713L23.8653,15.8713C21.7733,15.8713 20.0683,17.5743 20.0683,19.6643L34.3643,19.6643C35.4103,19.6643 36.2633,18.8133 36.2633,17.7673C36.2633,10.9933 31.4593,7.6643 27.3913,5.7673C23.6333,4.0253 20.0303,3.9483 20.0303,3.9483Z\">\n      <aapt:attr name=\"android:fillColor\">\n        <gradient \n            android:startY=\"20.534323\"\n            android:startX=\"22.366518\"\n            android:endY=\"7.772023\"\n            android:endX=\"30.234228\"\n            android:type=\"linear\">\n          <item android:offset=\"0\" android:color=\"#FF3A8EE6\"/>\n          <item android:offset=\"0.24\" android:color=\"#FF5C79F0\"/>\n          <item android:offset=\"0.63\" android:color=\"#FF9059FF\"/>\n          <item android:offset=\"1\" android:color=\"#FFC139E6\"/>\n        </gradient>\n      </aapt:attr>\n    </path>\n    <path\n        android:pathData=\"M32.2333,15.4453C33.5123,16.4903 34.8293,17.4963 36.0693,18.5803C36.1853,18.3483 36.2633,18.0773 36.2633,17.7673C36.2633,10.9933 31.4593,7.6643 27.3913,5.7673C23.6333,4.0253 20.0303,3.9483 20.0303,3.9483C26.2283,4.7613 31.1873,9.4843 32.2333,15.4453Z\">\n      <aapt:attr name=\"android:fillColor\">\n        <gradient \n            android:startY=\"8.195093\"\n            android:startX=\"30.235817\"\n            android:endY=\"12.836453\"\n            android:endX=\"26.934916\"\n            android:type=\"linear\">\n          <item android:offset=\"0\" android:color=\"#7E6E008B\"/>\n          <item android:offset=\"0.5\" android:color=\"#00C846CB\"/>\n          <item android:offset=\"1\" android:color=\"#00C846CB\"/>\n        </gradient>\n      </aapt:attr>\n    </path>\n    <path\n        android:pathData=\"M32.0013,15.8713L23.8653,15.8713C21.7733,15.8713 20.0683,17.5743 20.0683,19.6643L34.3643,19.6643C34.9453,19.6643 35.4883,19.3933 35.8373,18.9673C34.5583,17.9223 33.2793,16.9163 32.0013,15.8713Z\">\n      <aapt:attr name=\"android:fillColor\">\n        <gradient \n            android:startY=\"18.076923\"\n            android:startX=\"31.69962\"\n            android:endY=\"17.594997\"\n            android:endX=\"23.366179\"\n            android:type=\"linear\">\n          <item android:offset=\"0\" android:color=\"#006A2BEA\"/>\n          <item android:offset=\"0.14\" android:color=\"#006A2BEA\"/>\n          <item android:offset=\"0.3\" android:color=\"#15662CE6\"/>\n          <item android:offset=\"0.47\" android:color=\"#2C592FDB\"/>\n          <item android:offset=\"0.64\" android:color=\"#424534C9\"/>\n          <item android:offset=\"0.82\" android:color=\"#59283BAF\"/>\n          <item android:offset=\"0.99\" android:color=\"#7003448D\"/>\n          <item android:offset=\"1\" android:color=\"#7200458B\"/>\n        </gradient>\n      </aapt:attr>\n    </path>\n  </group>\n</vector>\n"
  },
  {
    "path": "android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        xmlns:aapt=\"http://schemas.android.com/aapt\"\n        android:width=\"108dp\"\n        android:height=\"108dp\"\n        android:viewportWidth=\"92.5\"\n        android:viewportHeight=\"92.5\">\n    <group android:translateX=\"27.75\"\n            android:translateY=\"28.25\">\n      <path\n          android:pathData=\"M18.1313,0.0003C8.1363,0.0003 0.0003,7.9743 0.0003,17.7673C0.0003,18.8133 0.8523,19.6643 1.8983,19.6643L16.2333,19.6643L16.2333,29.1093L11.7773,24.6963C11.0413,23.9613 9.8403,23.9613 9.0653,24.6963C8.3293,25.4323 8.3293,26.6323 9.0653,27.4063L16.7753,35.1093C16.8143,35.1483 16.8533,35.1873 16.9303,35.2253L16.9693,35.2253C17.0083,35.2643 17.0463,35.3033 17.0853,35.3033L17.1243,35.3033C17.1633,35.3423 17.2013,35.3423 17.2403,35.3803L17.2793,35.3803C17.3183,35.4193 17.3953,35.4193 17.4343,35.4583C17.4733,35.4963 17.5503,35.4963 17.5893,35.4963C17.6283,35.4963 17.7053,35.5353 17.7443,35.5353L17.7823,35.5353C17.8213,35.5353 17.8603,35.5353 17.9373,35.5743L18.3253,35.5743C18.3643,35.5743 18.4023,35.5743 18.4803,35.5353L18.5193,35.5353C18.5573,35.5353 18.6353,35.4963 18.6743,35.4963C18.7123,35.4963 18.7903,35.4583 18.8293,35.4193C18.8673,35.3803 18.9453,35.3803 18.9843,35.3423C19.0223,35.3033 19.0613,35.3033 19.1003,35.2643L19.1383,35.2643C19.1773,35.2253 19.2163,35.1873 19.2553,35.1873L19.2933,35.1873C19.3323,35.1483 19.3713,35.1093 19.4483,35.0713L27.1583,27.3673C27.8943,26.6323 27.8943,25.4323 27.1583,24.6583C26.4223,23.9223 25.2213,23.9223 24.4463,24.6583L20.0303,29.1093L20.0303,19.7033L34.3643,19.7033C35.4103,19.7033 36.2633,18.8513 36.2633,17.8063C36.2633,7.9743 28.1273,0.0003 18.1313,0.0003ZM3.9133,15.8713C4.8813,9.0963 10.8863,3.8323 18.1313,3.8323C25.3763,3.8323 31.3423,9.0963 32.3113,15.8713L3.9133,15.8713Z\"\n          android:fillType=\"nonZero\">\n        <aapt:attr name=\"android:fillColor\">\n          <gradient\n              android:startY=\"2.9809632\"\n              android:startX=\"25.805717\"\n              android:endY=\"31.687763\"\n              android:endX=\"8.569217\"\n              android:type=\"linear\">\n            <item android:offset=\"0\" android:color=\"#FFFF980E\"/>\n            <item android:offset=\"0.21\" android:color=\"#FFFF7139\"/>\n            <item android:offset=\"0.36\" android:color=\"#FFFF5854\"/>\n            <item android:offset=\"0.46\" android:color=\"#FFFF4F5E\"/>\n            <item android:offset=\"0.69\" android:color=\"#FFFF3750\"/>\n            <item android:offset=\"0.86\" android:color=\"#FFF92261\"/>\n            <item android:offset=\"1\" android:color=\"#FFF5156C\"/>\n          </gradient>\n        </aapt:attr>\n      </path>\n      <path\n          android:pathData=\"M18.1313,0.0003C8.1363,0.0003 0.0003,7.9743 0.0003,17.7673C0.0003,18.8133 0.8523,19.6643 1.8983,19.6643L16.2333,19.6643L16.2333,29.1093L11.7773,24.6963C11.0413,23.9613 9.8403,23.9613 9.0653,24.6963C8.3293,25.4323 8.3293,26.6323 9.0653,27.4063L16.7753,35.1093C16.8143,35.1483 16.8533,35.1873 16.9303,35.2253L16.9693,35.2253C17.0083,35.2643 17.0463,35.3033 17.0853,35.3033L17.1243,35.3033C17.1633,35.3423 17.2013,35.3423 17.2403,35.3803L17.2793,35.3803C17.3183,35.4193 17.3953,35.4193 17.4343,35.4583C17.4733,35.4963 17.5503,35.4963 17.5893,35.4963C17.6283,35.4963 17.7053,35.5353 17.7443,35.5353L17.7823,35.5353C17.8213,35.5353 17.8603,35.5353 17.9373,35.5743L18.3253,35.5743C18.3643,35.5743 18.4023,35.5743 18.4803,35.5353L18.5193,35.5353C18.5573,35.5353 18.6353,35.4963 18.6743,35.4963C18.7123,35.4963 18.7903,35.4583 18.8293,35.4193C18.8673,35.3803 18.9453,35.3803 18.9843,35.3423C19.0223,35.3033 19.0613,35.3033 19.1003,35.2643L19.1383,35.2643C19.1773,35.2253 19.2163,35.1873 19.2553,35.1873L19.2933,35.1873C19.3323,35.1483 19.3713,35.1093 19.4483,35.0713L27.1583,27.3673C27.8943,26.6323 27.8943,25.4323 27.1583,24.6583C26.4223,23.9223 25.2213,23.9223 24.4463,24.6583L20.0303,29.1093L20.0303,19.7033L34.3643,19.7033C35.4103,19.7033 36.2633,18.8513 36.2633,17.8063C36.2633,7.9743 28.1273,0.0003 18.1313,0.0003ZM3.9133,15.8713C4.8813,9.0963 10.8863,3.8323 18.1313,3.8323C25.3763,3.8323 31.3423,9.0963 32.3113,15.8713L3.9133,15.8713Z\"\n          android:fillType=\"nonZero\">\n        <aapt:attr name=\"android:fillColor\">\n          <gradient\n              android:startY=\"2.9809632\"\n              android:startX=\"25.805717\"\n              android:endY=\"31.687763\"\n              android:endX=\"8.569217\"\n              android:type=\"linear\">\n            <item android:offset=\"0\" android:color=\"#CCFFF44F\"/>\n            <item android:offset=\"0.75\" android:color=\"#00FFF44F\"/>\n            <item android:offset=\"1\" android:color=\"#00FFF44F\"/>\n          </gradient>\n        </aapt:attr>\n      </path>\n      <path\n          android:pathData=\"M20.0303,3.9483C26.3833,4.8003 31.4203,9.6773 32.3113,15.8713L23.8653,15.8713C21.7733,15.8713 20.0683,17.5743 20.0683,19.6643L34.3643,19.6643C35.4103,19.6643 36.2633,18.8133 36.2633,17.7673C36.2633,10.9933 31.4593,7.6643 27.3913,5.7673C23.6333,4.0253 20.0303,3.9483 20.0303,3.9483Z\">\n        <aapt:attr name=\"android:fillColor\">\n          <gradient\n              android:startY=\"20.534323\"\n              android:startX=\"22.366518\"\n              android:endY=\"7.772023\"\n              android:endX=\"30.234228\"\n              android:type=\"linear\">\n            <item android:offset=\"0\" android:color=\"#FF3A8EE6\"/>\n            <item android:offset=\"0.24\" android:color=\"#FF5C79F0\"/>\n            <item android:offset=\"0.63\" android:color=\"#FF9059FF\"/>\n            <item android:offset=\"1\" android:color=\"#FFC139E6\"/>\n          </gradient>\n        </aapt:attr>\n      </path>\n      <path\n          android:pathData=\"M32.2333,15.4453C33.5123,16.4903 34.8293,17.4963 36.0693,18.5803C36.1853,18.3483 36.2633,18.0773 36.2633,17.7673C36.2633,10.9933 31.4593,7.6643 27.3913,5.7673C23.6333,4.0253 20.0303,3.9483 20.0303,3.9483C26.2283,4.7613 31.1873,9.4843 32.2333,15.4453Z\">\n        <aapt:attr name=\"android:fillColor\">\n          <gradient\n              android:startY=\"8.195093\"\n              android:startX=\"30.235817\"\n              android:endY=\"12.836453\"\n              android:endX=\"26.934916\"\n              android:type=\"linear\">\n            <item android:offset=\"0\" android:color=\"#7E6E008B\"/>\n            <item android:offset=\"0.5\" android:color=\"#00C846CB\"/>\n            <item android:offset=\"1\" android:color=\"#00C846CB\"/>\n          </gradient>\n        </aapt:attr>\n      </path>\n      <path\n          android:pathData=\"M32.0013,15.8713L23.8653,15.8713C21.7733,15.8713 20.0683,17.5743 20.0683,19.6643L34.3643,19.6643C34.9453,19.6643 35.4883,19.3933 35.8373,18.9673C34.5583,17.9223 33.2793,16.9163 32.0013,15.8713Z\">\n        <aapt:attr name=\"android:fillColor\">\n          <gradient\n              android:startY=\"18.076923\"\n              android:startX=\"31.69962\"\n              android:endY=\"17.594997\"\n              android:endX=\"23.366179\"\n              android:type=\"linear\">\n            <item android:offset=\"0\" android:color=\"#006A2BEA\"/>\n            <item android:offset=\"0.14\" android:color=\"#006A2BEA\"/>\n            <item android:offset=\"0.3\" android:color=\"#15662CE6\"/>\n            <item android:offset=\"0.47\" android:color=\"#2C592FDB\"/>\n            <item android:offset=\"0.64\" android:color=\"#424534C9\"/>\n            <item android:offset=\"0.82\" android:color=\"#59283BAF\"/>\n            <item android:offset=\"0.99\" android:color=\"#7003448D\"/>\n            <item android:offset=\"1\" android:color=\"#7200458B\"/>\n          </gradient>\n        </aapt:attr>\n      </path>\n    </group>\n</vector>\n"
  },
  {
    "path": "android/app/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<im.delight.android.webview.AdvancedWebView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/webView\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".MainActivity\" />"
  },
  {
    "path": "android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@color/ic_launcher_background\"/>\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\"/>\n</adaptive-icon>"
  },
  {
    "path": "android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@color/ic_launcher_background\"/>\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\"/>\n</adaptive-icon>"
  },
  {
    "path": "android/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "android/app/src/main/res/values/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"ic_launcher_background\">#220033</color>\n</resources>"
  },
  {
    "path": "android/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Send</string>\n</resources>\n"
  },
  {
    "path": "android/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "android/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    ext.kotlin_version = '1.3.21'\n    ext.android_components_version = '0.26.0'\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.3.2'\n        classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21\"\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        maven { url \"https://maven.mozilla.org/maven2\" }\n        jcenter()\n        maven { url \"https://jitpack.io\" }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "android/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Tue Feb 19 08:34:25 EST 2019\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.10.1-all.zip\n"
  },
  {
    "path": "android/gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n"
  },
  {
    "path": "android/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "android/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "android/pages/.eslintrc.yaml",
    "content": "env:\n  browser: true\n\nparserOptions:\n  sourceType: module\n\n"
  },
  {
    "path": "android/pages/error.js",
    "content": "const html = require('choo/html');\n\nexport default function error(_state, _emit) {\n  return html`\n    <body>\n      <div id=\"white\">\n        <h1>Error</h1>\n        <p>Sorry, an error occurred.</p>\n      </div>\n    </body>\n  `;\n}\n"
  },
  {
    "path": "android/pages/home.js",
    "content": "const html = require('choo/html');\nconst { list } = require('../../app/utils');\nconst archiveTile = require('../../app/ui/archiveTile');\nconst modal = require('../../app/ui/modal');\nconst intro = require('../../app/ui/intro');\nconst assets = require('../../common/assets');\n\nmodule.exports = function(state, emit) {\n  function onchange(event) {\n    event.preventDefault();\n    const newFiles = Array.from(event.target.files);\n\n    emit('addFiles', { files: newFiles });\n  }\n\n  function onclick() {\n    document.getElementById('file-upload').click();\n  }\n\n  const archives = state.storage.files\n    .filter(archive => !archive.expired)\n    .map(archive => archiveTile(state, emit, archive))\n    .reverse();\n\n  let content = '';\n  let button = html`\n    <div\n      class=\"bg-blue-50 rounded-full m-4 flex items-center justify-center shadow-lg\"\n      style=\"width: 56px; height: 56px\"\n      onclick=\"${onclick}\"\n    >\n      <img src=\"${assets.get('add.svg')}\" />\n    </div>\n  `;\n  if (state.uploading) {\n    content = archiveTile.uploading(state, emit);\n    button = '';\n  } else if (state.archive.numFiles > 0) {\n    content = archiveTile.wip(state, emit);\n    button = '';\n  } else {\n    content =\n      archives.length < 1\n        ? intro(state)\n        : list(archives, 'h-full overflow-y-auto w-full', 'mb-3 w-full');\n  }\n\n  return html`\n    <main class=\"main\">\n      ${state.modal && modal(state, emit)}\n      <section\n        class=\"h-full w-full p-6 z-10 overflow-hidden md:flex md:flex-row md:rounded-lg md:shadow-big\"\n      >\n        ${content}\n      </section>\n      <div class=\"fixed right-0 bottom-0 z-20\">\n        ${button}\n        <input\n          id=\"file-upload\"\n          class=\"hidden\"\n          type=\"file\"\n          multiple\n          onchange=\"${onchange}\"\n          onclick=\"${e => e.stopPropagation()}\"\n        />\n      </div>\n    </main>\n  `;\n};\n"
  },
  {
    "path": "android/pages/preferences.js",
    "content": "const html = require('choo/html');\n\nimport { setFileProtocolWssUrl, getFileProtocolWssUrl } from '../../app/api';\n\nexport default function preferences(state, emit) {\n  const wssURL = getFileProtocolWssUrl();\n\n  function updateWssUrl(event) {\n    state.wssURL = event.target.value;\n    setFileProtocolWssUrl(state.wssURL);\n    emit('render');\n  }\n\n  function clickDone(event) {\n    event.preventDefault();\n    emit('pushState', '/');\n  }\n\n  return html`\n    <body>\n      <div id=\"white\">\n        <div id=\"preferences\">\n          <a onclick=\"${clickDone}\" href=\"#\"> done </a>\n          <dl>\n            <dt>wss url:</dt>\n            <dd>\n              <input type=\"text\" onchange=\"${updateWssUrl}\" value=\"${wssURL}\" />\n            </dd>\n          </dl>\n        </div>\n      </div>\n    </body>\n  `;\n}\n"
  },
  {
    "path": "android/pages/share.js",
    "content": "const html = require('choo/html');\n\nexport default function uploadComplete(state, emit) {\n  const file = state.storage.files[state.storage.files.length - 1];\n  function onclick(e) {\n    e.preventDefault();\n    input.select();\n    document.execCommand('copy');\n    input.selectionEnd = input.selectionStart;\n    copyText.textContent = 'Copied!';\n    setTimeout(function() {\n      copyText.textContent = 'Copy link';\n    }, 2000);\n  }\n\n  function uploadFile(event) {\n    event.preventDefault();\n    const target = event.target;\n    const file = target.files[0];\n    if (file.size === 0) {\n      return;\n    }\n\n    emit('pushState', '/upload');\n    emit('addFiles', { files: [file] });\n    emit('upload', {});\n  }\n\n  const input = html`\n    <input id=\"url\" value=\"${file.url}\" readonly=\"true\" />\n  `;\n  const copyText = html`\n    <span>Copy link</span>\n  `;\n  return html`<body>\n  <div id=\"white\">\n    <div class=\"card\">\n      <div>The card contents will be here.</div>\n      <div>Expires after: <span class=\"expires-after\">exp</span></div>\n      ${input}\n      <div id=\"copy-link\" onclick=${onclick}>\n        <img id=\"copy-image\" src=${state.getAsset('copy-link.png')} />\n        ${copyText}\n      </div>\n      <label id=\"label\" for=\"input\">\n        <img src=${state.getAsset('cloud-upload.png')} />\n      </label>\n      <input id=\"input\" name=\"input\" type=\"file\" onchange=${uploadFile} />\n  </div>\n</body>`;\n}\n"
  },
  {
    "path": "android/pages/upload.js",
    "content": "const html = require('choo/html');\n\nexport default function progressBar(state, emit) {\n  let percent = 0;\n  if (state.transfer && state.transfer.progress) {\n    percent = Math.floor(state.transfer.progressRatio * 100);\n  }\n  function onclick(e) {\n    e.preventDefault();\n    if (state.uploading) {\n      emit('cancel');\n    }\n    emit('pushState', '/');\n  }\n  return html`\n    <body>\n      <div id=\"white\">\n        <div class=\"card\">\n          <div>${percent}%</div>\n          <span class=\"progress\" style=\"width: ${percent}%\">.</span>\n          <div class=\"cancel\" onclick=\"${onclick}\">CANCEL</div>\n        </div>\n      </div>\n    </body>\n  `;\n}\n"
  },
  {
    "path": "android/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "android/stores/intents.js",
    "content": "/* eslint-disable no-console */\n\nexport default function intentHandler(state, emitter) {\n  window.addEventListener(\n    'message',\n    event => {\n      if (typeof event.data !== 'string' || !event.data.startsWith('data:')) {\n        return;\n      }\n      fetch(event.data)\n        .then(res => res.blob())\n        .then(blob => {\n          emitter.emit('addFiles', { files: [blob] });\n          emitter.emit('upload', {});\n        })\n        .catch(e => console.error('ERROR ' + e + ' ' + e.stack));\n    },\n    false\n  );\n}\n"
  },
  {
    "path": "android/stores/state.js",
    "content": "/* eslint-disable no-console */\n\nimport User from '../user';\nimport storage from '../../app/storage';\n\nexport default function initialState(state, emitter) {\n  const files = [];\n\n  Object.assign(state, {\n    prefix: '/android_asset',\n    user: new User(storage),\n    getAsset(name) {\n      return `${state.prefix}/${name}`;\n    },\n    sentry: {\n      captureException: e => {\n        console.error('ERROR ' + e + ' ' + e.stack);\n      }\n    },\n    storage: {\n      files,\n      remove: function(fileId) {\n        console.log('REMOVE FILEID', fileId);\n      },\n      writeFile: function(file) {\n        console.log('WRITEFILE', file);\n      },\n      addFile: function(file) {\n        console.log('addfile' + JSON.stringify(file));\n        files.push(file);\n        emitter.emit('pushState', `/share/${file.id}`);\n      },\n      totalUploads: 0\n    },\n    transfer: null,\n    uploading: false,\n    settingPassword: false,\n    passwordSetError: null,\n    route: '/'\n  });\n}\n"
  },
  {
    "path": "android/user.js",
    "content": "/* global Android */\nimport User from '../app/user';\nimport { deriveFileListKey } from '../app/fxa';\n\nexport default class AndroidUser extends User {\n  constructor(storage, limits) {\n    super(storage, limits);\n  }\n\n  async login() {\n    Android.beginOAuthFlow();\n  }\n\n  startAuthFlow() {\n    return Promise.resolve();\n  }\n\n  async finishLogin(accountInfo) {\n    const jwks = JSON.parse(accountInfo.keys);\n    const ikm = jwks['https://identity.mozilla.com/apps/send'].k;\n    const profile = {\n      displayName: accountInfo.displayName,\n      email: accountInfo.email,\n      avatar: accountInfo.avatar,\n      access_token: accountInfo.accessToken\n    };\n    profile.fileListKey = await deriveFileListKey(ikm);\n    this.info = profile;\n  }\n}\n"
  },
  {
    "path": "app/.eslintrc.yml",
    "content": "env:\n  browser: true\n  node: true\n\nparserOptions:\n  sourceType: module\n\nrules:\n  node/no-unsupported-features: off\n"
  },
  {
    "path": "app/api.js",
    "content": "import { arrayToB64, b64ToArray, delay } from './utils';\nimport { ECE_RECORD_SIZE } from './ece';\n\nlet fileProtocolWssUrl = null;\ntry {\n  fileProtocolWssUrl = localStorage.getItem('wssURL');\n} catch (e) {\n  // NOOP\n}\nif (!fileProtocolWssUrl) {\n  fileProtocolWssUrl = 'wss://send.firefox.com/api/ws';\n}\n\nexport class ConnectionError extends Error {\n  constructor(cancelled, duration, size) {\n    super(cancelled ? '0' : 'connection closed');\n    this.cancelled = cancelled;\n    this.duration = duration;\n    this.size = size;\n  }\n}\n\nexport function setFileProtocolWssUrl(url) {\n  localStorage && localStorage.setItem('wssURL', url);\n  fileProtocolWssUrl = url;\n}\n\nexport function getFileProtocolWssUrl() {\n  return fileProtocolWssUrl;\n}\n\nlet apiUrlPrefix = '';\nexport function getApiUrl(path) {\n  return apiUrlPrefix + path;\n}\n\nexport function setApiUrlPrefix(prefix) {\n  apiUrlPrefix = prefix;\n}\n\nfunction post(obj, bearerToken) {\n  const h = {\n    'Content-Type': 'application/json'\n  };\n  if (bearerToken) {\n    h['Authentication'] = `Bearer ${bearerToken}`;\n  }\n  return {\n    method: 'POST',\n    headers: new Headers(h),\n    body: JSON.stringify(obj)\n  };\n}\n\nexport function parseNonce(header) {\n  header = header || '';\n  return header.split(' ')[1];\n}\n\nasync function fetchWithAuth(url, params, keychain) {\n  const result = {};\n  params = params || {};\n  const h = await keychain.authHeader();\n  params.headers = new Headers({\n    Authorization: h,\n    'Content-Type': 'application/json'\n  });\n  const response = await fetch(url, params);\n  result.response = response;\n  result.ok = response.ok;\n  const nonce = parseNonce(response.headers.get('WWW-Authenticate'));\n  result.shouldRetry = response.status === 401 && nonce !== keychain.nonce;\n  keychain.nonce = nonce;\n  return result;\n}\n\nasync function fetchWithAuthAndRetry(url, params, keychain) {\n  const result = await fetchWithAuth(url, params, keychain);\n  if (result.shouldRetry) {\n    return fetchWithAuth(url, params, keychain);\n  }\n  return result;\n}\n\nexport async function del(id, owner_token) {\n  const response = await fetch(\n    getApiUrl(`/api/delete/${id}`),\n    post({ owner_token })\n  );\n  return response.ok;\n}\n\nexport async function setParams(id, owner_token, bearerToken, params) {\n  const response = await fetch(\n    getApiUrl(`/api/params/${id}`),\n    post(\n      {\n        owner_token,\n        dlimit: params.dlimit\n      },\n      bearerToken\n    )\n  );\n  return response.ok;\n}\n\nexport async function fileInfo(id, owner_token) {\n  const response = await fetch(\n    getApiUrl(`/api/info/${id}`),\n    post({ owner_token })\n  );\n\n  if (response.ok) {\n    const obj = await response.json();\n    return obj;\n  }\n\n  throw new Error(response.status);\n}\n\nexport async function metadata(id, keychain) {\n  const result = await fetchWithAuthAndRetry(\n    getApiUrl(`/api/metadata/${id}`),\n    { method: 'GET' },\n    keychain\n  );\n  if (result.ok) {\n    const data = await result.response.json();\n    const meta = await keychain.decryptMetadata(b64ToArray(data.metadata));\n    return {\n      size: meta.size,\n      ttl: data.ttl,\n      name: meta.name,\n      type: meta.type,\n      manifest: meta.manifest,\n      flagged: data.flagged\n    };\n  }\n  throw new Error(result.response.status);\n}\n\nexport async function setPassword(id, owner_token, keychain) {\n  const auth = await keychain.authKeyB64();\n  const response = await fetch(\n    getApiUrl(`/api/password/${id}`),\n    post({ owner_token, auth })\n  );\n  return response.ok;\n}\n\nfunction asyncInitWebSocket(server) {\n  return new Promise((resolve, reject) => {\n    try {\n      const ws = new WebSocket(server);\n      ws.addEventListener('open', () => resolve(ws), { once: true });\n    } catch (e) {\n      reject(new ConnectionError(false));\n    }\n  });\n}\n\nfunction listenForResponse(ws, canceller) {\n  return new Promise((resolve, reject) => {\n    function handleClose(event) {\n      // a 'close' event before a 'message' event means the request failed\n      ws.removeEventListener('message', handleMessage);\n      reject(new ConnectionError(canceller.cancelled));\n    }\n    function handleMessage(msg) {\n      ws.removeEventListener('close', handleClose);\n      try {\n        const response = JSON.parse(msg.data);\n        if (response.error) {\n          throw new Error(response.error);\n        } else {\n          resolve(response);\n        }\n      } catch (e) {\n        reject(e);\n      }\n    }\n    ws.addEventListener('message', handleMessage, { once: true });\n    ws.addEventListener('close', handleClose, { once: true });\n  });\n}\n\nasync function upload(\n  stream,\n  metadata,\n  verifierB64,\n  timeLimit,\n  dlimit,\n  bearerToken,\n  onprogress,\n  canceller\n) {\n  let size = 0;\n  const start = Date.now();\n  const host = window.location.hostname;\n  const port = window.location.port;\n  const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';\n  const endpoint =\n    window.location.protocol === 'file:'\n      ? fileProtocolWssUrl\n      : `${protocol}//${host}${port ? ':' : ''}${port}/api/ws`;\n\n  const ws = await asyncInitWebSocket(endpoint);\n\n  try {\n    const metadataHeader = arrayToB64(new Uint8Array(metadata));\n    const fileMeta = {\n      fileMetadata: metadataHeader,\n      authorization: `send-v1 ${verifierB64}`,\n      bearer: bearerToken,\n      timeLimit,\n      dlimit\n    };\n    const uploadInfoResponse = listenForResponse(ws, canceller);\n    ws.send(JSON.stringify(fileMeta));\n    const uploadInfo = await uploadInfoResponse;\n\n    const completedResponse = listenForResponse(ws, canceller);\n\n    const reader = stream.getReader();\n    let state = await reader.read();\n    while (!state.done) {\n      if (canceller.cancelled) {\n        ws.close();\n      }\n      if (ws.readyState !== WebSocket.OPEN) {\n        break;\n      }\n      const buf = state.value;\n      ws.send(buf);\n      onprogress(size);\n      size += buf.length;\n      state = await reader.read();\n      while (\n        ws.bufferedAmount > ECE_RECORD_SIZE * 2 &&\n        ws.readyState === WebSocket.OPEN &&\n        !canceller.cancelled\n      ) {\n        await delay();\n      }\n    }\n    if (ws.readyState === WebSocket.OPEN) {\n      ws.send(new Uint8Array([0])); //EOF\n    }\n\n    await completedResponse;\n    uploadInfo.duration = Date.now() - start;\n    return uploadInfo;\n  } catch (e) {\n    e.size = size;\n    e.duration = Date.now() - start;\n    throw e;\n  } finally {\n    if (![WebSocket.CLOSED, WebSocket.CLOSING].includes(ws.readyState)) {\n      ws.close();\n    }\n  }\n}\n\nexport function uploadWs(\n  encrypted,\n  metadata,\n  verifierB64,\n  timeLimit,\n  dlimit,\n  bearerToken,\n  onprogress\n) {\n  const canceller = { cancelled: false };\n\n  return {\n    cancel: function() {\n      canceller.cancelled = true;\n    },\n\n    result: upload(\n      encrypted,\n      metadata,\n      verifierB64,\n      timeLimit,\n      dlimit,\n      bearerToken,\n      onprogress,\n      canceller\n    )\n  };\n}\n\n////////////////////////\n\nasync function _downloadStream(id, dlToken, signal) {\n  const response = await fetch(getApiUrl(`/api/download/${id}`), {\n    signal: signal,\n    method: 'GET',\n    headers: { Authorization: `Bearer ${dlToken}` }\n  });\n\n  if (response.status !== 200) {\n    throw new Error(response.status);\n  }\n\n  return response.body;\n}\n\nasync function tryDownloadStream(id, dlToken, signal, tries = 2) {\n  try {\n    const result = await _downloadStream(id, dlToken, signal);\n    return result;\n  } catch (e) {\n    if (e.message === '401' && --tries > 0) {\n      return tryDownloadStream(id, dlToken, signal, tries);\n    }\n    if (e.name === 'AbortError') {\n      throw new Error('0');\n    }\n    throw e;\n  }\n}\n\nexport function downloadStream(id, dlToken) {\n  const controller = new AbortController();\n  function cancel() {\n    controller.abort();\n  }\n  return {\n    cancel,\n    result: tryDownloadStream(id, dlToken, controller.signal)\n  };\n}\n\n//////////////////\n\nasync function download(id, dlToken, onprogress, canceller) {\n  const xhr = new XMLHttpRequest();\n  canceller.oncancel = function() {\n    xhr.abort();\n  };\n  return new Promise(function(resolve, reject) {\n    xhr.addEventListener('loadend', function() {\n      canceller.oncancel = function() {};\n      if (xhr.status !== 200) {\n        return reject(new Error(xhr.status));\n      }\n\n      const blob = new Blob([xhr.response]);\n      resolve(blob);\n    });\n\n    xhr.addEventListener('progress', function(event) {\n      if (event.target.status === 200) {\n        onprogress(event.loaded);\n      }\n    });\n    xhr.open('get', getApiUrl(`/api/download/blob/${id}`));\n    xhr.setRequestHeader('Authorization', `Bearer ${dlToken}`);\n    xhr.responseType = 'blob';\n    xhr.send();\n    onprogress(0);\n  });\n}\n\nasync function tryDownload(id, dlToken, onprogress, canceller, tries = 2) {\n  try {\n    const result = await download(id, dlToken, onprogress, canceller);\n    return result;\n  } catch (e) {\n    if (e.message === '401' && --tries > 0) {\n      return tryDownload(id, dlToken, onprogress, canceller, tries);\n    }\n    throw e;\n  }\n}\n\nexport function downloadFile(id, dlToken, onprogress) {\n  const canceller = {\n    oncancel: function() {} // download() sets this\n  };\n  function cancel() {\n    canceller.oncancel();\n  }\n  return {\n    cancel,\n    result: tryDownload(id, dlToken, onprogress, canceller)\n  };\n}\n\nexport async function getFileList(bearerToken, kid) {\n  const headers = new Headers({ Authorization: `Bearer ${bearerToken}` });\n  const response = await fetch(getApiUrl(`/api/filelist/${kid}`), { headers });\n  if (response.ok) {\n    const encrypted = await response.blob();\n    return encrypted;\n  }\n  throw new Error(response.status);\n}\n\nexport async function setFileList(bearerToken, kid, data) {\n  const headers = new Headers({ Authorization: `Bearer ${bearerToken}` });\n  const response = await fetch(getApiUrl(`/api/filelist/${kid}`), {\n    headers,\n    method: 'POST',\n    body: data\n  });\n  return response.ok;\n}\n\nexport function sendMetrics(blob) {\n  if (!navigator.sendBeacon) {\n    return;\n  }\n  try {\n    navigator.sendBeacon(getApiUrl('/api/metrics'), blob);\n  } catch (e) {\n    console.error(e);\n  }\n}\n\nexport async function getConstants() {\n  const response = await fetch(getApiUrl('/config'));\n\n  if (response.ok) {\n    const obj = await response.json();\n    return obj;\n  }\n\n  throw new Error(response.status);\n}\n\nexport async function reportLink(id, keychain, reason) {\n  const result = await fetchWithAuthAndRetry(\n    getApiUrl(`/api/report/${id}`),\n    {\n      method: 'POST',\n      body: JSON.stringify({ reason })\n    },\n    keychain\n  );\n\n  if (result.ok) {\n    return;\n  }\n\n  throw new Error(result.response.status);\n}\n\nexport async function getDownloadToken(id, keychain) {\n  const result = await fetchWithAuthAndRetry(\n    getApiUrl(`/api/download/token/${id}`),\n    {\n      method: 'GET'\n    },\n    keychain\n  );\n\n  if (result.ok) {\n    return (await result.response.json()).token;\n  }\n  throw new Error(result.response.status);\n}\n\nexport async function downloadDone(id, dlToken) {\n  const headers = new Headers({ Authorization: `Bearer ${dlToken}` });\n  const response = await fetch(getApiUrl(`/api/download/done/${id}`), {\n    headers,\n    method: 'POST'\n  });\n  return response.ok;\n}\n"
  },
  {
    "path": "app/archive.js",
    "content": "import { blobStream, concatStream } from './streams';\n\nfunction isDupe(newFile, array) {\n  for (const file of array) {\n    if (\n      newFile.name === file.name &&\n      newFile.size === file.size &&\n      newFile.lastModified === file.lastModified\n    ) {\n      return true;\n    }\n  }\n  return false;\n}\n\nexport default class Archive {\n  constructor(files = [], defaultTimeLimit = 86400) {\n    this.files = Array.from(files);\n    this.defaultTimeLimit = defaultTimeLimit;\n    this.timeLimit = defaultTimeLimit;\n    this.dlimit = 1;\n    this.password = null;\n  }\n\n  get name() {\n    return this.files.length > 1 ? 'Send-Archive.zip' : this.files[0].name;\n  }\n\n  get type() {\n    return this.files.length > 1 ? 'send-archive' : this.files[0].type;\n  }\n\n  get size() {\n    return this.files.reduce((total, file) => total + file.size, 0);\n  }\n\n  get numFiles() {\n    return this.files.length;\n  }\n\n  get manifest() {\n    return {\n      files: this.files.map(file => ({\n        name: file.name,\n        size: file.size,\n        type: file.type\n      }))\n    };\n  }\n\n  get stream() {\n    return concatStream(this.files.map(file => blobStream(file)));\n  }\n\n  addFiles(files, maxSize, maxFiles) {\n    if (this.files.length + files.length > maxFiles) {\n      throw new Error('tooManyFiles');\n    }\n    const newFiles = files.filter(\n      file => file.size > 0 && !isDupe(file, this.files)\n    );\n    const newSize = newFiles.reduce((total, file) => total + file.size, 0);\n    if (this.size + newSize > maxSize) {\n      throw new Error('fileTooBig');\n    }\n    this.files = this.files.concat(newFiles);\n    return true;\n  }\n\n  remove(file) {\n    const index = this.files.indexOf(file);\n    if (index > -1) {\n      this.files.splice(index, 1);\n    }\n  }\n\n  clear() {\n    this.files = [];\n    this.dlimit = 1;\n    this.timeLimit = this.defaultTimeLimit;\n    this.password = null;\n  }\n}\n"
  },
  {
    "path": "app/capabilities.js",
    "content": "/* global AUTH_CONFIG */\nimport { browserName, locale } from './utils';\n\nasync function checkCrypto() {\n  try {\n    const key = await crypto.subtle.generateKey(\n      {\n        name: 'AES-GCM',\n        length: 128\n      },\n      true,\n      ['encrypt', 'decrypt']\n    );\n    await crypto.subtle.exportKey('raw', key);\n    await crypto.subtle.encrypt(\n      {\n        name: 'AES-GCM',\n        iv: crypto.getRandomValues(new Uint8Array(12)),\n        tagLength: 128\n      },\n      key,\n      new ArrayBuffer(8)\n    );\n    await crypto.subtle.importKey(\n      'raw',\n      crypto.getRandomValues(new Uint8Array(16)),\n      'PBKDF2',\n      false,\n      ['deriveKey']\n    );\n    await crypto.subtle.importKey(\n      'raw',\n      crypto.getRandomValues(new Uint8Array(16)),\n      'HKDF',\n      false,\n      ['deriveKey']\n    );\n    await crypto.subtle.generateKey(\n      {\n        name: 'ECDH',\n        namedCurve: 'P-256'\n      },\n      true,\n      ['deriveBits']\n    );\n    return true;\n  } catch (err) {\n    try {\n      window.asmCrypto = await import('asmcrypto.js');\n      await import('@dannycoates/webcrypto-liner/build/shim');\n      return true;\n    } catch (e) {\n      return false;\n    }\n  }\n}\n\nfunction checkStreams() {\n  try {\n    new ReadableStream({\n      pull() {}\n    });\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n\nasync function polyfillStreams() {\n  try {\n    await import('@mattiasbuelens/web-streams-polyfill');\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n\nexport default async function getCapabilities() {\n  const browser = browserName();\n  const isMobile = /mobi|android/i.test(navigator.userAgent);\n  const serviceWorker = 'serviceWorker' in navigator && browser !== 'edge';\n  let crypto = await checkCrypto();\n  const nativeStreams = checkStreams();\n  let polyStreams = false;\n  if (!nativeStreams) {\n    polyStreams = await polyfillStreams();\n  }\n  let account = typeof AUTH_CONFIG !== 'undefined';\n  try {\n    account = account && !!localStorage;\n  } catch (e) {\n    account = false;\n  }\n  const share =\n    isMobile &&\n    typeof navigator.share === 'function' &&\n    locale().startsWith('en'); // en until strings merge\n\n  const standalone =\n    window.matchMedia('(display-mode: standalone)').matches ||\n    navigator.standalone;\n\n  const mobileFirefox = browser === 'firefox' && isMobile;\n\n  return {\n    account,\n    crypto,\n    serviceWorker,\n    streamUpload: nativeStreams || polyStreams,\n    streamDownload:\n      nativeStreams && serviceWorker && browser !== 'safari' && !mobileFirefox,\n    multifile: nativeStreams || polyStreams,\n    share,\n    standalone\n  };\n}\n"
  },
  {
    "path": "app/controller.js",
    "content": "import FileSender from './fileSender';\nimport FileReceiver from './fileReceiver';\nimport { copyToClipboard, delay, openLinksInNewTab, percent } from './utils';\nimport * as metrics from './metrics';\nimport { bytes, locale } from './utils';\nimport okDialog from './ui/okDialog';\nimport copyDialog from './ui/copyDialog';\nimport shareDialog from './ui/shareDialog';\n\nexport default function(state, emitter) {\n  let lastRender = 0;\n  let updateTitle = false;\n\n  function render() {\n    emitter.emit('render');\n  }\n\n  async function checkFiles() {\n    const changes = await state.user.syncFileList();\n    const rerender = changes.incoming || changes.downloadCount;\n    if (rerender) {\n      render();\n    }\n  }\n\n  function updateProgress() {\n    if (updateTitle) {\n      emitter.emit('DOMTitleChange', percent(state.transfer.progressRatio));\n    }\n    render();\n  }\n\n  emitter.on('DOMContentLoaded', () => {\n    document.addEventListener('blur', () => (updateTitle = true));\n    document.addEventListener('focus', () => {\n      updateTitle = false;\n      emitter.emit('DOMTitleChange', 'Send');\n    });\n    checkFiles();\n  });\n\n  emitter.on('render', () => {\n    lastRender = Date.now();\n  });\n\n  emitter.on('login', email => {\n    state.user.login(email);\n  });\n\n  emitter.on('logout', async () => {\n    await state.user.logout();\n    metrics.loggedOut({ trigger: 'button' });\n    emitter.emit('pushState', '/');\n  });\n\n  emitter.on('removeUpload', file => {\n    state.archive.remove(file);\n    if (state.archive.numFiles === 0) {\n      state.archive.clear();\n    }\n    render();\n  });\n\n  emitter.on('delete', async ownedFile => {\n    try {\n      metrics.deletedUpload({\n        size: ownedFile.size,\n        time: ownedFile.time,\n        speed: ownedFile.speed,\n        type: ownedFile.type,\n        ttl: ownedFile.expiresAt - Date.now(),\n        location\n      });\n      state.storage.remove(ownedFile.id);\n      await ownedFile.del();\n    } catch (e) {\n      state.sentry.captureException(e);\n    }\n    render();\n  });\n\n  emitter.on('cancel', () => {\n    state.transfer.cancel();\n  });\n\n  emitter.on('addFiles', async ({ files }) => {\n    if (files.length < 1) {\n      return;\n    }\n    const maxSize = state.user.maxSize;\n    try {\n      state.archive.addFiles(\n        files,\n        maxSize,\n        state.LIMITS.MAX_FILES_PER_ARCHIVE\n      );\n    } catch (e) {\n      if (e.message === 'fileTooBig' && maxSize < state.LIMITS.MAX_FILE_SIZE) {\n        return emitter.emit('signup-cta', 'size');\n      }\n      state.modal = okDialog(\n        state.translate(e.message, {\n          size: bytes(maxSize),\n          count: state.LIMITS.MAX_FILES_PER_ARCHIVE\n        })\n      );\n    }\n    render();\n  });\n\n  emitter.on('authenticate', async (code, oauthState) => {\n    try {\n      await state.user.finishLogin(code, oauthState);\n      await state.user.syncFileList();\n      emitter.emit('replaceState', '/');\n    } catch (e) {\n      emitter.emit('replaceState', '/error');\n      setTimeout(render);\n    }\n  });\n\n  emitter.on('upload', async () => {\n    if (state.storage.files.length >= state.LIMITS.MAX_ARCHIVES_PER_USER) {\n      state.modal = okDialog(\n        state.translate('tooManyArchives', {\n          count: state.LIMITS.MAX_ARCHIVES_PER_USER\n        })\n      );\n      return render();\n    }\n    const archive = state.archive;\n    const sender = new FileSender();\n\n    sender.on('progress', updateProgress);\n    sender.on('encrypting', render);\n    sender.on('complete', render);\n    state.transfer = sender;\n    state.uploading = true;\n    render();\n\n    const links = openLinksInNewTab();\n    await delay(200);\n    const start = Date.now();\n    try {\n      const ownedFile = await sender.upload(archive, state.user.bearerToken);\n      state.storage.totalUploads += 1;\n      const duration = Date.now() - start;\n      metrics.completedUpload(archive, duration);\n\n      state.storage.addFile(ownedFile);\n      // TODO integrate password into /upload request\n      if (archive.password) {\n        emitter.emit('password', {\n          password: archive.password,\n          file: ownedFile\n        });\n      }\n      state.modal = state.capabilities.share\n        ? shareDialog(ownedFile.name, ownedFile.url)\n        : copyDialog(ownedFile.name, ownedFile.url);\n    } catch (err) {\n      if (err.message === '0') {\n        //cancelled. do nothing\n        metrics.cancelledUpload(archive, err.duration);\n        render();\n      } else if (err.message === '401') {\n        const refreshed = await state.user.refresh();\n        if (refreshed) {\n          return emitter.emit('upload');\n        }\n        emitter.emit('pushState', '/error');\n      } else {\n        // eslint-disable-next-line no-console\n        console.error(err);\n        state.sentry.withScope(scope => {\n          scope.setExtra('duration', err.duration);\n          scope.setExtra('size', err.size);\n          state.sentry.captureException(err);\n        });\n        metrics.stoppedUpload(archive, err.duration);\n        emitter.emit('pushState', '/error');\n      }\n    } finally {\n      openLinksInNewTab(links, false);\n      archive.clear();\n      state.uploading = false;\n      state.transfer = null;\n      await state.user.syncFileList();\n      render();\n    }\n  });\n\n  emitter.on('password', async ({ password, file }) => {\n    try {\n      state.settingPassword = true;\n      render();\n      await file.setPassword(password);\n      state.storage.writeFile(file);\n      await delay(1000);\n    } catch (err) {\n      // eslint-disable-next-line no-console\n      console.error(err);\n      state.passwordSetError = err;\n    } finally {\n      state.settingPassword = false;\n    }\n    render();\n  });\n\n  emitter.on('getMetadata', async () => {\n    const file = state.fileInfo;\n\n    const receiver = new FileReceiver(file);\n    try {\n      await receiver.getMetadata();\n      state.transfer = receiver;\n    } catch (e) {\n      if (e.message === '401' || e.message === '404') {\n        file.password = null;\n        file.dead = e.message === '404';\n      } else {\n        console.error(e);\n        return emitter.emit('pushState', '/error');\n      }\n    }\n\n    render();\n  });\n\n  emitter.on('download', async file => {\n    state.transfer.on('progress', updateProgress);\n    state.transfer.on('decrypting', render);\n    state.transfer.on('complete', render);\n    const links = openLinksInNewTab();\n    const size = file.size;\n    const start = Date.now();\n    try {\n      const dl = state.transfer.download({\n        stream: state.capabilities.streamDownload,\n        storage: state.storage\n      });\n      render();\n      await dl;\n      state.storage.totalDownloads += 1;\n      const duration = Date.now() - start;\n      metrics.completedDownload({\n        size,\n        duration,\n        password_protected: file.requiresPassword\n      });\n    } catch (err) {\n      if (err.message === '0') {\n        // download cancelled\n        state.transfer.reset();\n        render();\n      } else {\n        // eslint-disable-next-line no-console\n        state.transfer = null;\n        const location = ['404', '403'].includes(err.message)\n          ? '/404'\n          : '/error';\n        if (location === '/error') {\n          state.sentry.withScope(scope => {\n            scope.setExtra('duration', err.duration);\n            scope.setExtra('size', err.size);\n            scope.setExtra('progress', err.progress);\n            state.sentry.captureException(err);\n          });\n          const duration = Date.now() - start;\n          metrics.stoppedDownload({\n            size,\n            duration,\n            password_protected: file.requiresPassword\n          });\n        }\n        emitter.emit('pushState', location);\n      }\n    } finally {\n      openLinksInNewTab(links, false);\n    }\n  });\n\n  emitter.on('copy', ({ url }) => {\n    copyToClipboard(url);\n    // metrics.copiedLink({ location });\n  });\n\n  emitter.on('closeModal', () => {\n    if (\n      state.PREFS.surveyUrl &&\n      ['copy', 'share'].includes(state.modal.type) &&\n      locale().startsWith('en') &&\n      (state.storage.totalUploads > 1 || state.storage.totalDownloads > 0) &&\n      !state.user.surveyed\n    ) {\n      state.user.surveyed = true;\n      // state.modal = surveyDialog();\n    } else {\n      state.modal = null;\n    }\n    render();\n  });\n\n  emitter.on('report', async ({ reason }) => {\n    try {\n      const receiver = state.transfer || new FileReceiver(state.fileInfo);\n      await receiver.reportLink(reason);\n      render();\n    } catch (err) {\n      console.error(err);\n      if (err.message === '404') {\n        state.fileInfo = { reported: true };\n        return render();\n      }\n      emitter.emit('pushState', '/error');\n    }\n  });\n\n  setInterval(() => {\n    // poll for updates of the upload list\n    if (!state.modal && state.route === '/') {\n      checkFiles();\n    }\n  }, 2 * 60 * 1000);\n\n  setInterval(() => {\n    // poll for rerendering the file list countdown timers\n    if (\n      !state.modal &&\n      state.route === '/' &&\n      state.storage.files.length > 0 &&\n      Date.now() - lastRender > 30000\n    ) {\n      render();\n    }\n  }, 60000);\n}\n"
  },
  {
    "path": "app/crc32.js",
    "content": "const LOOKUP = Int32Array.from([\n  0x00000000,\n  0x77073096,\n  0xee0e612c,\n  0x990951ba,\n  0x076dc419,\n  0x706af48f,\n  0xe963a535,\n  0x9e6495a3,\n  0x0edb8832,\n  0x79dcb8a4,\n  0xe0d5e91e,\n  0x97d2d988,\n  0x09b64c2b,\n  0x7eb17cbd,\n  0xe7b82d07,\n  0x90bf1d91,\n  0x1db71064,\n  0x6ab020f2,\n  0xf3b97148,\n  0x84be41de,\n  0x1adad47d,\n  0x6ddde4eb,\n  0xf4d4b551,\n  0x83d385c7,\n  0x136c9856,\n  0x646ba8c0,\n  0xfd62f97a,\n  0x8a65c9ec,\n  0x14015c4f,\n  0x63066cd9,\n  0xfa0f3d63,\n  0x8d080df5,\n  0x3b6e20c8,\n  0x4c69105e,\n  0xd56041e4,\n  0xa2677172,\n  0x3c03e4d1,\n  0x4b04d447,\n  0xd20d85fd,\n  0xa50ab56b,\n  0x35b5a8fa,\n  0x42b2986c,\n  0xdbbbc9d6,\n  0xacbcf940,\n  0x32d86ce3,\n  0x45df5c75,\n  0xdcd60dcf,\n  0xabd13d59,\n  0x26d930ac,\n  0x51de003a,\n  0xc8d75180,\n  0xbfd06116,\n  0x21b4f4b5,\n  0x56b3c423,\n  0xcfba9599,\n  0xb8bda50f,\n  0x2802b89e,\n  0x5f058808,\n  0xc60cd9b2,\n  0xb10be924,\n  0x2f6f7c87,\n  0x58684c11,\n  0xc1611dab,\n  0xb6662d3d,\n  0x76dc4190,\n  0x01db7106,\n  0x98d220bc,\n  0xefd5102a,\n  0x71b18589,\n  0x06b6b51f,\n  0x9fbfe4a5,\n  0xe8b8d433,\n  0x7807c9a2,\n  0x0f00f934,\n  0x9609a88e,\n  0xe10e9818,\n  0x7f6a0dbb,\n  0x086d3d2d,\n  0x91646c97,\n  0xe6635c01,\n  0x6b6b51f4,\n  0x1c6c6162,\n  0x856530d8,\n  0xf262004e,\n  0x6c0695ed,\n  0x1b01a57b,\n  0x8208f4c1,\n  0xf50fc457,\n  0x65b0d9c6,\n  0x12b7e950,\n  0x8bbeb8ea,\n  0xfcb9887c,\n  0x62dd1ddf,\n  0x15da2d49,\n  0x8cd37cf3,\n  0xfbd44c65,\n  0x4db26158,\n  0x3ab551ce,\n  0xa3bc0074,\n  0xd4bb30e2,\n  0x4adfa541,\n  0x3dd895d7,\n  0xa4d1c46d,\n  0xd3d6f4fb,\n  0x4369e96a,\n  0x346ed9fc,\n  0xad678846,\n  0xda60b8d0,\n  0x44042d73,\n  0x33031de5,\n  0xaa0a4c5f,\n  0xdd0d7cc9,\n  0x5005713c,\n  0x270241aa,\n  0xbe0b1010,\n  0xc90c2086,\n  0x5768b525,\n  0x206f85b3,\n  0xb966d409,\n  0xce61e49f,\n  0x5edef90e,\n  0x29d9c998,\n  0xb0d09822,\n  0xc7d7a8b4,\n  0x59b33d17,\n  0x2eb40d81,\n  0xb7bd5c3b,\n  0xc0ba6cad,\n  0xedb88320,\n  0x9abfb3b6,\n  0x03b6e20c,\n  0x74b1d29a,\n  0xead54739,\n  0x9dd277af,\n  0x04db2615,\n  0x73dc1683,\n  0xe3630b12,\n  0x94643b84,\n  0x0d6d6a3e,\n  0x7a6a5aa8,\n  0xe40ecf0b,\n  0x9309ff9d,\n  0x0a00ae27,\n  0x7d079eb1,\n  0xf00f9344,\n  0x8708a3d2,\n  0x1e01f268,\n  0x6906c2fe,\n  0xf762575d,\n  0x806567cb,\n  0x196c3671,\n  0x6e6b06e7,\n  0xfed41b76,\n  0x89d32be0,\n  0x10da7a5a,\n  0x67dd4acc,\n  0xf9b9df6f,\n  0x8ebeeff9,\n  0x17b7be43,\n  0x60b08ed5,\n  0xd6d6a3e8,\n  0xa1d1937e,\n  0x38d8c2c4,\n  0x4fdff252,\n  0xd1bb67f1,\n  0xa6bc5767,\n  0x3fb506dd,\n  0x48b2364b,\n  0xd80d2bda,\n  0xaf0a1b4c,\n  0x36034af6,\n  0x41047a60,\n  0xdf60efc3,\n  0xa867df55,\n  0x316e8eef,\n  0x4669be79,\n  0xcb61b38c,\n  0xbc66831a,\n  0x256fd2a0,\n  0x5268e236,\n  0xcc0c7795,\n  0xbb0b4703,\n  0x220216b9,\n  0x5505262f,\n  0xc5ba3bbe,\n  0xb2bd0b28,\n  0x2bb45a92,\n  0x5cb36a04,\n  0xc2d7ffa7,\n  0xb5d0cf31,\n  0x2cd99e8b,\n  0x5bdeae1d,\n  0x9b64c2b0,\n  0xec63f226,\n  0x756aa39c,\n  0x026d930a,\n  0x9c0906a9,\n  0xeb0e363f,\n  0x72076785,\n  0x05005713,\n  0x95bf4a82,\n  0xe2b87a14,\n  0x7bb12bae,\n  0x0cb61b38,\n  0x92d28e9b,\n  0xe5d5be0d,\n  0x7cdcefb7,\n  0x0bdbdf21,\n  0x86d3d2d4,\n  0xf1d4e242,\n  0x68ddb3f8,\n  0x1fda836e,\n  0x81be16cd,\n  0xf6b9265b,\n  0x6fb077e1,\n  0x18b74777,\n  0x88085ae6,\n  0xff0f6a70,\n  0x66063bca,\n  0x11010b5c,\n  0x8f659eff,\n  0xf862ae69,\n  0x616bffd3,\n  0x166ccf45,\n  0xa00ae278,\n  0xd70dd2ee,\n  0x4e048354,\n  0x3903b3c2,\n  0xa7672661,\n  0xd06016f7,\n  0x4969474d,\n  0x3e6e77db,\n  0xaed16a4a,\n  0xd9d65adc,\n  0x40df0b66,\n  0x37d83bf0,\n  0xa9bcae53,\n  0xdebb9ec5,\n  0x47b2cf7f,\n  0x30b5ffe9,\n  0xbdbdf21c,\n  0xcabac28a,\n  0x53b39330,\n  0x24b4a3a6,\n  0xbad03605,\n  0xcdd70693,\n  0x54de5729,\n  0x23d967bf,\n  0xb3667a2e,\n  0xc4614ab8,\n  0x5d681b02,\n  0x2a6f2b94,\n  0xb40bbe37,\n  0xc30c8ea1,\n  0x5a05df1b,\n  0x2d02ef8d\n]);\n\nmodule.exports = function crc32(uint8Array, previous) {\n  let crc = previous === 0 ? 0 : ~~previous ^ -1;\n  for (let i = 0; i < uint8Array.byteLength; i++) {\n    crc = LOOKUP[(crc ^ uint8Array[i]) & 0xff] ^ (crc >>> 8);\n  }\n  return (crc ^ -1) >>> 0;\n};\n"
  },
  {
    "path": "app/dragManager.js",
    "content": "export default function(state, emitter) {\n  emitter.on('DOMContentLoaded', () => {\n    document.body.addEventListener('dragover', event => {\n      if (state.route === '/') {\n        event.preventDefault();\n      }\n    });\n    document.body.addEventListener('drop', event => {\n      if (\n        state.route === '/' &&\n        !state.uploading &&\n        event.dataTransfer &&\n        event.dataTransfer.files\n      ) {\n        event.preventDefault();\n        emitter.emit('addFiles', {\n          files: Array.from(event.dataTransfer.files)\n        });\n      }\n    });\n  });\n}\n"
  },
  {
    "path": "app/ece.js",
    "content": "import { transformStream } from './streams';\nimport { concat } from './utils';\n\nconst NONCE_LENGTH = 12;\nconst TAG_LENGTH = 16;\nconst KEY_LENGTH = 16;\nconst MODE_ENCRYPT = 'encrypt';\nconst MODE_DECRYPT = 'decrypt';\nexport const ECE_RECORD_SIZE = 1024 * 64;\n\nconst encoder = new TextEncoder();\n\nfunction generateSalt(len) {\n  const randSalt = new Uint8Array(len);\n  crypto.getRandomValues(randSalt);\n  return randSalt.buffer;\n}\n\nclass ECETransformer {\n  constructor(mode, ikm, rs, salt) {\n    this.mode = mode;\n    this.prevChunk;\n    this.seq = 0;\n    this.firstchunk = true;\n    this.rs = rs;\n    this.ikm = ikm.buffer;\n    this.salt = salt;\n  }\n\n  async generateKey() {\n    const inputKey = await crypto.subtle.importKey(\n      'raw',\n      this.ikm,\n      'HKDF',\n      false,\n      ['deriveKey']\n    );\n\n    return crypto.subtle.deriveKey(\n      {\n        name: 'HKDF',\n        salt: this.salt,\n        info: encoder.encode('Content-Encoding: aes128gcm\\0'),\n        hash: 'SHA-256'\n      },\n      inputKey,\n      {\n        name: 'AES-GCM',\n        length: 128\n      },\n      true, // Edge polyfill requires key to be extractable to encrypt :/\n      ['encrypt', 'decrypt']\n    );\n  }\n\n  async generateNonceBase() {\n    const inputKey = await crypto.subtle.importKey(\n      'raw',\n      this.ikm,\n      'HKDF',\n      false,\n      ['deriveKey']\n    );\n\n    const base = await crypto.subtle.exportKey(\n      'raw',\n      await crypto.subtle.deriveKey(\n        {\n          name: 'HKDF',\n          salt: this.salt,\n          info: encoder.encode('Content-Encoding: nonce\\0'),\n          hash: 'SHA-256'\n        },\n        inputKey,\n        {\n          name: 'AES-GCM',\n          length: 128\n        },\n        true,\n        ['encrypt', 'decrypt']\n      )\n    );\n\n    return base.slice(0, NONCE_LENGTH);\n  }\n\n  generateNonce(seq) {\n    if (seq > 0xffffffff) {\n      throw new Error('record sequence number exceeds limit');\n    }\n    const nonce = new DataView(this.nonceBase.slice());\n    const m = nonce.getUint32(nonce.byteLength - 4);\n    const xor = (m ^ seq) >>> 0; //forces unsigned int xor\n    nonce.setUint32(nonce.byteLength - 4, xor);\n    return new Uint8Array(nonce.buffer);\n  }\n\n  pad(data, isLast) {\n    const len = data.length;\n    if (len + TAG_LENGTH >= this.rs) {\n      throw new Error('data too large for record size');\n    }\n\n    if (isLast) {\n      return concat(data, Uint8Array.of(2));\n    } else {\n      const padding = new Uint8Array(this.rs - len - TAG_LENGTH);\n      padding[0] = 1;\n      return concat(data, padding);\n    }\n  }\n\n  unpad(data, isLast) {\n    for (let i = data.length - 1; i >= 0; i--) {\n      if (data[i]) {\n        if (isLast) {\n          if (data[i] !== 2) {\n            throw new Error('delimiter of final record is not 2');\n          }\n        } else {\n          if (data[i] !== 1) {\n            throw new Error('delimiter of not final record is not 1');\n          }\n        }\n        return data.slice(0, i);\n      }\n    }\n    throw new Error('no delimiter found');\n  }\n\n  createHeader() {\n    const nums = new DataView(new ArrayBuffer(5));\n    nums.setUint32(0, this.rs);\n    return concat(new Uint8Array(this.salt), new Uint8Array(nums.buffer));\n  }\n\n  readHeader(buffer) {\n    if (buffer.length < 21) {\n      throw new Error('chunk too small for reading header');\n    }\n    const header = {};\n    const dv = new DataView(buffer.buffer);\n    header.salt = buffer.slice(0, KEY_LENGTH);\n    header.rs = dv.getUint32(KEY_LENGTH);\n    const idlen = dv.getUint8(KEY_LENGTH + 4);\n    header.length = idlen + KEY_LENGTH + 5;\n    return header;\n  }\n\n  async encryptRecord(buffer, seq, isLast) {\n    const nonce = this.generateNonce(seq);\n    const encrypted = await crypto.subtle.encrypt(\n      { name: 'AES-GCM', iv: nonce },\n      this.key,\n      this.pad(buffer, isLast)\n    );\n    return new Uint8Array(encrypted);\n  }\n\n  async decryptRecord(buffer, seq, isLast) {\n    const nonce = this.generateNonce(seq);\n    const data = await crypto.subtle.decrypt(\n      {\n        name: 'AES-GCM',\n        iv: nonce,\n        tagLength: 128\n      },\n      this.key,\n      buffer\n    );\n\n    return this.unpad(new Uint8Array(data), isLast);\n  }\n\n  async start(controller) {\n    if (this.mode === MODE_ENCRYPT) {\n      this.key = await this.generateKey();\n      this.nonceBase = await this.generateNonceBase();\n      controller.enqueue(this.createHeader());\n    } else if (this.mode !== MODE_DECRYPT) {\n      throw new Error('mode must be either encrypt or decrypt');\n    }\n  }\n\n  async transformPrevChunk(isLast, controller) {\n    if (this.mode === MODE_ENCRYPT) {\n      controller.enqueue(\n        await this.encryptRecord(this.prevChunk, this.seq, isLast)\n      );\n      this.seq++;\n    } else {\n      if (this.seq === 0) {\n        //the first chunk during decryption contains only the header\n        const header = this.readHeader(this.prevChunk);\n        this.salt = header.salt;\n        this.rs = header.rs;\n        this.key = await this.generateKey();\n        this.nonceBase = await this.generateNonceBase();\n      } else {\n        controller.enqueue(\n          await this.decryptRecord(this.prevChunk, this.seq - 1, isLast)\n        );\n      }\n      this.seq++;\n    }\n  }\n\n  async transform(chunk, controller) {\n    if (!this.firstchunk) {\n      await this.transformPrevChunk(false, controller);\n    }\n    this.firstchunk = false;\n    this.prevChunk = new Uint8Array(chunk.buffer);\n  }\n\n  async flush(controller) {\n    //console.log('ece stream ends')\n    if (this.prevChunk) {\n      await this.transformPrevChunk(true, controller);\n    }\n  }\n}\n\nclass StreamSlicer {\n  constructor(rs, mode) {\n    this.mode = mode;\n    this.rs = rs;\n    this.chunkSize = mode === MODE_ENCRYPT ? rs - 17 : 21;\n    this.partialChunk = new Uint8Array(this.chunkSize); //where partial chunks are saved\n    this.offset = 0;\n  }\n\n  send(buf, controller) {\n    controller.enqueue(buf);\n    if (this.chunkSize === 21 && this.mode === MODE_DECRYPT) {\n      this.chunkSize = this.rs;\n    }\n    this.partialChunk = new Uint8Array(this.chunkSize);\n    this.offset = 0;\n  }\n\n  //reslice input into record sized chunks\n  transform(chunk, controller) {\n    //console.log('Received chunk with %d bytes.', chunk.byteLength)\n    let i = 0;\n\n    if (this.offset > 0) {\n      const len = Math.min(chunk.byteLength, this.chunkSize - this.offset);\n      this.partialChunk.set(chunk.slice(0, len), this.offset);\n      this.offset += len;\n      i += len;\n\n      if (this.offset === this.chunkSize) {\n        this.send(this.partialChunk, controller);\n      }\n    }\n\n    while (i < chunk.byteLength) {\n      const remainingBytes = chunk.byteLength - i;\n      if (remainingBytes >= this.chunkSize) {\n        const record = chunk.slice(i, i + this.chunkSize);\n        i += this.chunkSize;\n        this.send(record, controller);\n      } else {\n        const end = chunk.slice(i, i + remainingBytes);\n        i += end.byteLength;\n        this.partialChunk.set(end);\n        this.offset = end.byteLength;\n      }\n    }\n  }\n\n  flush(controller) {\n    if (this.offset > 0) {\n      controller.enqueue(this.partialChunk.slice(0, this.offset));\n    }\n  }\n}\n\n/*\ninput: a ReadableStream containing data to be transformed\nkey:  Uint8Array containing key of size KEY_LENGTH\nrs:   int containing record size, optional\nsalt: ArrayBuffer containing salt of KEY_LENGTH length, optional\n*/\nexport function encryptStream(\n  input,\n  key,\n  rs = ECE_RECORD_SIZE,\n  salt = generateSalt(KEY_LENGTH)\n) {\n  const mode = 'encrypt';\n  const inputStream = transformStream(input, new StreamSlicer(rs, mode));\n  return transformStream(inputStream, new ECETransformer(mode, key, rs, salt));\n}\n\n/*\ninput: a ReadableStream containing data to be transformed\nkey:  Uint8Array containing key of size KEY_LENGTH\nrs:   int containing record size, optional\n*/\nexport function decryptStream(input, key, rs = ECE_RECORD_SIZE) {\n  const mode = 'decrypt';\n  const inputStream = transformStream(input, new StreamSlicer(rs, mode));\n  return transformStream(inputStream, new ECETransformer(mode, key, rs));\n}\n"
  },
  {
    "path": "app/experiments.js",
    "content": "import hash from 'string-hash';\nimport Account from './ui/account';\n\nconst experiments = {\n  signin_button_color: {\n    eligible: function() {\n      return true;\n    },\n    variant: function() {\n      return ['white-blue', 'blue', 'white-violet', 'violet'][\n        Math.floor(Math.random() * 4)\n      ];\n    },\n    run: function(variant, state) {\n      const account = state.cache(Account, 'account');\n      account.buttonClass = variant;\n    }\n  }\n};\n\n//Returns a number between 0 and 1\n// eslint-disable-next-line no-unused-vars\nfunction luckyNumber(str) {\n  return hash(str) / 0xffffffff;\n}\n\nfunction checkExperiments(state, emitter) {\n  const all = Object.keys(experiments);\n  const id = all.find(id => experiments[id].eligible(state));\n  if (id) {\n    const variant = experiments[id].variant(state);\n    state.storage.enroll(id, variant);\n    experiments[id].run(variant, state, emitter);\n  }\n}\n\nexport default function initialize(state, emitter) {\n  emitter.on('DOMContentLoaded', () => {\n    const xp = experiments[state.query.x];\n    if (xp) {\n      xp.run(+state.query.v, state, emitter);\n    }\n  });\n  const enrolled = state.storage.enrolled;\n  // single experiment per session for now\n  const id = Object.keys(enrolled)[0];\n  if (Object.keys(experiments).includes(id)) {\n    experiments[id].run(enrolled[id], state, emitter);\n  } else {\n    checkExperiments(state, emitter);\n  }\n}\n"
  },
  {
    "path": "app/fileReceiver.js",
    "content": "import Nanobus from 'nanobus';\nimport Keychain from './keychain';\nimport { delay, bytes, streamToArrayBuffer } from './utils';\nimport {\n  downloadFile,\n  downloadDone,\n  metadata,\n  getApiUrl,\n  reportLink,\n  getDownloadToken\n} from './api';\nimport { blobStream } from './streams';\nimport Zip from './zip';\n\nexport default class FileReceiver extends Nanobus {\n  constructor(fileInfo) {\n    super('FileReceiver');\n    this.keychain = new Keychain(fileInfo.secretKey, fileInfo.nonce);\n    if (fileInfo.requiresPassword) {\n      this.keychain.setPassword(fileInfo.password, fileInfo.url);\n    }\n    this.fileInfo = fileInfo;\n    this.dlToken = null;\n    this.reset();\n  }\n\n  get id() {\n    return this.fileInfo.id;\n  }\n\n  get progressRatio() {\n    return this.progress[0] / this.progress[1];\n  }\n\n  get progressIndefinite() {\n    return this.state !== 'downloading';\n  }\n\n  get sizes() {\n    return {\n      partialSize: bytes(this.progress[0]),\n      totalSize: bytes(this.progress[1])\n    };\n  }\n\n  cancel() {\n    if (this.downloadRequest) {\n      this.downloadRequest.cancel();\n    }\n  }\n\n  reset() {\n    this.msg = 'fileSizeProgress';\n    this.state = 'initialized';\n    this.progress = [0, 1];\n  }\n\n  async getMetadata() {\n    const meta = await metadata(this.fileInfo.id, this.keychain);\n    this.fileInfo.name = meta.name;\n    this.fileInfo.type = meta.type;\n    this.fileInfo.size = +meta.size;\n    this.fileInfo.manifest = meta.manifest;\n    this.fileInfo.flagged = meta.flagged;\n    this.state = 'ready';\n  }\n\n  async reportLink(reason) {\n    await reportLink(this.fileInfo.id, this.keychain, reason);\n  }\n\n  sendMessageToSw(msg) {\n    return new Promise((resolve, reject) => {\n      const channel = new MessageChannel();\n\n      channel.port1.onmessage = function(event) {\n        if (event.data === undefined) {\n          reject('bad response from serviceWorker');\n        } else if (event.data.error !== undefined) {\n          reject(event.data.error);\n        } else {\n          resolve(event.data);\n        }\n      };\n\n      navigator.serviceWorker.controller.postMessage(msg, [channel.port2]);\n    });\n  }\n\n  async downloadBlob(noSave = false) {\n    this.state = 'downloading';\n    this.downloadRequest = await downloadFile(\n      this.fileInfo.id,\n      this.dlToken,\n      p => {\n        this.progress = [p, this.fileInfo.size];\n        this.emit('progress');\n      }\n    );\n    try {\n      const ciphertext = await this.downloadRequest.result;\n      this.downloadRequest = null;\n      this.msg = 'decryptingFile';\n      this.state = 'decrypting';\n      this.emit('decrypting');\n      let size = this.fileInfo.size;\n      let plainStream = this.keychain.decryptStream(blobStream(ciphertext));\n      if (this.fileInfo.type === 'send-archive') {\n        const zip = new Zip(this.fileInfo.manifest, plainStream);\n        plainStream = zip.stream;\n        size = zip.size;\n      }\n      const plaintext = await streamToArrayBuffer(plainStream, size);\n      if (!noSave) {\n        await saveFile({\n          plaintext,\n          name: decodeURIComponent(this.fileInfo.name),\n          type: this.fileInfo.type\n        });\n      }\n      this.msg = 'downloadFinish';\n      this.emit('complete');\n      this.state = 'complete';\n    } catch (e) {\n      this.downloadRequest = null;\n      throw e;\n    }\n  }\n\n  async downloadStream(noSave = false) {\n    const start = Date.now();\n    const onprogress = p => {\n      this.progress = [p, this.fileInfo.size];\n      this.emit('progress');\n    };\n\n    this.downloadRequest = {\n      cancel: () => {\n        this.sendMessageToSw({ request: 'cancel', id: this.fileInfo.id });\n      }\n    };\n\n    try {\n      this.state = 'downloading';\n\n      const info = {\n        request: 'init',\n        id: this.fileInfo.id,\n        filename: this.fileInfo.name,\n        type: this.fileInfo.type,\n        manifest: this.fileInfo.manifest,\n        key: this.fileInfo.secretKey,\n        requiresPassword: this.fileInfo.requiresPassword,\n        password: this.fileInfo.password,\n        url: this.fileInfo.url,\n        size: this.fileInfo.size,\n        nonce: this.keychain.nonce,\n        dlToken: this.dlToken,\n        noSave\n      };\n      await this.sendMessageToSw(info);\n\n      onprogress(0);\n\n      if (noSave) {\n        const res = await fetch(getApiUrl(`/api/download/${this.fileInfo.id}`));\n        if (res.status !== 200) {\n          throw new Error(res.status);\n        }\n      } else {\n        const downloadPath = `/api/download/${this.fileInfo.id}`;\n        let downloadUrl = getApiUrl(downloadPath);\n        if (downloadUrl === downloadPath) {\n          downloadUrl = `${location.protocol}//${location.host}${downloadPath}`;\n        }\n        const a = document.createElement('a');\n        a.href = downloadUrl;\n        document.body.appendChild(a);\n        a.click();\n      }\n\n      let prog = 0;\n      let hangs = 0;\n      while (prog < this.fileInfo.size) {\n        const msg = await this.sendMessageToSw({\n          request: 'progress',\n          id: this.fileInfo.id\n        });\n        if (msg.progress === prog) {\n          hangs++;\n        } else {\n          hangs = 0;\n        }\n        if (hangs > 30) {\n          // TODO: On Chrome we don't get a cancel\n          // signal so one is indistinguishable from\n          // a hang. We may be able to detect\n          // which end is hung in the service worker\n          // to improve on this.\n          const e = new Error('hung download');\n          e.duration = Date.now() - start;\n          e.size = this.fileInfo.size;\n          e.progress = prog;\n          throw e;\n        }\n        prog = msg.progress;\n        onprogress(prog);\n        await delay(1000);\n      }\n\n      this.downloadRequest = null;\n      this.msg = 'downloadFinish';\n      this.emit('complete');\n      this.state = 'complete';\n    } catch (e) {\n      this.downloadRequest = null;\n      if (e === 'cancelled' || e.message === '400') {\n        throw new Error(0);\n      }\n      throw e;\n    }\n  }\n\n  async download({ stream, storage, noSave }) {\n    this.dlToken = storage.getDownloadToken(this.id);\n    if (!this.dlToken) {\n      this.dlToken = await getDownloadToken(this.id, this.keychain);\n      storage.setDownloadToken(this.id, this.dlToken);\n    }\n    if (stream) {\n      await this.downloadStream(noSave);\n    } else {\n      await this.downloadBlob(noSave);\n    }\n    await downloadDone(this.id, this.dlToken);\n    storage.setDownloadToken(this.id);\n  }\n}\n\nasync function saveFile(file) {\n  return new Promise(function(resolve, reject) {\n    const dataView = new DataView(file.plaintext);\n    const blob = new Blob([dataView], { type: file.type });\n\n    if (navigator.msSaveBlob) {\n      navigator.msSaveBlob(blob, file.name);\n      return resolve();\n    } else if (/iPhone|fxios/i.test(navigator.userAgent)) {\n      // This method is much slower but createObjectURL\n      // is buggy on iOS\n      const reader = new FileReader();\n      reader.addEventListener('loadend', function() {\n        if (reader.error) {\n          return reject(reader.error);\n        }\n        if (reader.result) {\n          const a = document.createElement('a');\n          a.href = reader.result;\n          a.download = file.name;\n          document.body.appendChild(a);\n          a.click();\n        }\n        resolve();\n      });\n      reader.readAsDataURL(blob);\n    } else {\n      const downloadUrl = URL.createObjectURL(blob);\n      const a = document.createElement('a');\n      a.href = downloadUrl;\n      a.download = file.name;\n      document.body.appendChild(a);\n      a.click();\n      URL.revokeObjectURL(downloadUrl);\n      setTimeout(resolve, 100);\n    }\n  });\n}\n"
  },
  {
    "path": "app/fileSender.js",
    "content": "import Nanobus from 'nanobus';\nimport OwnedFile from './ownedFile';\nimport Keychain from './keychain';\nimport { arrayToB64, bytes } from './utils';\nimport { uploadWs } from './api';\nimport { encryptedSize } from './utils';\n\nexport default class FileSender extends Nanobus {\n  constructor() {\n    super('FileSender');\n    this.keychain = new Keychain();\n    this.reset();\n  }\n\n  get progressRatio() {\n    return this.progress[0] / this.progress[1];\n  }\n\n  get progressIndefinite() {\n    return (\n      ['fileSizeProgress', 'notifyUploadEncryptDone'].indexOf(this.msg) === -1\n    );\n  }\n\n  get sizes() {\n    return {\n      partialSize: bytes(this.progress[0]),\n      totalSize: bytes(this.progress[1])\n    };\n  }\n\n  reset() {\n    this.uploadRequest = null;\n    this.msg = 'importingFile';\n    this.progress = [0, 1];\n    this.cancelled = false;\n  }\n\n  cancel() {\n    this.cancelled = true;\n    if (this.uploadRequest) {\n      this.uploadRequest.cancel();\n    }\n  }\n\n  async upload(archive, bearerToken) {\n    if (this.cancelled) {\n      throw new Error(0);\n    }\n    this.msg = 'encryptingFile';\n    this.emit('encrypting');\n    const totalSize = encryptedSize(archive.size);\n    const encStream = await this.keychain.encryptStream(archive.stream);\n    const metadata = await this.keychain.encryptMetadata(archive);\n    const authKeyB64 = await this.keychain.authKeyB64();\n\n    this.uploadRequest = uploadWs(\n      encStream,\n      metadata,\n      authKeyB64,\n      archive.timeLimit,\n      archive.dlimit,\n      bearerToken,\n      p => {\n        this.progress = [p, totalSize];\n        this.emit('progress');\n      }\n    );\n\n    if (this.cancelled) {\n      throw new Error(0);\n    }\n\n    this.msg = 'fileSizeProgress';\n    this.emit('progress'); // HACK to kick MS Edge\n    try {\n      const result = await this.uploadRequest.result;\n      this.msg = 'notifyUploadEncryptDone';\n      this.uploadRequest = null;\n      this.progress = [1, 1];\n      const secretKey = arrayToB64(this.keychain.rawSecret);\n      const ownedFile = new OwnedFile({\n        id: result.id,\n        url: `${result.url}#${secretKey}`,\n        name: archive.name,\n        size: archive.size,\n        manifest: archive.manifest,\n        time: result.duration,\n        speed: archive.size / (result.duration / 1000),\n        createdAt: Date.now(),\n        expiresAt: Date.now() + archive.timeLimit * 1000,\n        secretKey: secretKey,\n        nonce: this.keychain.nonce,\n        ownerToken: result.ownerToken,\n        dlimit: archive.dlimit,\n        timeLimit: archive.timeLimit\n      });\n\n      return ownedFile;\n    } catch (e) {\n      this.msg = 'errorPageHeader';\n      this.uploadRequest = null;\n      throw e;\n    }\n  }\n}\n"
  },
  {
    "path": "app/fxa.js",
    "content": "/* global AUTH_CONFIG */\nimport { arrayToB64, b64ToArray, concat } from './utils';\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\nfunction getOtherInfo(enc) {\n  const name = encoder.encode(enc);\n  const length = 256;\n  const buffer = new ArrayBuffer(name.length + 16);\n  const dv = new DataView(buffer);\n  const result = new Uint8Array(buffer);\n  let i = 0;\n  dv.setUint32(i, name.length);\n  i += 4;\n  result.set(name, i);\n  i += name.length;\n  dv.setUint32(i, 0);\n  i += 4;\n  dv.setUint32(i, 0);\n  i += 4;\n  dv.setUint32(i, length);\n  return result;\n}\n\nasync function concatKdf(key, enc) {\n  if (key.length !== 32) {\n    throw new Error('unsupported key length');\n  }\n  const otherInfo = getOtherInfo(enc);\n  const buffer = new ArrayBuffer(4 + key.length + otherInfo.length);\n  const dv = new DataView(buffer);\n  const concat = new Uint8Array(buffer);\n  dv.setUint32(0, 1);\n  concat.set(key, 4);\n  concat.set(otherInfo, key.length + 4);\n  const result = await crypto.subtle.digest('SHA-256', concat);\n  return new Uint8Array(result);\n}\n\nexport async function prepareScopedBundleKey(storage) {\n  const keys = await crypto.subtle.generateKey(\n    {\n      name: 'ECDH',\n      namedCurve: 'P-256'\n    },\n    true,\n    ['deriveBits']\n  );\n  const privateJwk = await crypto.subtle.exportKey('jwk', keys.privateKey);\n  const publicJwk = await crypto.subtle.exportKey('jwk', keys.publicKey);\n  const kid = await crypto.subtle.digest(\n    'SHA-256',\n    encoder.encode(JSON.stringify(publicJwk))\n  );\n  privateJwk.kid = kid;\n  publicJwk.kid = kid;\n  storage.set('scopedBundlePrivateKey', JSON.stringify(privateJwk));\n  return arrayToB64(encoder.encode(JSON.stringify(publicJwk)));\n}\n\nexport async function decryptBundle(storage, bundle) {\n  const privateJwk = JSON.parse(storage.get('scopedBundlePrivateKey'));\n  storage.remove('scopedBundlePrivateKey');\n  const privateKey = await crypto.subtle.importKey(\n    'jwk',\n    privateJwk,\n    {\n      name: 'ECDH',\n      namedCurve: 'P-256'\n    },\n    false,\n    ['deriveBits']\n  );\n  const jweParts = bundle.split('.');\n  if (jweParts.length !== 5) {\n    throw new Error('invalid jwe');\n  }\n  const header = JSON.parse(decoder.decode(b64ToArray(jweParts[0])));\n  const additionalData = encoder.encode(jweParts[0]);\n  const iv = b64ToArray(jweParts[2]);\n  const ciphertext = b64ToArray(jweParts[3]);\n  const tag = b64ToArray(jweParts[4]);\n\n  if (header.alg !== 'ECDH-ES' || header.enc !== 'A256GCM') {\n    throw new Error('unsupported jwe type');\n  }\n\n  const publicKey = await crypto.subtle.importKey(\n    'jwk',\n    header.epk,\n    {\n      name: 'ECDH',\n      namedCurve: 'P-256'\n    },\n    false,\n    []\n  );\n  const sharedBits = await crypto.subtle.deriveBits(\n    {\n      name: 'ECDH',\n      public: publicKey\n    },\n    privateKey,\n    256\n  );\n\n  const rawSharedKey = await concatKdf(new Uint8Array(sharedBits), header.enc);\n  const sharedKey = await crypto.subtle.importKey(\n    'raw',\n    rawSharedKey,\n    {\n      name: 'AES-GCM'\n    },\n    false,\n    ['decrypt']\n  );\n\n  const plaintext = await crypto.subtle.decrypt(\n    {\n      name: 'AES-GCM',\n      iv: iv,\n      additionalData: additionalData,\n      tagLength: tag.length * 8\n    },\n    sharedKey,\n    concat(ciphertext, tag)\n  );\n\n  return JSON.parse(decoder.decode(plaintext));\n}\n\nexport async function preparePkce(storage) {\n  const verifier = arrayToB64(crypto.getRandomValues(new Uint8Array(64)));\n  storage.set('pkceVerifier', verifier);\n  const challenge = await crypto.subtle.digest(\n    'SHA-256',\n    encoder.encode(verifier)\n  );\n  return arrayToB64(new Uint8Array(challenge));\n}\n\nexport async function deriveFileListKey(ikm) {\n  const baseKey = await crypto.subtle.importKey(\n    'raw',\n    b64ToArray(ikm),\n    { name: 'HKDF' },\n    false,\n    ['deriveKey']\n  );\n  const fileListKey = await crypto.subtle.deriveKey(\n    {\n      name: 'HKDF',\n      salt: new Uint8Array(),\n      info: encoder.encode('fileList'),\n      hash: 'SHA-256'\n    },\n    baseKey,\n    {\n      name: 'AES-GCM',\n      length: 128\n    },\n    true,\n    ['encrypt', 'decrypt']\n  );\n  const rawFileListKey = await crypto.subtle.exportKey('raw', fileListKey);\n  return arrayToB64(new Uint8Array(rawFileListKey));\n}\n\nexport async function getFileListKey(storage, bundle) {\n  const jwks = await decryptBundle(storage, bundle);\n  const jwk = jwks[AUTH_CONFIG.key_scope];\n  return deriveFileListKey(jwk.k);\n}\n"
  },
  {
    "path": "app/keychain.js",
    "content": "import { arrayToB64, b64ToArray } from './utils';\nimport { decryptStream, encryptStream } from './ece.js';\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\nexport default class Keychain {\n  constructor(secretKeyB64, nonce) {\n    this._nonce = nonce || 'yRCdyQ1EMSA3mo4rqSkuNQ==';\n    if (secretKeyB64) {\n      this.rawSecret = b64ToArray(secretKeyB64);\n    } else {\n      this.rawSecret = crypto.getRandomValues(new Uint8Array(16));\n    }\n    this.secretKeyPromise = crypto.subtle.importKey(\n      'raw',\n      this.rawSecret,\n      'HKDF',\n      false,\n      ['deriveKey']\n    );\n    this.metaKeyPromise = this.secretKeyPromise.then(function(secretKey) {\n      return crypto.subtle.deriveKey(\n        {\n          name: 'HKDF',\n          salt: new Uint8Array(),\n          info: encoder.encode('metadata'),\n          hash: 'SHA-256'\n        },\n        secretKey,\n        {\n          name: 'AES-GCM',\n          length: 128\n        },\n        false,\n        ['encrypt', 'decrypt']\n      );\n    });\n    this.authKeyPromise = this.secretKeyPromise.then(function(secretKey) {\n      return crypto.subtle.deriveKey(\n        {\n          name: 'HKDF',\n          salt: new Uint8Array(),\n          info: encoder.encode('authentication'),\n          hash: 'SHA-256'\n        },\n        secretKey,\n        {\n          name: 'HMAC',\n          hash: { name: 'SHA-256' }\n        },\n        true,\n        ['sign']\n      );\n    });\n  }\n\n  get nonce() {\n    return this._nonce;\n  }\n\n  set nonce(n) {\n    if (n && n !== this._nonce) {\n      this._nonce = n;\n    }\n  }\n\n  setPassword(password, shareUrl) {\n    this.authKeyPromise = crypto.subtle\n      .importKey('raw', encoder.encode(password), { name: 'PBKDF2' }, false, [\n        'deriveKey'\n      ])\n      .then(passwordKey =>\n        crypto.subtle.deriveKey(\n          {\n            name: 'PBKDF2',\n            salt: encoder.encode(shareUrl),\n            iterations: 100,\n            hash: 'SHA-256'\n          },\n          passwordKey,\n          {\n            name: 'HMAC',\n            hash: 'SHA-256'\n          },\n          true,\n          ['sign']\n        )\n      );\n  }\n\n  setAuthKey(authKeyB64) {\n    this.authKeyPromise = crypto.subtle.importKey(\n      'raw',\n      b64ToArray(authKeyB64),\n      {\n        name: 'HMAC',\n        hash: 'SHA-256'\n      },\n      true,\n      ['sign']\n    );\n  }\n\n  async authKeyB64() {\n    const authKey = await this.authKeyPromise;\n    const rawAuth = await crypto.subtle.exportKey('raw', authKey);\n    return arrayToB64(new Uint8Array(rawAuth));\n  }\n\n  async authHeader() {\n    const authKey = await this.authKeyPromise;\n    const sig = await crypto.subtle.sign(\n      {\n        name: 'HMAC'\n      },\n      authKey,\n      b64ToArray(this.nonce)\n    );\n    return `send-v1 ${arrayToB64(new Uint8Array(sig))}`;\n  }\n\n  async encryptMetadata(metadata) {\n    const metaKey = await this.metaKeyPromise;\n    const ciphertext = await crypto.subtle.encrypt(\n      {\n        name: 'AES-GCM',\n        iv: new Uint8Array(12),\n        tagLength: 128\n      },\n      metaKey,\n      encoder.encode(\n        JSON.stringify({\n          name: metadata.name,\n          size: metadata.size,\n          type: metadata.type || 'application/octet-stream',\n          manifest: metadata.manifest || {}\n        })\n      )\n    );\n    return ciphertext;\n  }\n\n  encryptStream(plainStream) {\n    return encryptStream(plainStream, this.rawSecret);\n  }\n\n  decryptStream(cryptotext) {\n    return decryptStream(cryptotext, this.rawSecret);\n  }\n\n  async decryptMetadata(ciphertext) {\n    const metaKey = await this.metaKeyPromise;\n    const plaintext = await crypto.subtle.decrypt(\n      {\n        name: 'AES-GCM',\n        iv: new Uint8Array(12),\n        tagLength: 128\n      },\n      metaKey,\n      ciphertext\n    );\n    return JSON.parse(decoder.decode(plaintext));\n  }\n}\n"
  },
  {
    "path": "app/locale.js",
    "content": "import { FluentBundle } from '@fluent/bundle';\n\nfunction makeBundle(locale, ftl) {\n  const bundle = new FluentBundle(locale, { useIsolating: false });\n  bundle.addMessages(ftl);\n  return bundle;\n}\n\nexport async function getTranslator(locale) {\n  const bundles = [];\n  const { default: en } = await import('../public/locales/en-US/send.ftl');\n  if (locale !== 'en-US') {\n    const { default: ftl } = await import(\n      `../public/locales/${locale}/send.ftl`\n    );\n    bundles.push(makeBundle(locale, ftl));\n  }\n  bundles.push(makeBundle('en-US', en));\n  return function(id, data) {\n    for (let bundle of bundles) {\n      if (bundle.hasMessage(id)) {\n        return bundle.format(bundle.getMessage(id), data);\n      }\n    }\n  };\n}\n"
  },
  {
    "path": "app/main.css",
    "content": "@tailwind base;\n\nhtml {\n  line-height: 1.15;\n}\n\n@tailwind components;\n\n:not(input) {\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n\n:root {\n  --violet-gradient: linear-gradient(\n    -180deg,\n    rgba(144, 89, 255, 0.8) 0%,\n    rgba(144, 89, 255, 0.4) 100%\n  );\n}\n\na {\n  color: inherit;\n  text-decoration: none;\n}\n\na:focus {\n  outline: 1px dotted grey;\n}\n\nbody {\n  overflow-x: hidden;\n}\n\n.btn {\n  @apply bg-blue-60;\n  @apply text-white;\n  @apply cursor-pointer;\n  @apply py-4;\n  @apply px-6;\n  @apply font-semibold;\n}\n\n.btn:hover {\n  @apply bg-blue-70;\n}\n\n.btn:focus {\n  @apply bg-blue-70;\n}\n\n.btn:disabled {\n  @apply bg-grey-transparent;\n\n  cursor: not-allowed;\n}\n\n.checkbox {\n  @apply leading-normal;\n  @apply select-none;\n}\n\n.checkbox > input[type='checkbox'] {\n  @apply absolute;\n  @apply opacity-0;\n}\n\n.checkbox > label {\n  @apply cursor-pointer;\n}\n\n.checkbox > label::before {\n  /* @apply bg-grey-10; */\n  @apply border;\n  @apply rounded-sm;\n\n  content: '';\n  height: 1.5rem;\n  width: 1.5rem;\n  margin-right: 0.5rem;\n  float: left;\n}\n\n.checkbox > label:hover::before {\n  @apply border-blue-50;\n}\n\n.checkbox > input:focus + label::before {\n  @apply border-blue-50;\n}\n\n.checkbox > input:checked + label::before {\n  @apply bg-blue-50;\n  @apply border-blue-50;\n\n  background-image: url('../assets/lock.svg');\n  background-position: center;\n  background-size: 1.25rem;\n  background-repeat: no-repeat;\n}\n\n.checkbox > input:disabled + label {\n  cursor: auto;\n}\n\n.checkbox > input:disabled + label::before {\n  @apply bg-blue-50;\n  @apply border-blue-50;\n\n  background-image: url('../assets/lock.svg');\n  background-position: center;\n  background-size: 1.25rem;\n  background-repeat: no-repeat;\n  cursor: auto;\n}\n\ndetails {\n  overflow: hidden;\n}\n\ndetails > summary::-webkit-details-marker {\n  display: none;\n}\n\ndetails > summary > svg {\n  transition: all 0.25s cubic-bezier(0.07, 0.95, 0, 1);\n}\n\ndetails[open] {\n  overflow-y: auto;\n}\n\ndetails[open] > summary > svg {\n  transform: rotate(90deg);\n}\n\nfooter li:hover {\n  text-decoration: underline;\n}\n\n.link-blue {\n  @apply text-blue-60;\n}\n\n.link-blue:hover {\n  @apply text-blue-70;\n}\n\n.link-blue:focus {\n  @apply text-blue-70;\n}\n\n.main-header img {\n  height: 32px;\n  width: auto;\n}\n\n.intro {\n  max-width: 100%;\n  height: unset;\n}\n\n.dl-bg {\n  filter: grayscale(1) opacity(0.15);\n}\n\n.main {\n  display: flex;\n  position: relative;\n  max-width: 64rem;\n  width: 100%;\n  height: 100%;\n}\n\n.main > section {\n  @apply bg-white;\n}\n\n#password-msg::after {\n  content: '\\200b';\n}\n\nprogress {\n  @apply bg-grey-30;\n  @apply rounded-sm;\n  @apply w-full;\n  @apply h-1;\n}\n\nprogress::-webkit-progress-bar {\n  @apply bg-grey-30;\n  @apply rounded-sm;\n  @apply w-full;\n  @apply h-1;\n}\n\nprogress::-webkit-progress-value {\n  /* stylelint-disable */\n  background-image: -webkit-linear-gradient(\n      -45deg,\n      transparent 20%,\n      rgba(255, 255, 255, 0.4) 20%,\n      rgba(255, 255, 255, 0.4) 40%,\n      transparent 40%,\n      transparent 60%,\n      rgba(255, 255, 255, 0.4) 60%,\n      rgba(255, 255, 255, 0.4) 80%,\n      transparent 80%\n    ),\n    -webkit-linear-gradient(left, #0a84ff, #0a84ff);\n  /* stylelint-enable */\n  border-radius: 2px;\n  background-size: 21px 20px, 100% 100%, 100% 100%;\n  -webkit-animation: animate-stripes 1s linear infinite;\n}\n\nprogress::-moz-progress-bar {\n  /* stylelint-disable */\n  background-image: -moz-linear-gradient(\n      135deg,\n      transparent 20%,\n      rgba(255, 255, 255, 0.4) 20%,\n      rgba(255, 255, 255, 0.4) 40%,\n      transparent 40%,\n      transparent 60%,\n      rgba(255, 255, 255, 0.4) 60%,\n      rgba(255, 255, 255, 0.4) 80%,\n      transparent 80%\n    ),\n    -moz-linear-gradient(left, #0a84ff, #0a84ff);\n  /* stylelint-enable */\n  border-radius: 2px;\n  background-size: 21px 20px, 100% 100%, 100% 100%;\n  animation: animate-stripes 1s linear infinite;\n}\n\n@-webkit-keyframes animate-stripes {\n  100% {\n    background-position: -21px 0;\n  }\n}\n\n@keyframes animate-stripes {\n  100% {\n    background-position: -21px 0;\n  }\n}\n\nselect {\n  background-image: url('../assets/select-arrow.svg');\n  background-position: calc(100% - 0.75rem);\n  background-repeat: no-repeat;\n}\n\n@screen md {\n  .main-header img {\n    height: 48px;\n    width: auto;\n  }\n\n  .intro {\n    max-width: unset;\n    height: unset;\n    margin-bottom: -3rem;\n    margin-right: -7rem;\n  }\n\n  .main {\n    @apply flex-1;\n    @apply self-center;\n    @apply items-center;\n    @apply m-auto;\n    @apply py-8;\n\n    min-height: 42rem;\n    max-height: 42rem;\n    width: calc(100% - 3rem);\n  }\n}\n\n@screen dark {\n  body {\n    @apply text-grey-10;\n\n    background-image: unset;\n  }\n\n  .btn {\n    @apply bg-blue-40;\n    @apply text-white;\n  }\n\n  .btn:hover {\n    @apply bg-blue-50;\n  }\n\n  .btn:focus {\n    @apply bg-blue-50;\n  }\n\n  .btn:disabled {\n    @apply bg-grey-80;\n  }\n\n  .link-blue {\n    @apply text-blue-40;\n  }\n\n  .link-blue:hover {\n    @apply text-blue-50;\n  }\n\n  .link-blue:focus {\n    @apply text-blue-50;\n  }\n\n  .main > section {\n    @apply bg-grey-90;\n  }\n\n  @screen md {\n    .main > section {\n      @apply border;\n      @apply border-grey-80;\n    }\n  }\n}\n\n@tailwind utilities;\n\n@responsive {\n  .shadow-light {\n    box-shadow: 0 0 8px 0 rgba(12, 12, 13, 0.1);\n  }\n\n  .shadow-big {\n    box-shadow: 0 12px 18px 2px rgba(34, 0, 51, 0.04),\n      0 6px 22px 4px rgba(7, 48, 114, 0.12),\n      0 6px 10px -4px rgba(14, 13, 26, 0.12);\n  }\n}\n\n@variants focus {\n  .outline {\n    outline: 1px dotted grey;\n  }\n}\n\n.word-break-all {\n  word-break: break-all;\n  line-break: anywhere;\n}\n\n.signin {\n  backface-visibility: hidden;\n  border-radius: 6px;\n  transition-property: transform, background-color;\n  transition-duration: 250ms;\n  transition-timing-function: cubic-bezier(0.07, 0.95, 0, 1);\n}\n\n.signin:hover,\n.signin:focus {\n  transform: scale(1.0625);\n}\n\n.signin:hover:active {\n  transform: scale(0.9375);\n}\n"
  },
  {
    "path": "app/main.js",
    "content": "/* global DEFAULTS LIMITS PREFS */\nimport 'core-js';\nimport 'fast-text-encoding'; // MS Edge support\nimport 'intl-pluralrules';\nimport choo from 'choo';\nimport nanotiming from 'nanotiming';\nimport routes from './routes';\nimport getCapabilities from './capabilities';\nimport controller from './controller';\nimport dragManager from './dragManager';\nimport pasteManager from './pasteManager';\nimport storage from './storage';\nimport metrics from './metrics';\nimport experiments from './experiments';\nimport * as Sentry from '@sentry/browser';\nimport './main.css';\nimport User from './user';\nimport { getTranslator } from './locale';\nimport Archive from './archive';\nimport { setTranslate, locale } from './utils';\n\nif (navigator.doNotTrack !== '1' && window.SENTRY_CONFIG) {\n  Sentry.init(window.SENTRY_CONFIG);\n}\n\nif (process.env.NODE_ENV === 'production') {\n  nanotiming.disabled = true;\n}\n\n(async function start() {\n  const capabilities = await getCapabilities();\n  if (\n    !capabilities.crypto &&\n    window.location.pathname !== '/unsupported/crypto'\n  ) {\n    return window.location.assign('/unsupported/crypto');\n  }\n  if (capabilities.serviceWorker) {\n    try {\n      await navigator.serviceWorker.register('/serviceWorker.js');\n      await navigator.serviceWorker.ready;\n    } catch (e) {\n      // continue but disable streaming downloads\n      capabilities.streamDownload = false;\n    }\n  }\n\n  const translate = await getTranslator(locale());\n  setTranslate(translate);\n  // eslint-disable-next-line require-atomic-updates\n  window.initialState = {\n    LIMITS,\n    DEFAULTS,\n    PREFS,\n    archive: new Archive([], DEFAULTS.EXPIRE_SECONDS),\n    capabilities,\n    translate,\n    storage,\n    sentry: Sentry,\n    user: new User(storage, LIMITS, window.AUTH_CONFIG),\n    transfer: null,\n    fileInfo: null,\n    locale: locale()\n  };\n\n  const app = routes(choo({ hash: true }));\n  // eslint-disable-next-line require-atomic-updates\n  window.app = app;\n  app.use(experiments);\n  app.use(metrics);\n  app.use(controller);\n  app.use(dragManager);\n  app.use(pasteManager);\n  app.mount('body');\n})();\n"
  },
  {
    "path": "app/metrics.js",
    "content": "import storage from './storage';\nimport { platform, locale } from './utils';\nimport { sendMetrics } from './api';\n\nlet appState = null;\nlet experiment = null;\nconst HOUR = 1000 * 60 * 60;\nconst events = [];\nlet session_id = Date.now();\nconst lang = locale();\n\nexport default function initialize(state, emitter) {\n  appState = state;\n\n  emitter.on('DOMContentLoaded', () => {\n    experiment = storage.enrolled;\n    if (!appState.user.firstAction) {\n      appState.user.firstAction =\n        appState.route === '/' ? 'upload' : 'download';\n    }\n    const query = appState.query;\n    addEvent('client_visit', {\n      entrypoint: appState.route === '/' ? 'upload' : 'download',\n      referrer: document.referrer,\n      utm_campaign: query.utm_campaign,\n      utm_content: query.utm_content,\n      utm_medium: query.utm_medium,\n      utm_source: query.utm_source,\n      utm_term: query.utm_term\n    });\n  });\n  emitter.on('experiment', experimentEvent);\n  window.addEventListener('unload', submitEvents);\n}\n\nfunction sizeOrder(n) {\n  return Math.floor(Math.log10(n));\n}\n\nfunction submitEvents() {\n  if (navigator.doNotTrack === '1') {\n    return;\n  }\n  sendMetrics(\n    new Blob(\n      [\n        JSON.stringify({\n          now: Date.now(),\n          session_id,\n          lang,\n          platform: platform(),\n          events\n        })\n      ],\n      { type: 'text/plain' } // see http://crbug.com/490015\n    )\n  );\n  events.splice(0);\n}\n\nasync function addEvent(event_type, event_properties) {\n  const user_id = await appState.user.metricId();\n  const device_id = await appState.user.deviceId();\n  const ab_id = Object.keys(experiment)[0];\n  if (ab_id) {\n    event_properties.experiment = ab_id;\n    event_properties.variant = experiment[ab_id];\n  }\n  events.push({\n    device_id,\n    event_properties,\n    event_type,\n    time: Date.now(),\n    user_id,\n    user_properties: {\n      anonymous: !appState.user.loggedIn,\n      first_action: appState.user.firstAction,\n      active_count: storage.files.length\n    }\n  });\n  if (events.length === 25) {\n    submitEvents();\n  }\n}\n\nfunction cancelledUpload(archive, duration) {\n  return addEvent('client_upload', {\n    download_limit: archive.dlimit,\n    duration: sizeOrder(duration),\n    file_count: archive.numFiles,\n    password_protected: !!archive.password,\n    size: sizeOrder(archive.size),\n    status: 'cancel',\n    time_limit: archive.timeLimit\n  });\n}\n\nfunction completedUpload(archive, duration) {\n  return addEvent('client_upload', {\n    download_limit: archive.dlimit,\n    duration: sizeOrder(duration),\n    file_count: archive.numFiles,\n    password_protected: !!archive.password,\n    size: sizeOrder(archive.size),\n    status: 'ok',\n    time_limit: archive.timeLimit\n  });\n}\n\nfunction stoppedUpload(archive, duration = 0) {\n  return addEvent('client_upload', {\n    download_limit: archive.dlimit,\n    duration: sizeOrder(duration),\n    file_count: archive.numFiles,\n    password_protected: !!archive.password,\n    size: sizeOrder(archive.size),\n    status: 'error',\n    time_limit: archive.timeLimit\n  });\n}\n\nfunction stoppedDownload(params) {\n  return addEvent('client_download', {\n    duration: sizeOrder(params.duration),\n    password_protected: params.password_protected,\n    size: sizeOrder(params.size),\n    status: 'error'\n  });\n}\n\nfunction completedDownload(params) {\n  return addEvent('client_download', {\n    duration: sizeOrder(params.duration),\n    password_protected: params.password_protected,\n    size: sizeOrder(params.size),\n    status: 'ok'\n  });\n}\n\nfunction deletedUpload(ownedFile) {\n  return addEvent('client_delete', {\n    age: Math.floor((Date.now() - ownedFile.createdAt) / HOUR),\n    downloaded: ownedFile.dtotal > 0,\n    status: 'ok'\n  });\n}\n\nfunction experimentEvent(params) {\n  return addEvent('client_experiment', params);\n}\n\nfunction submittedSignup(params) {\n  return addEvent('client_login', {\n    status: 'ok',\n    trigger: params.trigger\n  });\n}\n\nfunction canceledSignup(params) {\n  return addEvent('client_login', {\n    status: 'cancel',\n    trigger: params.trigger\n  });\n}\n\nfunction loggedOut(params) {\n  addEvent('client_logout', {\n    status: 'ok',\n    trigger: params.trigger\n  });\n  // flush events and start new anon session\n  submitEvents();\n  session_id = Date.now();\n}\n\nexport {\n  cancelledUpload,\n  stoppedUpload,\n  completedUpload,\n  deletedUpload,\n  stoppedDownload,\n  completedDownload,\n  submittedSignup,\n  canceledSignup,\n  loggedOut\n};\n"
  },
  {
    "path": "app/ownedFile.js",
    "content": "import Keychain from './keychain';\nimport { arrayToB64 } from './utils';\nimport { del, fileInfo, setParams, setPassword } from './api';\n\nexport default class OwnedFile {\n  constructor(obj) {\n    if (!obj.manifest) {\n      throw new Error('invalid file object');\n    }\n    this.id = obj.id;\n    this.url = obj.url;\n    this.name = obj.name;\n    this.size = obj.size;\n    this.manifest = obj.manifest;\n    this.time = obj.time;\n    this.speed = obj.speed;\n    this.createdAt = obj.createdAt;\n    this.expiresAt = obj.expiresAt;\n    this.ownerToken = obj.ownerToken;\n    this.dlimit = obj.dlimit || 1;\n    this.dtotal = obj.dtotal || 0;\n    this.keychain = new Keychain(obj.secretKey, obj.nonce);\n    this._hasPassword = !!obj.hasPassword;\n    this.timeLimit = obj.timeLimit;\n  }\n\n  get hasPassword() {\n    return !!this._hasPassword;\n  }\n\n  get expired() {\n    return this.dlimit === this.dtotal || Date.now() > this.expiresAt;\n  }\n\n  async setPassword(password) {\n    try {\n      this.password = password;\n      this._hasPassword = true;\n      this.keychain.setPassword(password, this.url);\n      const result = await setPassword(this.id, this.ownerToken, this.keychain);\n      return result;\n    } catch (e) {\n      this.password = null;\n      this._hasPassword = false;\n      throw e;\n    }\n  }\n\n  del() {\n    return del(this.id, this.ownerToken);\n  }\n\n  changeLimit(dlimit, user = {}) {\n    if (this.dlimit !== dlimit) {\n      this.dlimit = dlimit;\n      return setParams(this.id, this.ownerToken, user.bearerToken, { dlimit });\n    }\n    return Promise.resolve(true);\n  }\n\n  async updateDownloadCount() {\n    const oldTotal = this.dtotal;\n    const oldLimit = this.dlimit;\n    try {\n      const result = await fileInfo(this.id, this.ownerToken);\n      this.dtotal = result.dtotal;\n      this.dlimit = result.dlimit;\n    } catch (e) {\n      if (e.message === '404') {\n        this.dtotal = this.dlimit;\n      }\n      // ignore other errors\n    }\n    return oldTotal !== this.dtotal || oldLimit !== this.dlimit;\n  }\n\n  toJSON() {\n    return {\n      id: this.id,\n      url: this.url,\n      name: this.name,\n      size: this.size,\n      manifest: this.manifest,\n      time: this.time,\n      speed: this.speed,\n      createdAt: this.createdAt,\n      expiresAt: this.expiresAt,\n      secretKey: arrayToB64(this.keychain.rawSecret),\n      ownerToken: this.ownerToken,\n      dlimit: this.dlimit,\n      dtotal: this.dtotal,\n      hasPassword: this.hasPassword,\n      timeLimit: this.timeLimit\n    };\n  }\n}\n"
  },
  {
    "path": "app/pasteManager.js",
    "content": "function getString(item) {\n  return new Promise(resolve => {\n    item.getAsString(resolve);\n  });\n}\n\nexport default function(state, emitter) {\n  window.addEventListener('paste', async event => {\n    if (state.route !== '/' || state.uploading) return;\n    if (['password', 'text', 'email'].includes(event.target.type)) return;\n\n    const items = Array.from(event.clipboardData.items);\n    const transferFiles = items.filter(item => item.kind === 'file');\n    const strings = items.filter(item => item.kind === 'string');\n    if (transferFiles.length) {\n      const promises = transferFiles.map(async (f, i) => {\n        const blob = f.getAsFile();\n        if (!blob) {\n          return null;\n        }\n        const name = await getString(strings[i]);\n        const file = new File([blob], name, { type: blob.type });\n        return file;\n      });\n      const files = (await Promise.all(promises)).filter(f => !!f);\n      if (files.length) {\n        emitter.emit('addFiles', { files });\n      }\n    } else if (strings.length) {\n      strings[0].getAsString(s => {\n        const file = new File([s], 'pasted.txt', { type: 'text/plain' });\n        emitter.emit('addFiles', { files: [file] });\n      });\n    }\n  });\n}\n"
  },
  {
    "path": "app/readme.md",
    "content": "# Application Code\n\n`app/` contains the browser code that gets bundled into `app.[hash].js`. It's got all the logic, crypto, and UI. All of it gets used in the browser, and some of it by the server for server side rendering.\n\nThe main entrypoint for the browser is [main.js](./main.js) and on the server [routes.js](./routes.js) is imported by [/server/routes/pages.js](../server/routes/pages.js)\n\n- `pages` contains display logic an markup for pages\n- `routes` contains route definitions and logic\n- `templates` contains ui elements smaller than pages\n"
  },
  {
    "path": "app/routes.js",
    "content": "const choo = require('choo');\nconst download = require('./ui/download');\nconst body = require('./ui/body');\n\nmodule.exports = function(app = choo({ hash: true })) {\n  app.route('/', body(require('./ui/home')));\n  app.route('/download/:id', body(download));\n  app.route('/download/:id/:key', body(download));\n  app.route('/unsupported/:reason', body(require('./ui/unsupported')));\n  app.route('/error', body(require('./ui/error')));\n  app.route('/blank', body(require('./ui/blank')));\n  app.route('/oauth', function(state, emit) {\n    emit('authenticate', state.query.code, state.query.state);\n  });\n  app.route('/login', function(state, emit) {\n    emit('replaceState', '/');\n    setTimeout(() => emit('render'));\n  });\n  app.route('/report', body(require('./ui/report')));\n  app.route('*', body(require('./ui/notFound')));\n  return app;\n};\n"
  },
  {
    "path": "app/serviceWorker.js",
    "content": "import assets from '../common/assets';\nimport { version } from '../package.json';\nimport Keychain from './keychain';\nimport { downloadStream } from './api';\nimport { transformStream } from './streams';\nimport Zip from './zip';\nimport contentDisposition from 'content-disposition';\n\nlet noSave = false;\nconst map = new Map();\nconst IMAGES = /.*\\.(png|svg|jpg)$/;\nconst VERSIONED_ASSET = /\\.[A-Fa-f0-9]{8}\\.(js|css|png|svg|jpg)(#\\w+)?$/;\nconst DOWNLOAD_URL = /\\/api\\/download\\/([A-Fa-f0-9]{4,})/;\nconst FONT = /\\.woff2?$/;\n\nself.addEventListener('install', () => {\n  self.skipWaiting();\n});\n\nself.addEventListener('activate', event => {\n  event.waitUntil(self.clients.claim().then(precache));\n});\n\nasync function decryptStream(id) {\n  const file = map.get(id);\n  if (!file) {\n    return new Response(null, { status: 400 });\n  }\n  try {\n    let size = file.size;\n    let type = file.type;\n    const keychain = new Keychain(file.key, file.nonce);\n    if (file.requiresPassword) {\n      keychain.setPassword(file.password, file.url);\n    }\n\n    file.download = downloadStream(id, file.dlToken);\n\n    const body = await file.download.result;\n\n    const decrypted = keychain.decryptStream(body);\n\n    let zipStream = null;\n    if (file.type === 'send-archive') {\n      const zip = new Zip(file.manifest, decrypted);\n      zipStream = zip.stream;\n      type = 'application/zip';\n      size = zip.size;\n    }\n    const responseStream = transformStream(\n      zipStream || decrypted,\n      {\n        transform(chunk, controller) {\n          file.progress += chunk.length;\n          controller.enqueue(chunk);\n        }\n      },\n      function oncancel() {\n        // NOTE: cancel doesn't currently fire on chrome\n        // https://bugs.chromium.org/p/chromium/issues/detail?id=638494\n        file.download.cancel();\n        map.delete(id);\n      }\n    );\n\n    const headers = {\n      'Content-Disposition': contentDisposition(file.filename),\n      'Content-Type': type,\n      'Content-Length': size\n    };\n    return new Response(responseStream, { headers });\n  } catch (e) {\n    if (noSave) {\n      return new Response(null, { status: e.message });\n    }\n\n    return new Response(null, {\n      status: 302,\n      headers: {\n        Location: `/download/${id}/#${file.key}`\n      }\n    });\n  }\n}\n\nasync function precache() {\n  try {\n    await cleanCache();\n    const cache = await caches.open(version);\n    const images = assets.match(IMAGES);\n    await cache.addAll(images);\n  } catch (e) {\n    console.error(e);\n    // cache will get populated on demand\n  }\n}\n\nasync function cleanCache() {\n  const oldCaches = await caches.keys();\n  for (const c of oldCaches) {\n    if (c !== version) {\n      await caches.delete(c);\n    }\n  }\n}\n\nfunction cacheable(url) {\n  return VERSIONED_ASSET.test(url) || FONT.test(url);\n}\n\nasync function cachedOrFetched(req) {\n  const cache = await caches.open(version);\n  const cached = await cache.match(req);\n  if (cached) {\n    return cached;\n  }\n  const fetched = await fetch(req);\n  if (fetched.ok && cacheable(req.url)) {\n    cache.put(req, fetched.clone());\n  }\n  return fetched;\n}\n\nself.onfetch = event => {\n  const req = event.request;\n  if (req.method !== 'GET') return;\n  const url = new URL(req.url);\n  const dlmatch = DOWNLOAD_URL.exec(url.pathname);\n  if (dlmatch) {\n    event.respondWith(decryptStream(dlmatch[1]));\n  } else if (cacheable(url.pathname)) {\n    event.respondWith(cachedOrFetched(req));\n  }\n};\n\nself.onmessage = event => {\n  if (event.data.request === 'init') {\n    noSave = event.data.noSave;\n    const info = {\n      key: event.data.key,\n      nonce: event.data.nonce,\n      filename: event.data.filename,\n      requiresPassword: event.data.requiresPassword,\n      password: event.data.password,\n      url: event.data.url,\n      type: event.data.type,\n      manifest: event.data.manifest,\n      size: event.data.size,\n      dlToken: event.data.dlToken,\n      progress: 0\n    };\n    map.set(event.data.id, info);\n\n    event.ports[0].postMessage('file info received');\n  } else if (event.data.request === 'progress') {\n    const file = map.get(event.data.id);\n    if (!file) {\n      event.ports[0].postMessage({ error: 'cancelled' });\n    } else {\n      if (file.progress === file.size) {\n        map.delete(event.data.id);\n      }\n      event.ports[0].postMessage({ progress: file.progress });\n    }\n  } else if (event.data.request === 'cancel') {\n    const file = map.get(event.data.id);\n    if (file) {\n      if (file.download) {\n        file.download.cancel();\n      }\n      map.delete(event.data.id);\n    }\n    event.ports[0].postMessage('download cancelled');\n  }\n};\n"
  },
  {
    "path": "app/storage.js",
    "content": "import { arrayToB64, isFile } from './utils';\nimport OwnedFile from './ownedFile';\n\nclass Mem {\n  constructor() {\n    this.items = new Map();\n  }\n\n  get length() {\n    return this.items.size;\n  }\n\n  getItem(key) {\n    return this.items.get(key);\n  }\n\n  setItem(key, value) {\n    return this.items.set(key, value);\n  }\n\n  removeItem(key) {\n    return this.items.delete(key);\n  }\n\n  key(i) {\n    return this.items.keys()[i];\n  }\n}\n\nclass Storage {\n  constructor() {\n    try {\n      this.engine = localStorage || new Mem();\n    } catch (e) {\n      this.engine = new Mem();\n    }\n    this._files = this.loadFiles();\n    this.pruneTokens();\n  }\n\n  loadFiles() {\n    const fs = new Map();\n    for (let i = 0; i < this.engine.length; i++) {\n      const k = this.engine.key(i);\n      if (isFile(k)) {\n        try {\n          const f = new OwnedFile(JSON.parse(this.engine.getItem(k)));\n          if (!f.id) {\n            f.id = f.fileId;\n          }\n\n          fs.set(f.id, f);\n        } catch (err) {\n          // obviously you're not a golfer\n          this.engine.removeItem(k);\n        }\n      }\n    }\n    return fs;\n  }\n\n  get id() {\n    let id = this.engine.getItem('device_id');\n    if (!id) {\n      id = arrayToB64(crypto.getRandomValues(new Uint8Array(16)));\n      this.engine.setItem('device_id', id);\n    }\n    return id;\n  }\n\n  get totalDownloads() {\n    return Number(this.engine.getItem('totalDownloads'));\n  }\n  set totalDownloads(n) {\n    this.engine.setItem('totalDownloads', n);\n  }\n  get totalUploads() {\n    return Number(this.engine.getItem('totalUploads'));\n  }\n  set totalUploads(n) {\n    this.engine.setItem('totalUploads', n);\n  }\n  get referrer() {\n    return this.engine.getItem('referrer');\n  }\n  set referrer(str) {\n    this.engine.setItem('referrer', str);\n  }\n  get enrolled() {\n    return JSON.parse(this.engine.getItem('ab_experiments') || '{}');\n  }\n\n  enroll(id, variant) {\n    const enrolled = {};\n    enrolled[id] = variant;\n    this.engine.setItem('ab_experiments', JSON.stringify(enrolled));\n  }\n\n  get files() {\n    return Array.from(this._files.values()).sort(\n      (a, b) => a.createdAt - b.createdAt\n    );\n  }\n\n  get user() {\n    try {\n      return JSON.parse(this.engine.getItem('user'));\n    } catch (e) {\n      return null;\n    }\n  }\n\n  set user(info) {\n    return this.engine.setItem('user', JSON.stringify(info));\n  }\n\n  getFileById(id) {\n    return this._files.get(id);\n  }\n\n  get(id) {\n    return this.engine.getItem(id);\n  }\n\n  set(id, value) {\n    return this.engine.setItem(id, value);\n  }\n\n  remove(property) {\n    if (isFile(property)) {\n      this._files.delete(property);\n    }\n    this.engine.removeItem(property);\n  }\n\n  addFile(file) {\n    this._files.set(file.id, file);\n    this.writeFile(file);\n  }\n\n  writeFile(file) {\n    this.engine.setItem(file.id, JSON.stringify(file));\n  }\n\n  writeFiles() {\n    this._files.forEach(f => this.writeFile(f));\n  }\n\n  clearLocalFiles() {\n    this._files.forEach(f => this.engine.removeItem(f.id));\n    this._files = new Map();\n  }\n\n  async merge(files = []) {\n    let incoming = false;\n    let outgoing = false;\n    let downloadCount = false;\n    for (const f of files) {\n      if (!this.getFileById(f.id)) {\n        this.addFile(new OwnedFile(f));\n        incoming = true;\n      }\n    }\n    const workingFiles = this.files.slice();\n    for (const f of workingFiles) {\n      const cc = await f.updateDownloadCount();\n      if (cc) {\n        await this.writeFile(f);\n      }\n      downloadCount = downloadCount || cc;\n      outgoing = outgoing || f.expired;\n      if (f.expired) {\n        this.remove(f.id);\n      } else if (!files.find(x => x.id === f.id)) {\n        outgoing = true;\n      }\n    }\n    return {\n      incoming,\n      outgoing,\n      downloadCount\n    };\n  }\n\n  setDownloadToken(id, token) {\n    let otherTokens = {};\n    try {\n      otherTokens = JSON.parse(this.get('dlTokens'));\n    } catch (e) {\n      //\n    }\n    if (token) {\n      const record = { token, ts: Date.now() };\n      this.set('dlTokens', JSON.stringify({ ...otherTokens, [id]: record }));\n    } else {\n      this.set('dlTokens', JSON.stringify({ ...otherTokens, [id]: undefined }));\n    }\n  }\n\n  getDownloadToken(id) {\n    try {\n      return JSON.parse(this.get('dlTokens'))[id].token;\n    } catch (e) {\n      return undefined;\n    }\n  }\n\n  pruneTokens() {\n    try {\n      const now = Date.now();\n      const tokens = JSON.parse(this.get('dlTokens'));\n      const keep = {};\n      for (const id of Object.keys(tokens)) {\n        const t = tokens[id];\n        if (t.ts > now - 7 * 86400 * 1000) {\n          keep[id] = t;\n        }\n      }\n      if (Object.keys(keep).length < Object.keys(tokens).length) {\n        this.set('dlTokens', JSON.stringify(keep));\n      }\n    } catch (e) {\n      console.error(e);\n    }\n  }\n}\n\nexport default new Storage();\n"
  },
  {
    "path": "app/streams.js",
    "content": "/* global TransformStream */\n\nexport function transformStream(readable, transformer, oncancel) {\n  try {\n    return readable.pipeThrough(new TransformStream(transformer));\n  } catch (e) {\n    const reader = readable.getReader();\n    return new ReadableStream({\n      start(controller) {\n        if (transformer.start) {\n          return transformer.start(controller);\n        }\n      },\n      async pull(controller) {\n        let enqueued = false;\n        const wrappedController = {\n          enqueue(d) {\n            enqueued = true;\n            controller.enqueue(d);\n          }\n        };\n        while (!enqueued) {\n          const data = await reader.read();\n          if (data.done) {\n            if (transformer.flush) {\n              await transformer.flush(controller);\n            }\n            return controller.close();\n          }\n          await transformer.transform(data.value, wrappedController);\n        }\n      },\n      cancel(reason) {\n        readable.cancel(reason);\n        if (oncancel) {\n          oncancel(reason);\n        }\n      }\n    });\n  }\n}\n\nclass BlobStreamController {\n  constructor(blob, size) {\n    this.blob = blob;\n    this.index = 0;\n    this.chunkSize = size || 1024 * 64;\n  }\n\n  pull(controller) {\n    return new Promise((resolve, reject) => {\n      const bytesLeft = this.blob.size - this.index;\n      if (bytesLeft <= 0) {\n        controller.close();\n        return resolve();\n      }\n      const size = Math.min(this.chunkSize, bytesLeft);\n      const slice = this.blob.slice(this.index, this.index + size);\n      const reader = new FileReader();\n      reader.onload = () => {\n        controller.enqueue(new Uint8Array(reader.result));\n        resolve();\n      };\n      reader.onerror = reject;\n      reader.readAsArrayBuffer(slice);\n      this.index += size;\n    });\n  }\n}\n\nexport function blobStream(blob, size) {\n  return new ReadableStream(new BlobStreamController(blob, size));\n}\n\nclass ConcatStreamController {\n  constructor(streams) {\n    this.streams = streams;\n    this.index = 0;\n    this.reader = null;\n    this.nextReader();\n  }\n\n  nextReader() {\n    const next = this.streams[this.index++];\n    this.reader = next && next.getReader();\n  }\n\n  async pull(controller) {\n    if (!this.reader) {\n      return controller.close();\n    }\n    const data = await this.reader.read();\n    if (data.done) {\n      this.nextReader();\n      return this.pull(controller);\n    }\n    controller.enqueue(data.value);\n  }\n}\n\nexport function concatStream(streams) {\n  return new ReadableStream(new ConcatStreamController(streams));\n}\n"
  },
  {
    "path": "app/ui/account.js",
    "content": "const html = require('choo/html');\nconst Component = require('choo/component');\n\nclass Account extends Component {\n  constructor(name, state, emit) {\n    super(name);\n    this.state = state;\n    this.emit = emit;\n    this.enabled = state.capabilities.account;\n    this.local = state.components[name] = {};\n    this.buttonClass = '';\n    this.setLocal();\n  }\n\n  avatarClick(event) {\n    event.preventDefault();\n    const menu = document.getElementById('accountMenu');\n    menu.classList.toggle('invisible');\n    menu.focus();\n  }\n\n  hideMenu(event) {\n    event.stopPropagation();\n    const menu = document.getElementById('accountMenu');\n    menu.classList.add('invisible');\n  }\n\n  login(event) {\n    event.preventDefault();\n    this.emit('signup-cta', 'button');\n  }\n\n  logout(event) {\n    event.preventDefault();\n    this.emit('logout');\n  }\n\n  changed() {\n    return this.local.loggedIn !== this.state.user.loggedIn;\n  }\n\n  setLocal() {\n    const changed = this.changed();\n    if (changed) {\n      this.local.loggedIn = this.state.user.loggedIn;\n    }\n    return changed;\n  }\n\n  update() {\n    return this.setLocal();\n  }\n\n  createElement() {\n    if (!this.enabled) {\n      return html`\n        <send-account></send-account>\n      `;\n    }\n    const user = this.state.user;\n    const translate = this.state.translate;\n    this.setLocal();\n    if (user.loginRequired && !this.local.loggedIn) {\n      return html`\n        <send-account></send-account>\n      `;\n    }\n    if (!this.local.loggedIn) {\n      return html`\n        <send-account>\n          <button\n            class=\"px-4 py-2 md:px-8 md:py-4 focus:outline signin border-2 link-blue border-blue-60 hover:border-blue-70 dark:border-blue-40 dark:hover:border-blue-50\"\n            onclick=\"${e => this.login(e)}\"\n            title=\"${translate('signInOnlyButton')}\"\n          >\n            ${translate('signInOnlyButton')}\n          </button>\n        </send-account>\n      `;\n    }\n    return html`\n      <send-account class=\"relative h-8\">\n        <input\n          type=\"image\"\n          alt=\"${user.email}\"\n          class=\"w-8 h-8 rounded-full border text-blue-50 md:text-white focus:outline\"\n          src=\"${user.avatar}\"\n          onclick=\"${e => this.avatarClick(e)}\"\n        />\n        <ul\n          id=\"accountMenu\"\n          class=\"invisible absolute top-0 right-0 mt-10 pt-2 pb-2 bg-white shadow-md whitespace-no-wrap outline-none z-50 dark:bg-grey-80\"\n          onblur=\"${e => this.hideMenu(e)}\"\n        >\n          <li class=\"p-2 text-grey-60 dark:text-grey-50\">${user.email}</li>\n          <li>\n            <button\n              class=\"block w-full text-left px-4 py-2 text-grey-80 dark:text-grey-30 hover:bg-blue-50 hover:text-white cursor-pointer focus:outline\"\n              onclick=\"${e => this.logout(e)}\"\n              title=\"${translate('signOut')}\"\n            >\n              ${translate('signOut')}\n            </button>\n          </li>\n        </ul>\n      </send-account>\n    `;\n  }\n}\n\nmodule.exports = Account;\n"
  },
  {
    "path": "app/ui/archiveTile.js",
    "content": "/* global Android */\n\nconst html = require('choo/html');\nconst raw = require('choo/html/raw');\nconst assets = require('../../common/assets');\nconst {\n  bytes,\n  copyToClipboard,\n  list,\n  percent,\n  platform,\n  timeLeft\n} = require('../utils');\nconst expiryOptions = require('./expiryOptions');\n\nfunction expiryInfo(translate, archive) {\n  const l10n = timeLeft(archive.expiresAt - Date.now());\n  return raw(\n    translate('archiveExpiryInfo', {\n      downloadCount: translate('downloadCount', {\n        num: archive.dlimit - archive.dtotal\n      }),\n      timespan: translate(l10n.id, l10n)\n    })\n  );\n}\n\nfunction password(state) {\n  const MAX_LENGTH = 32;\n\n  return html`\n    <div class=\"mb-2 px-1\">\n      <input\n        id=\"autocomplete-decoy\"\n        class=\"hidden\"\n        type=\"password\"\n        value=\"lol\"\n      />\n      <div class=\"checkbox inline-block mr-3\">\n        <input\n          id=\"add-password\"\n          type=\"checkbox\"\n          ${state.archive.password ? 'checked' : ''}\n          autocomplete=\"off\"\n          onchange=\"${togglePasswordInput}\"\n        />\n        <label for=\"add-password\">\n          ${state.translate('addPassword')}\n        </label>\n      </div>\n      <input\n        id=\"password-input\"\n        class=\"${state.archive.password\n          ? ''\n          : 'invisible'} border rounded focus:border-blue-60 leading-normal my-1 py-1 px-2 h-8 dark:bg-grey-80\"\n        autocomplete=\"off\"\n        maxlength=\"${MAX_LENGTH}\"\n        type=\"password\"\n        oninput=\"${inputChanged}\"\n        onfocus=\"${focused}\"\n        placeholder=\"${state.translate('unlockInputPlaceholder')}\"\n        value=\"${state.archive.password || ''}\"\n      />\n      <label\n        id=\"password-msg\"\n        for=\"password-input\"\n        class=\"block text-xs text-grey-70\"\n      ></label>\n    </div>\n  `;\n\n  function togglePasswordInput(event) {\n    event.stopPropagation();\n    const checked = event.target.checked;\n    const input = document.getElementById('password-input');\n    if (checked) {\n      input.classList.remove('invisible');\n      input.focus();\n    } else {\n      input.classList.add('invisible');\n      input.value = '';\n      document.getElementById('password-msg').textContent = '';\n      state.archive.password = null;\n    }\n  }\n\n  function inputChanged() {\n    const passwordInput = document.getElementById('password-input');\n    const pwdmsg = document.getElementById('password-msg');\n    const password = passwordInput.value;\n    const length = password.length;\n\n    if (length === MAX_LENGTH) {\n      pwdmsg.textContent = state.translate('maxPasswordLength', {\n        length: MAX_LENGTH\n      });\n    } else {\n      pwdmsg.textContent = '';\n    }\n    state.archive.password = password;\n  }\n\n  function focused(event) {\n    event.preventDefault();\n    const el = document.getElementById('password-input');\n    if (el.placeholder !== state.translate('unlockInputPlaceholder')) {\n      el.placeholder = '';\n    }\n  }\n}\n\nfunction fileInfo(file, action) {\n  return html`\n    <send-file class=\"flex flex-row items-center p-3 w-full\">\n      <svg class=\"h-8 w-8 text-white dark:text-grey-90\">\n        <use xlink:href=\"${assets.get('blue_file.svg')}#icon\"/>\n      </svg>\n      <p class=\"ml-4 w-full\">\n        <h1 class=\"text-base font-medium word-break-all\">${file.name}</h1>\n        <div class=\"text-sm font-normal opacity-75 pt-1\">${bytes(\n          file.size\n        )}</div>\n      </p>\n      ${action}\n    </send-file>`;\n}\n\nfunction archiveInfo(archive, action) {\n  return html`\n    <p class=\"w-full flex items-center\">\n      <svg class=\"h-8 w-6 mr-3 flex-shrink-0 text-white dark:text-grey-90\">\n        <use xlink:href=\"${assets.get('blue_file.svg')}#icon\"/>\n      </svg>\n      <p class=\"flex-grow\">\n        <h1 class=\"text-base font-medium word-break-all\">${archive.name}</h1>\n        <div class=\"text-sm font-normal opacity-75 pt-1\">${bytes(\n          archive.size\n        )}</div>\n      </p>\n      ${action}\n    </p>`;\n}\n\nfunction archiveDetails(translate, archive) {\n  if (archive.manifest.files.length > 1) {\n    return html`\n      <details\n        class=\"w-full pb-1\"\n        ${archive.open ? 'open' : ''}\n        ontoggle=\"${toggled}\"\n      >\n        <summary\n          class=\"flex items-center link-blue text-sm cursor-pointer outline-none\"\n        >\n          <svg\n            class=\"fill-current w-4 h-4 mr-1\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            viewBox=\"0 0 20 20\"\n          >\n            <path\n              d=\"M12.95 10.707l.707-.707L8 4.343 6.586 5.757 10.828 10l-4.242 4.243L8 15.657l4.95-4.95z\"\n            />\n          </svg>\n          ${translate('fileCount', {\n            num: archive.manifest.files.length\n          })}\n        </summary>\n        ${list(archive.manifest.files.map(f => fileInfo(f)))}\n      </details>\n    `;\n  }\n  function toggled(event) {\n    event.stopPropagation();\n    archive.open = event.target.open;\n  }\n}\n\nmodule.exports = function(state, emit, archive) {\n  const copyOrShare =\n    state.capabilities.share || platform() === 'android'\n      ? html`\n          <button\n            class=\"link-blue self-end flex items-start\"\n            onclick=${share}\n            title=\"Share link\"\n          >\n            <svg class=\"h-4 w-4 mr-2\">\n              <use xlink:href=\"${assets.get('share-24.svg')}#icon\" />\n            </svg>\n            Share link\n          </button>\n        `\n      : html`\n          <button\n            class=\"link-blue focus:outline self-end flex items-center\"\n            onclick=${copy}\n            title=\"${state.translate('copyLinkButton')}\"\n          >\n            <svg class=\"h-4 w-4 mr-2\">\n              <use xlink:href=\"${assets.get('copy-16.svg')}#icon\" />\n            </svg>\n            ${state.translate('copyLinkButton')}\n          </button>\n        `;\n  const dl =\n    platform() === 'web'\n      ? html`\n          <a\n            class=\"flex items-baseline link-blue\"\n            href=\"${archive.url}\"\n            title=\"${state.translate('downloadButtonLabel')}\"\n            tabindex=\"0\"\n          >\n            <svg class=\"h-4 w-3 mr-2\">\n              <use xlink:href=\"${assets.get('dl.svg')}#icon\" />\n            </svg>\n            ${state.translate('downloadButtonLabel')}\n          </a>\n        `\n      : html`\n          <div></div>\n        `;\n  return html`\n    <send-archive\n      id=\"archive-${archive.id}\"\n      class=\"flex flex-col items-start rounded shadow-light bg-white p-4 w-full dark:bg-grey-90 dark:border dark:border-grey-70\"\n    >\n      ${archiveInfo(\n        archive,\n        html`\n          <input\n            type=\"image\"\n            class=\"self-start flex-shrink-0 text-white hover:opacity-75 focus:outline\"\n            alt=\"${state.translate('deleteButtonHover')}\"\n            title=\"${state.translate('deleteButtonHover')}\"\n            src=\"${assets.get('close-16.svg')}\"\n            onclick=${del}\n          />\n        `\n      )}\n      <div class=\"text-sm opacity-75 w-full mt-2 mb-2\">\n        ${expiryInfo(state.translate, archive)}\n      </div>\n      ${archiveDetails(state.translate, archive)}\n      <hr class=\"w-full border-t my-4 dark:border-grey-70\" />\n      <div class=\"flex justify-between w-full\">\n        ${dl} ${copyOrShare}\n      </div>\n    </send-archive>\n  `;\n\n  function copy(event) {\n    event.stopPropagation();\n    copyToClipboard(archive.url);\n    const text = event.target.lastChild;\n    text.textContent = state.translate('copiedUrl');\n    setTimeout(\n      () => (text.textContent = state.translate('copyLinkButton')),\n      1000\n    );\n  }\n\n  function del(event) {\n    event.stopPropagation();\n    emit('delete', archive);\n  }\n\n  async function share(event) {\n    event.stopPropagation();\n    if (platform() === 'android') {\n      Android.shareUrl(archive.url);\n    } else {\n      try {\n        await navigator.share({\n          title: state.translate('-send-brand'),\n          text: `Download \"${archive.name}\" with Firefox Send: simple, safe file sharing`,\n          //state.translate('shareMessage', { name }),\n          url: archive.url\n        });\n      } catch (e) {\n        // ignore\n      }\n    }\n  }\n};\n\nmodule.exports.wip = function(state, emit) {\n  return html`\n    <send-upload-area\n      class=\"flex flex-col bg-white h-full w-full dark:bg-grey-90\"\n      id=\"wip\"\n    >\n      ${list(\n        Array.from(state.archive.files)\n          .reverse()\n          .map(f =>\n            fileInfo(f, remove(f, state.translate('deleteButtonHover')))\n          ),\n        'flex-shrink bg-grey-10 rounded-t overflow-y-auto px-6 py-4 md:h-full md:max-h-half-screen dark:bg-black',\n        'bg-white px-2 my-2 shadow-light rounded dark:bg-grey-90 dark:border dark:border-grey-80'\n      )}\n      <div\n        class=\"flex-shrink-0 flex-grow flex items-end p-4 bg-grey-10 rounded-b mb-1 font-medium dark:bg-grey-90\"\n      >\n        <input\n          id=\"file-upload\"\n          class=\"opacity-0 w-0 h-0 appearance-none absolute overflow-hidden\"\n          type=\"file\"\n          multiple\n          onfocus=\"${focus}\"\n          onblur=\"${blur}\"\n          onchange=\"${add}\"\n        />\n        <div\n          for=\"file-upload\"\n          class=\"flex flex-row items-center justify-between w-full p-2\"\n        >\n          <label\n            for=\"file-upload\"\n            class=\"flex items-center cursor-pointer\"\n            title=\"${state.translate('addFilesButton')}\"\n          >\n            <svg class=\"w-6 h-6 mr-2 link-blue\">\n              <use xlink:href=\"${assets.get('addfiles.svg')}#plus\" />\n            </svg>\n            ${state.translate('addFilesButton')}\n          </label>\n          <div class=\"font-normal text-sm text-grey-70 dark:text-grey-40\">\n            ${state.translate('totalSize', {\n              size: bytes(state.archive.size)\n            })}\n          </div>\n        </div>\n      </div>\n      ${expiryOptions(state, emit)} ${password(state, emit)}\n      <button\n        id=\"upload-btn\"\n        class=\"btn rounded-lg flex-shrink-0 focus:outline\"\n        title=\"${state.translate('uploadButton')}\"\n        onclick=\"${upload}\"\n      >\n        ${state.translate('uploadButton')}\n      </button>\n    </send-upload-area>\n  `;\n\n  function focus(event) {\n    event.target.nextElementSibling.firstElementChild.classList.add('outline');\n  }\n\n  function blur(event) {\n    event.target.nextElementSibling.firstElementChild.classList.remove(\n      'outline'\n    );\n  }\n\n  function upload(event) {\n    window.scrollTo(0, 0);\n    event.preventDefault();\n    event.target.disabled = true;\n    if (!state.uploading) {\n      emit('upload');\n    }\n  }\n\n  function add(event) {\n    event.preventDefault();\n    const newFiles = Array.from(event.target.files);\n\n    emit('addFiles', { files: newFiles });\n    setTimeout(() => {\n      document\n        .querySelector('#wip > ul > li:first-child')\n        .scrollIntoView({ block: 'center' });\n    });\n  }\n\n  function remove(file, desc) {\n    return html`\n      <input\n        type=\"image\"\n        class=\"self-center text-white ml-4 h-4 hover:opacity-75 focus:outline\"\n        alt=\"${desc}\"\n        title=\"${desc}\"\n        src=\"${assets.get('close-16.svg')}\"\n        onclick=\"${del}\"\n      />\n    `;\n    function del(event) {\n      event.stopPropagation();\n      emit('removeUpload', file);\n    }\n  }\n};\n\nmodule.exports.uploading = function(state, emit) {\n  const progress = state.transfer.progressRatio;\n  const progressPercent = percent(progress);\n  const archive = state.archive;\n  return html`\n    <send-upload-area\n      id=\"${archive.id}\"\n      class=\"flex flex-col items-start rounded shadow-light bg-white p-4 w-full dark:bg-grey-90\"\n    >\n      ${archiveInfo(archive)}\n      <div class=\"text-xs opacity-75 w-full mt-2 mb-2\">\n        ${expiryInfo(state.translate, {\n          dlimit: state.archive.dlimit,\n          dtotal: 0,\n          expiresAt: Date.now() + 500 + state.archive.timeLimit * 1000\n        })}\n      </div>\n      <div class=\"link-blue text-sm font-medium mt-2\">\n        ${progressPercent}\n      </div>\n      <progress class=\"my-3\" value=\"${progress}\">${progressPercent}</progress>\n      <button\n        class=\"link-blue self-end font-medium\"\n        onclick=${cancel}\n        title=\"${state.translate('deletePopupCancel')}\"\n      >\n        ${state.translate('deletePopupCancel')}\n      </button>\n    </send-upload-area>\n  `;\n\n  function cancel(event) {\n    event.stopPropagation();\n    event.target.disabled = true;\n    emit('cancel');\n  }\n};\n\nmodule.exports.empty = function(state, emit) {\n  const upsell =\n    state.user.loggedIn || !state.capabilities.account\n      ? ''\n      : html`\n          <button\n            class=\"center font-medium text-sm link-blue mt-4 mb-2\"\n            onclick=\"${event => {\n              event.stopPropagation();\n              emit('signup-cta', 'drop');\n            }}\"\n          >\n            ${state.translate('signInSizeBump', {\n              size: bytes(state.LIMITS.MAX_FILE_SIZE)\n            })}\n          </button>\n        `;\n  return html`\n    <send-upload-area\n      class=\"flex flex-col items-center justify-center border-2 border-dashed border-grey-transparent rounded px-6 py-16 h-full w-full dark:border-grey-60\"\n      onclick=\"${e => {\n        if (e.target.tagName !== 'LABEL') {\n          document.getElementById('file-upload').click();\n        }\n      }}\"\n    >\n      <svg class=\"w-10 h-10 link-blue\">\n        <use xlink:href=\"/${assets.get('addfiles.svg')}#plus\" />\n      </svg>\n      <div class=\"pt-6 pb-2 text-center text-lg font-bold tracking-wide\">\n        ${state.translate('dragAndDropFiles')}\n      </div>\n      <div class=\"pb-6 text-center text-base\">\n        ${state.translate('orClickWithSize', {\n          size: bytes(state.user.maxSize)\n        })}\n      </div>\n      <input\n        id=\"file-upload\"\n        class=\"opacity-0 w-0 h-0 appearance-none absolute overflow-hidden\"\n        type=\"file\"\n        multiple\n        onfocus=\"${focus}\"\n        onblur=\"${blur}\"\n        onchange=\"${add}\"\n        onclick=\"${e => e.stopPropagation()}\"\n      />\n      <label\n        for=\"file-upload\"\n        role=\"button\"\n        class=\"btn rounded-lg flex items-center mt-4\"\n        title=\"${state.translate('addFilesButton', {\n          size: bytes(state.user.maxSize)\n        })}\"\n      >\n        ${state.translate('addFilesButton')}\n      </label>\n      <p\n        class=\"font-normal text-sm text-grey-50 dark:text-grey-40 my-6 mx-12 text-center max-w-sm leading-loose\"\n      >\n        ${state.translate('trustWarningMessage')}\n      </p>\n      ${upsell}\n    </send-upload-area>\n  `;\n\n  function focus(event) {\n    event.target.nextElementSibling.classList.add('bg-blue-70', 'outline');\n  }\n\n  function blur(event) {\n    event.target.nextElementSibling.classList.remove('bg-blue-70', 'outline');\n  }\n\n  function add(event) {\n    event.preventDefault();\n    const newFiles = Array.from(event.target.files);\n\n    emit('addFiles', { files: newFiles });\n  }\n};\n\nmodule.exports.preview = function(state, emit) {\n  const archive = state.fileInfo;\n  if (archive.open === undefined) {\n    archive.open = true;\n  }\n  const single = archive.manifest.files.length === 1;\n  const details = single\n    ? ''\n    : html`\n        <div class=\"mt-4 h-full md:h-48 overflow-y-auto\">\n          ${archiveDetails(state.translate, archive)}\n        </div>\n      `;\n  return html`\n    <send-archive\n      class=\"flex flex-col max-h-full bg-white w-full dark:bg-grey-90\"\n    >\n      <div class=\"border rounded py-3 px-4 dark:border-grey-70\">\n        ${archiveInfo(archive)} ${details}\n      </div>\n      <div class=\"checkbox inline-block mt-6 mx-auto\">\n        <input\n          id=\"trust-download\"\n          type=\"checkbox\"\n          autocomplete=\"off\"\n          onchange=\"${toggleDownloadEnabled}\"\n        />\n        <label for=\"trust-download\">\n          ${state.translate('downloadTrustCheckbox', {\n            count: archive.manifest.files.length\n          })}\n        </label>\n      </div>\n      <button\n        id=\"download-btn\"\n        disabled\n        class=\"btn rounded-lg mt-4 w-full flex-shrink-0 focus:outline\"\n        title=\"${state.translate('downloadButtonLabel')}\"\n        onclick=${download}\n      >\n        ${state.translate('downloadButtonLabel')}\n      </button>\n    </send-archive>\n  `;\n\n  function toggleDownloadEnabled(event) {\n    event.stopPropagation();\n    const checked = event.target.checked;\n    const btn = document.getElementById('download-btn');\n    btn.disabled = !checked;\n  }\n\n  function download(event) {\n    event.preventDefault();\n    event.target.disabled = true;\n    emit('download', archive);\n  }\n};\n\nmodule.exports.downloading = function(state) {\n  const archive = state.fileInfo;\n  const progress = state.transfer.progressRatio;\n  const progressPercent = percent(progress);\n  return html`\n    <send-archive\n      class=\"flex flex-col bg-white rounded shadow-light p-4 w-full max-w-sm md:w-128 dark:bg-grey-90\"\n    >\n      ${archiveInfo(archive)}\n      <div class=\"link-blue text-sm font-medium mt-2\">\n        ${progressPercent}\n      </div>\n      <progress class=\"my-3\" value=\"${progress}\">${progressPercent}</progress>\n    </send-archive>\n  `;\n};\n"
  },
  {
    "path": "app/ui/blank.js",
    "content": "const html = require('choo/html');\n\nmodule.exports = function() {\n  return html`\n    <main class=\"main\">\n      <section\n        class=\"h-full w-full p-6 md:p-8 md:flex md:flex-row md:rounded-xl md:shadow-big\"\n      >\n        <div class=\"md:mr-6 md:w-1/2 w-full\"></div>\n        <div class=\"md:w-1/2 mt-6 md:mt-0 w-full\"></div>\n      </section>\n    </main>\n  `;\n};\n"
  },
  {
    "path": "app/ui/body.js",
    "content": "const html = require('choo/html');\nconst Header = require('./header');\nconst Footer = require('./footer');\n\nmodule.exports = function body(main) {\n  return function(state, emit) {\n    const b = html`\n      <body\n        class=\"flex flex-col items-center font-sans md:h-screen md:bg-grey-10 dark:bg-black\"\n      >\n        ${state.cache(Header, 'header').render()} ${main(state, emit)}\n        ${state.cache(Footer, 'footer').render()}\n      </body>\n    `;\n    if (state.layout) {\n      // server side only\n      return state.layout(state, b);\n    }\n    return b;\n  };\n};\n"
  },
  {
    "path": "app/ui/copyDialog.js",
    "content": "const html = require('choo/html');\nconst { copyToClipboard } = require('../utils');\n\nmodule.exports = function(name, url) {\n  const dialog = function(state, emit, close) {\n    return html`\n      <send-copy-dialog\n        class=\"flex flex-col items-center text-center p-4 max-w-sm m-auto\"\n      >\n        <h1 class=\"text-3xl font-bold my-4\">\n          ${state.translate('notifyUploadEncryptDone')}\n        </h1>\n        <p class=\"font-normal leading-normal text-grey-80 dark:text-grey-40\">\n          ${state.translate('copyLinkDescription')} <br />\n          <span class=\"word-break-all\">${name}</span>\n        </p>\n        <input\n          type=\"text\"\n          id=\"share-url\"\n          class=\"w-full my-4 border rounded-lg leading-loose h-12 px-2 py-1 dark:bg-grey-80\"\n          value=\"${url}\"\n          readonly=\"true\"\n        />\n        <button\n          class=\"btn rounded-lg w-full flex-shrink-0 focus:outline\"\n          onclick=\"${copy}\"\n          title=\"${state.translate('copyLinkButton')}\"\n        >\n          ${state.translate('copyLinkButton')}\n        </button>\n        <button\n          class=\"link-blue my-4 font-medium cursor-pointer focus:outline\"\n          onclick=\"${close}\"\n          title=\"${state.translate('okButton')}\"\n        >\n          ${state.translate('okButton')}\n        </button>\n      </send-copy-dialog>\n    `;\n\n    function copy(event) {\n      event.stopPropagation();\n      copyToClipboard(url);\n      event.target.textContent = state.translate('copiedUrl');\n      setTimeout(close, 1000);\n    }\n  };\n  dialog.type = 'copy';\n  return dialog;\n};\n"
  },
  {
    "path": "app/ui/download.js",
    "content": "/* global downloadMetadata */\nconst html = require('choo/html');\nconst assets = require('../../common/assets');\nconst archiveTile = require('./archiveTile');\nconst modal = require('./modal');\nconst noStreams = require('./noStreams');\nconst notFound = require('./notFound');\nconst downloadPassword = require('./downloadPassword');\nconst downloadCompleted = require('./downloadCompleted');\nconst BIG_SIZE = 1024 * 1024 * 256;\n\nfunction createFileInfo(state) {\n  return {\n    id: state.params.id,\n    secretKey: state.params.key,\n    nonce: downloadMetadata.nonce,\n    requiresPassword: downloadMetadata.pwd\n  };\n}\n\nfunction downloading(state, emit) {\n  return html`\n    <div\n      class=\"flex flex-col w-full h-full items-center md:justify-center md:-mt-8\"\n    >\n      <h1 class=\"text-3xl font-bold mb-4\">\n        ${state.translate('downloadingTitle')}\n      </h1>\n      ${archiveTile.downloading(state, emit)}\n    </div>\n  `;\n}\n\nfunction preview(state, emit) {\n  if (state.fileInfo.flagged) {\n    return html`\n      <div\n        class=\"flex flex-col w-full max-w-md h-full mx-auto items-center justify-center\"\n      >\n        <h1 class=\"text-xl font-bold\">${state.translate('downloadFlagged')}</h1>\n      </div>\n    `;\n  }\n  if (!state.capabilities.streamDownload && state.fileInfo.size > BIG_SIZE) {\n    return noStreams(state, emit);\n  }\n  return html`\n    <div class=\"w-full md:flex md:flex-row items-stretch md:flex-1\">\n      <div\n        class=\"px-2 w-full md:px-0 flex-half md:flex md:flex-col mt-12 md:pr-8 pb-4\"\n      >\n        <h1 class=\"text-3xl font-bold mb-4 text-center md:text-left\">\n          ${state.translate('downloadTitle')}\n        </h1>\n        <p\n          class=\"text-grey-80 leading-normal dark:text-grey-40 mb-4 text-center md:text-left\"\n        >\n          ${state.translate('downloadDescription')}\n        </p>\n        <p\n          class=\"text-grey-80 leading-normal dark:text-grey-40 font-semibold text-center md:mb-8 md:text-left\"\n        >\n          ${state.translate('downloadConfirmDescription')}\n        </p>\n        <img\n          class=\"hidden md:block dl-bg w-full\"\n          src=\"${assets.get('intro.svg')}\"\n        />\n      </div>\n      <div\n        class=\"w-full flex-half flex-half md:flex md:flex-col md:justify-center\"\n      >\n        ${archiveTile.preview(state, emit)}\n        <a href=\"/report\" class=\"link-blue mt-4 text-center block\"\n          >${state.translate('reportFile', {\n            count: state.fileInfo.manifest.files.length\n          })}</a\n        >\n      </div>\n    </div>\n  `;\n}\n\nmodule.exports = function(state, emit) {\n  let content = '';\n  if (!state.fileInfo) {\n    state.fileInfo = createFileInfo(state);\n    if (downloadMetadata.status === 404) {\n      return notFound(state);\n    }\n    if (!state.fileInfo.nonce) {\n      // coming from something like the browser back button\n      return location.reload();\n    }\n  }\n\n  if (state.fileInfo.dead) {\n    return notFound(state);\n  }\n\n  if (!state.transfer && !state.fileInfo.requiresPassword) {\n    emit('getMetadata');\n  }\n\n  if (state.transfer) {\n    switch (state.transfer.state) {\n      case 'downloading':\n      case 'decrypting':\n        content = downloading(state, emit);\n        break;\n      case 'complete':\n        content = downloadCompleted(state);\n        break;\n      default:\n        content = preview(state, emit);\n    }\n  } else if (state.fileInfo.requiresPassword && !state.fileInfo.password) {\n    content = downloadPassword(state, emit);\n  }\n  return html`\n    <main class=\"main\">\n      ${state.modal && modal(state, emit)}\n      <section\n        class=\"relative overflow-hidden h-full w-full p-6 md:p-8 md:rounded-xl md:shadow-big md:flex md:flex-col\"\n      >\n        ${content}\n      </section>\n    </main>\n  `;\n};\n"
  },
  {
    "path": "app/ui/downloadCompleted.js",
    "content": "const html = require('choo/html');\nconst assets = require('../../common/assets');\n\nmodule.exports = function(state) {\n  const btnText = state.user.loggedIn ? 'okButton' : 'sendYourFilesLink';\n  return html`\n    <div\n      id=\"download-complete\"\n      class=\"flex flex-col items-center justify-center h-full w-full bg-white p-2 dark:bg-grey-90\"\n    >\n      <h1 class=\"text-center text-3xl font-bold my-2\">\n        ${state.translate('downloadFinish')}\n      </h1>\n      <img src=\"${assets.get('completed.svg')}\" class=\"my-8 h-48\" />\n      <p\n        class=\"text-grey-80 leading-normal dark:text-grey-40 ${state.user\n          .loggedIn\n          ? 'hidden'\n          : ''}\"\n      >\n        ${state.translate('trySendDescription')}\n      </p>\n      <p class=\"my-5\">\n        <a href=\"/\" class=\"btn rounded-lg flex items-center mt-4\" role=\"button\"\n          >${state.translate(btnText)}</a\n        >\n      </p>\n      <p class=\"\">\n        <a href=\"/report\" class=\"link-blue\">${state.translate('reportFile')}</a>\n      </p>\n    </div>\n  `;\n};\n"
  },
  {
    "path": "app/ui/downloadDialog.js",
    "content": "const html = require('choo/html');\n\nmodule.exports = function() {\n  return function(state, emit, close) {\n    const archive = state.fileInfo;\n    return html`\n      <send-download-dialog\n        class=\"flex flex-col w-full max-w-sm h-full mx-auto items-center justify-center\"\n      >\n        <h1 class=\"text-3xl font-bold mb-4\">\n          ${state.translate('downloadConfirmTitle')}\n        </h1>\n        <p\n          class=\"w-full text-grey-80 text-center leading-normal dark:text-grey-40 mb-8\"\n        >\n          ${state.translate('downloadConfirmDescription')}\n        </p>\n        <div class=\"checkbox inline-block mr-3 mb-8\">\n          <input\n            id=\"trust-download\"\n            type=\"checkbox\"\n            autocomplete=\"off\"\n            onchange=\"${toggleDownloadEnabled}\"\n          />\n          <label for=\"trust-download\">\n            ${state.translate('downloadTrustCheckbox')}\n          </label>\n        </div>\n        <button\n          id=\"download-btn\"\n          disabled\n          class=\"btn rounded-lg w-full flex-shrink-0\"\n          onclick=\"${download}\"\n          title=\"${state.translate('downloadButtonLabel')}\"\n        >\n          ${state.translate('downloadButtonLabel')}\n        </button>\n        <a href=\"/report\" class=\"link-blue mt-8\"\n          >${state.translate('reportFile')}</a\n        >\n      </send-download-dialog>\n    `;\n\n    function toggleDownloadEnabled(event) {\n      event.stopPropagation();\n      const checked = event.target.checked;\n      const btn = document.getElementById('download-btn');\n      btn.disabled = !checked;\n    }\n\n    function download(event) {\n      event.preventDefault();\n      close();\n      event.target.disabled = true;\n      emit('download', archive);\n    }\n  };\n};\n"
  },
  {
    "path": "app/ui/downloadPassword.js",
    "content": "const html = require('choo/html');\n\nmodule.exports = function(state, emit) {\n  const fileInfo = state.fileInfo;\n  const invalid = fileInfo.password === null;\n\n  const div = html`\n    <div\n      class=\"h-full w-full flex flex-col items-center justify-center bg-white py-8 max-w-md mx-auto dark:bg-grey-90\"\n    >\n      <h1 class=\"text-3xl font-bold mb-4\">\n        ${state.translate('downloadTitle')}\n      </h1>\n      <p\n        class=\"w-full mb-4 text-center text-grey-80 dark:text-grey-40 leading-normal\"\n      >\n        ${state.translate('downloadDescription')}\n      </p>\n      <form\n        class=\"flex flex-row flex-no-wrap w-full md:w-4/5\"\n        onsubmit=\"${checkPassword}\"\n        data-no-csrf\n      >\n        <input\n          id=\"autocomplete-decoy\"\n          class=\"hidden\"\n          type=\"password\"\n          value=\"lol\"\n        />\n        <input\n          id=\"password-input\"\n          class=\"w-full border-l border-t border-b rounded-l-lg rounded-r-none ${invalid\n            ? 'border-red dark:border-red-40'\n            : 'border-grey'} leading-loose px-2 py-1 dark:bg-grey-80\"\n          maxlength=\"32\"\n          autocomplete=\"off\"\n          placeholder=\"${state.translate('unlockInputPlaceholder')}\"\n          oninput=\"${inputChanged}\"\n          type=\"password\"\n        />\n        <input\n          type=\"submit\"\n          id=\"password-btn\"\n          class=\"btn rounded-r-lg rounded-l-none ${invalid\n            ? 'bg-red hover:bg-red focus:bg-red dark:bg-red-40'\n            : ''}\"\n          value=\"${state.translate('unlockButtonLabel')}\"\n          title=\"${state.translate('unlockButtonLabel')}\"\n        />\n      </form>\n      <label\n        id=\"password-error\"\n        class=\"${invalid ? '' : 'invisible'} text-red dark:text-red-40 my-4\"\n        for=\"password-input\"\n      >\n        ${state.translate('passwordTryAgain')}\n      </label>\n    </div>\n  `;\n\n  if (!(div instanceof String)) {\n    setTimeout(() => document.getElementById('password-input').focus());\n  }\n\n  function inputChanged(event) {\n    event.stopPropagation();\n    event.preventDefault();\n    const label = document.getElementById('password-error');\n    const input = document.getElementById('password-input');\n    const btn = document.getElementById('password-btn');\n    label.classList.add('invisible');\n    input.classList.remove('border-red', 'dark:border-red-40');\n    btn.classList.remove(\n      'bg-red',\n      'hover:bg-red',\n      'focus:bg-red',\n      'dark:bg-red-40'\n    );\n  }\n\n  function checkPassword(event) {\n    event.stopPropagation();\n    event.preventDefault();\n    const el = document.getElementById('password-input');\n    const password = el.value;\n    if (password.length > 0) {\n      document.getElementById('password-btn').disabled = true;\n      // Strip any url parameters between fileId and secretKey\n      const fileInfoUrl = window.location.href.replace(/\\?.+#/, '#');\n      state.fileInfo.url = fileInfoUrl;\n      state.fileInfo.password = password;\n      emit('getMetadata');\n    }\n    return false;\n  }\n\n  return div;\n};\n"
  },
  {
    "path": "app/ui/error.js",
    "content": "const html = require('choo/html');\nconst assets = require('../../common/assets');\nconst modal = require('./modal');\n\nmodule.exports = function(state, emit) {\n  const btnText = state.user.loggedIn ? 'okButton' : 'sendYourFilesLink';\n  return html`\n    <main class=\"main\">\n      ${state.modal && modal(state, emit)}\n      <section\n        class=\"flex flex-col items-center justify-center h-full w-full p-6 md:p-8 overflow-hidden md:rounded-xl md:shadow-big\"\n      >\n        <h1 class=\"text-center text-3xl font-bold my-2\">\n          ${state.translate('errorPageHeader')}\n        </h1>\n        <img class=\"my-12 h-48\" src=\"${assets.get('error.svg')}\" />\n        <p\n          class=\"max-w-md text-center text-grey-80 leading-normal dark:text-grey-40 ${state\n            .user.loggedIn\n            ? 'hidden'\n            : ''}\"\n        >\n          ${state.translate('trySendDescription')}\n        </p>\n        <p class=\"my-5\">\n          <a href=\"/\" class=\"btn rounded-lg flex items-center\" role=\"button\"\n            >${state.translate(btnText)}</a\n          >\n        </p>\n      </section>\n    </main>\n  `;\n};\n"
  },
  {
    "path": "app/ui/expiryOptions.js",
    "content": "const html = require('choo/html');\nconst raw = require('choo/html/raw');\nconst { secondsToL10nId } = require('../utils');\nconst selectbox = require('./selectbox');\n\nmodule.exports = function(state, emit) {\n  const el = html`\n    <div class=\"px-1\">\n      ${raw(\n        state.translate('archiveExpiryInfo', {\n          downloadCount:\n            '<span class=\"lg:inline-block md:block sm:inline-block block\"></span><select id=\"dlCount\"></select>',\n          timespan: '<select id=\"timespan\"></select>'\n        })\n      )}\n    </div>\n  `;\n  if (el.__encoded) {\n    // we're rendering on the server\n    return el;\n  }\n\n  const counts = state.DEFAULTS.DOWNLOAD_COUNTS.filter(\n    i => state.capabilities.account || i <= state.user.maxDownloads\n  );\n\n  const dlCountSelect = el.querySelector('#dlCount');\n  el.replaceChild(\n    selectbox(\n      state.archive.dlimit,\n      counts,\n      num => state.translate('downloadCount', { num }),\n      value => {\n        const max = state.user.maxDownloads;\n        state.archive.dlimit = Math.min(value, max);\n        if (value > max) {\n          emit('signup-cta', 'count');\n        } else {\n          emit('render');\n        }\n      },\n      'expire-after-dl-count-select'\n    ),\n    dlCountSelect\n  );\n\n  const expires = state.DEFAULTS.EXPIRE_TIMES_SECONDS.filter(\n    i => state.capabilities.account || i <= state.user.maxExpireSeconds\n  );\n\n  const timeSelect = el.querySelector('#timespan');\n  el.replaceChild(\n    selectbox(\n      state.archive.timeLimit,\n      expires,\n      num => {\n        const l10n = secondsToL10nId(num);\n        return state.translate(l10n.id, l10n);\n      },\n      value => {\n        const max = state.user.maxExpireSeconds;\n        state.archive.timeLimit = Math.min(value, max);\n        if (value > max) {\n          emit('signup-cta', 'time');\n        } else {\n          emit('render');\n        }\n      },\n      'expire-after-time-select'\n    ),\n    timeSelect\n  );\n\n  return el;\n};\n"
  },
  {
    "path": "app/ui/footer.js",
    "content": "const html = require('choo/html');\nconst Component = require('choo/component');\n\nclass Footer extends Component {\n  constructor(name, state) {\n    super(name);\n    this.state = state;\n  }\n\n  update() {\n    return false;\n  }\n\n  createElement() {\n    return html`\n      <footer\n        class=\"flex flex-col md:flex-row items-start w-full flex-none self-start p-6 md:p-8 font-medium text-xs text-grey-60 dark:text-grey-40 md:items-center justify-between\"\n      ></footer>\n    `;\n  }\n}\n\nmodule.exports = Footer;\n"
  },
  {
    "path": "app/ui/header.js",
    "content": "const html = require('choo/html');\nconst Component = require('choo/component');\nconst Account = require('./account');\nconst assets = require('../../common/assets');\nconst { platform } = require('../utils');\n\nclass Header extends Component {\n  constructor(name, state, emit) {\n    super(name);\n    this.state = state;\n    this.emit = emit;\n    this.account = state.cache(Account, 'account');\n  }\n\n  update() {\n    this.account.render();\n    return false;\n  }\n  createElement() {\n    const title =\n      platform() === 'android'\n        ? html`\n            <a class=\"flex flex-row items-center\">\n              <img src=\"${assets.get('icon.svg')}\" />\n              <svg class=\"w-48\">\n                <use xlink:href=\"${assets.get('wordmark.svg')}#logo\" />\n              </svg>\n            </a>\n          `\n        : html`\n            <a class=\"flex flex-row items-center\" href=\"/\">\n              <img\n                alt=\"${this.state.translate('title')}\"\n                src=\"${assets.get('icon.svg')}\"\n              />\n              <svg viewBox=\"66 0 340 64\" class=\"w-48 md:w-64\">\n                <use xlink:href=\"${assets.get('wordmark.svg')}#logo\" />\n              </svg>\n            </a>\n          `;\n    return html`\n      <header\n        class=\"main-header relative flex-none flex flex-row items-center justify-between w-full px-6 md:px-8 h-16 md:h-24 z-20 bg-transparent\"\n      >\n        ${title} ${this.account.render()}\n      </header>\n    `;\n  }\n}\n\nmodule.exports = Header;\n"
  },
  {
    "path": "app/ui/home.js",
    "content": "const html = require('choo/html');\nconst { list } = require('../utils');\nconst archiveTile = require('./archiveTile');\nconst modal = require('./modal');\nconst intro = require('./intro');\n\nmodule.exports = function(state, emit) {\n  if (state.user.loginRequired && !state.user.loggedIn) {\n    emit('signup-cta', 'required');\n  }\n  const archives = state.storage.files\n    .filter(archive => !archive.expired)\n    .map(archive => archiveTile(state, emit, archive));\n  let left = '';\n  if (state.uploading) {\n    left = archiveTile.uploading(state, emit);\n  } else if (state.archive.numFiles > 0) {\n    left = archiveTile.wip(state, emit);\n  } else {\n    left = archiveTile.empty(state, emit);\n  }\n  archives.reverse();\n  const right =\n    archives.length === 0\n      ? intro(state)\n      : list(archives, 'p-2 h-full overflow-y-auto w-full', 'mb-4 w-full');\n\n  return html`\n    <main class=\"main\">\n      ${state.modal && modal(state, emit)}\n      <section\n        class=\"h-full w-full p-6 md:p-8 overflow-hidden md:flex md:flex-row md:rounded-xl md:shadow-big\"\n      >\n        <div class=\"px-2 w-full md:px-0 md:mr-8 md:w-1/2\">${left}</div>\n        <div class=\"mt-6 w-full md:w-1/2 md:-m-2\">${right}</div>\n      </section>\n    </main>\n  `;\n};\n"
  },
  {
    "path": "app/ui/intro.js",
    "content": "const html = require('choo/html');\nconst assets = require('../../common/assets');\n\nmodule.exports = function intro(state) {\n  return html`\n    <send-intro\n      class=\"flex flex-col items-center justify-center bg-white px-6 md:py-0 py-6 mb-0 h-full w-full dark:bg-grey-90\"\n    >\n      <div class=\"mt-12 flex flex-col h-full\">\n        <h1 class=\"text-3xl font-bold md:pb-2\">\n          ${state.translate('introTitle')}\n        </h1>\n        <p class=\"max-w-sm leading-loose mt-6 md:mt-2 md:pr-14\">\n          ${state.translate('introDescription')}\n        </p>\n        <img class=\"intro\" src=\"${assets.get('intro.svg')}\" />\n      </div>\n    </send-intro>\n  `;\n};\n"
  },
  {
    "path": "app/ui/modal.js",
    "content": "const html = require('choo/html');\n\nmodule.exports = function(state, emit) {\n  return html`\n    <send-modal\n      class=\"absolute inset-0 flex items-center justify-center overflow-hidden z-40 bg-white md:rounded-xl md:my-8 dark:bg-grey-90\"\n    >\n      <div\n        class=\"h-full w-full max-h-screen absolute top-0 flex justify-center md:items-center\"\n      >\n        <div class=\"w-full\">\n          ${state.modal(state, emit, close)}\n        </div>\n      </div>\n    </send-modal>\n  `;\n\n  function close(event) {\n    if (event) {\n      event.preventDefault();\n      event.stopPropagation();\n    }\n    emit('closeModal');\n  }\n};\n"
  },
  {
    "path": "app/ui/noStreams.js",
    "content": "const html = require('choo/html');\nconst { bytes } = require('../utils');\nconst assets = require('../../common/assets');\n\nmodule.exports = function(state, emit) {\n  const archive = state.fileInfo;\n  return html`\n    <div\n      class=\"flex flex-col w-full max-w-md h-full mx-auto items-center justify-center\"\n    >\n      <h1 class=\"mb-4 text-3xl font-bold\">${state.translate(\n        'downloadTitle'\n      )}</h1>\n      <p\n        class=\"w-full p-2 border border-yellow-50 rounded md:w-4/5 text-orange-60 bg-yellow-40 text-center leading-normal\"\n      >\n        ⚠️ ${state.translate('noStreamsWarning')} ⚠️\n      </p>\n      <form class=\"md:w-128\" onsubmit=${submit}>\n        <fieldset class=\"border rounded p-4 my-4\" onchange=${optionChanged}>\n          <div class=\"flex items-center mb-2\">\n            <svg class=\"h-8 w-6 mr-3 flex-shrink-0 text-white dark:text-grey-90\">\n              <use xlink:href=\"${assets.get('blue_file.svg')}#icon\"/>\n            </svg>\n            <p class=\"flex-grow\">\n              <h1 class=\"text-base font-medium word-break-all\">${\n                archive.name\n              }</h1>\n              <div class=\"text-sm font-normal opacity-75 pt-1\">${bytes(\n                archive.size\n              )}</div>\n            </p>\n          </div>\n          <div class=\" mt-6 mb-3\">\n            <input class=\"mx-2\" type=\"radio\" name=\"gus\" id=\"copy\" value=\"copy\" checked>\n            <label class=\"\" for=\"copy\">${state.translate(\n              'noStreamsOptionCopy'\n            )}</label>\n          </div>\n          <div class=\"my-3\">\n            <input class=\"mx-2\" type=\"radio\" name=\"gus\" id=\"firefox\" value=\"firefox\">\n            <label class=\"\" for=\"firefox\">${state.translate(\n              'noStreamsOptionFirefox'\n            )}</label>\n          </div>\n          <div class=\"mt-3\">\n            <input class=\"mx-2\" type=\"radio\" name=\"gus\" id=\"download\" value=\"download\">\n            <label class=\"\" for=\"download\">${state.translate(\n              'noStreamsOptionDownload'\n            )}</label>\n          </div>\n        </fieldset>\n        <input\n            class=\"btn rounded-lg w-full flex flex-shrink-0 items-center justify-center\"\n            value=\"${state.translate('copyLinkButton')}\"\n            title=\"${state.translate('copyLinkButton')}\"\n            type=\"submit\" />\n            <p\n          class=\"text-grey-80 leading-normal dark:text-grey-40 font-semibold text-center md:my-8 md:text-left\"\n        >\n          ${state.translate('downloadConfirmDescription')}\n        </p>\n      </form>\n    </div>\n  `;\n\n  function optionChanged(event) {\n    event.stopPropagation();\n    const choice = event.target.value;\n    const button = event.currentTarget.nextElementSibling;\n    let title = button.title;\n    console.error(choice, title);\n    switch (choice) {\n      case 'copy':\n        title = state.translate('copyLinkButton');\n        break;\n      case 'firefox':\n        title = state.translate('downloadFirefox');\n        break;\n      case 'download':\n        title = state.translate('downloadButtonLabel');\n        break;\n    }\n    button.title = title;\n    button.value = title;\n  }\n\n  function submit(event) {\n    const action = document.querySelector('input[type=\"radio\"]:checked').value;\n    switch (action) {\n      case 'copy':\n        emit('copy', { url: window.location.href });\n        document.querySelector('input[type=\"submit\"]').value = state.translate(\n          'copiedUrl'\n        );\n        break;\n      case 'firefox':\n        window.open(\n          'https://www.mozilla.org/firefox/new/?utm_campaign=send-acquisition&utm_medium=referral&utm_source=send.firefox.com'\n        );\n        break;\n      case 'download':\n        emit('download', archive);\n        break;\n    }\n    return false;\n  }\n};\n"
  },
  {
    "path": "app/ui/notFound.js",
    "content": "const html = require('choo/html');\nconst assets = require('../../common/assets');\nconst modal = require('./modal');\n\nmodule.exports = function(state, emit) {\n  const btnText = state.user.loggedIn ? 'okButton' : 'sendYourFilesLink';\n  return html`\n    <main class=\"main\">\n      ${state.modal && modal(state, emit)}\n      <section\n        class=\"flex flex-col items-center justify-center h-full w-full p-6 md:p-8 overflow-hidden md:rounded-xl md:shadow-big\"\n      >\n        <h1 class=\"text-center text-3xl font-bold my-2\">\n          ${state.translate('expiredTitle')}\n        </h1>\n        <img src=\"${assets.get('notFound.svg')}\" class=\"my-12\" />\n        <p\n          class=\"max-w-md text-center text-grey-80 leading-normal dark:text-grey-40 ${state\n            .user.loggedIn\n            ? 'hidden'\n            : ''}\"\n        >\n          ${state.translate('trySendDescription')}\n        </p>\n        <p class=\"my-5\">\n          <a href=\"/\" class=\"btn rounded-lg flex items-center\" role=\"button\"\n            >${state.translate(btnText)}</a\n          >\n        </p>\n        <p class=\"\">\n          <a href=\"/report\" class=\"link-blue\"\n            >${state.translate('reportFile')}</a\n          >\n        </p>\n      </section>\n    </main>\n  `;\n};\n"
  },
  {
    "path": "app/ui/okDialog.js",
    "content": "const html = require('choo/html');\n\nmodule.exports = function(message) {\n  return function(state, emit, close) {\n    return html`\n      <send-ok-dialog class=\"flex flex-col max-w-sm p-4 m-auto\">\n        <h2 class=\"text-center text-xl font-bold m-8 leading-normal\">\n          ${message}\n        </h2>\n        <button\n          class=\"btn rounded-lg w-full flex-shrink-0\"\n          onclick=\"${close}\"\n          title=\"${state.translate('okButton')}\"\n        >\n          ${state.translate('okButton')}\n        </button>\n      </send-ok-dialog>\n    `;\n  };\n};\n"
  },
  {
    "path": "app/ui/report.js",
    "content": "const html = require('choo/html');\nconst assets = require('../../common/assets');\n\nconst REPORTABLES = ['Malware', 'Pii', 'Abuse'];\n\nmodule.exports = function(state, emit) {\n  let submitting = false;\n  const file = state.fileInfo;\n  if (!file) {\n    return html`\n      <main class=\"main\">\n        <section\n          class=\"flex flex-col items-center justify-center h-full w-full p-6 md:p-8 overflow-hidden md:rounded-xl md:shadow-big\"\n        >\n          <p class=\"text-xl text-center mb-4 leading-normal\">\n            ${state.translate('reportUnknownDescription')}\n          </p>\n        </section>\n      </main>\n    `;\n  }\n  if (file.reported) {\n    return html`\n      <main class=\"main\">\n        <section\n          class=\"flex flex-col items-center justify-center h-full w-full p-6 md:p-8 overflow-hidden md:rounded-xl md:shadow-big\"\n        >\n          <h1 class=\"text-center text-3xl font-bold my-2\">\n            ${state.translate('reportedTitle')}\n          </h1>\n          <p class=\"max-w-md text-center leading-normal\">\n            ${state.translate('reportedDescription')}\n          </p>\n          <img src=\"${assets.get('notFound.svg')}\" class=\"my-12\" />\n          <p class=\"my-5\">\n            <a href=\"/\" class=\"btn rounded-lg flex items-center\" role=\"button\"\n              >${state.translate('okButton')}</a\n            >\n          </p>\n        </section>\n      </main>\n    `;\n  }\n  return html`\n    <main class=\"main\">\n      <section\n        class=\"relative h-full w-full p-6 md:p-8 md:rounded-xl md:shadow-big\"\n      >\n        <div\n          class=\"flex flex-col w-full max-w-sm h-full mx-auto items-center justify-center\"\n        >\n          <h1 class=\"text-2xl font-bold mb-4\">\n            ${state.translate('reportFile')}\n          </h1>\n          <p class=\"mb-4 leading-normal font-semibold\">\n            ${state.translate('reportDescription')}\n          </p>\n          <form onsubmit=\"${report}\" data-no-csrf>\n            <fieldset onchange=\"${optionChanged}\">\n              <ul\n                class=\"list-none p-4 mb-6 rounded-sm bg-grey-10 dark:bg-black\"\n              >\n                ${REPORTABLES.map(\n                  reportable =>\n                    html`\n                      <li class=\"mb-2 leading-normal\">\n                        <label\n                          for=\"${reportable.toLowerCase()}\"\n                          class=\"flex items-center\"\n                        >\n                          <input\n                            type=\"radio\"\n                            name=\"reason\"\n                            id=\"${reportable.toLowerCase()}\"\n                            value=\"${reportable.toLowerCase()}\"\n                            class=\"mr-2 my-2 w-4 h-4 flex-none\"\n                          />\n                          ${state.translate(`reportReason${reportable}`)}\n                        </label>\n                      </li>\n                    `\n                )}\n              </ul>\n            </fieldset>\n            <input\n              type=\"submit\"\n              disabled\n              class=\"btn rounded-lg w-full flex-shrink-0 focus:outline\"\n              title=\"${state.translate('reportButton')}\"\n              value=\"${state.translate('reportButton')}\"\n            />\n          </form>\n        </div>\n      </section>\n    </main>\n  `;\n\n  function optionChanged(event) {\n    event.stopPropagation();\n    const button = event.currentTarget.nextElementSibling;\n    button.disabled = false;\n  }\n\n  function report(event) {\n    event.stopPropagation();\n    event.preventDefault();\n    if (submitting) {\n      return;\n    }\n    submitting = true;\n    state.fileInfo.reported = true;\n    const form = event.target;\n    emit('report', { reason: form.reason.value });\n  }\n};\n"
  },
  {
    "path": "app/ui/selectbox.js",
    "content": "const html = require('choo/html');\n\nmodule.exports = function(selected, options, translate, changed, htmlId) {\n  let x = selected;\n\n  return html`\n    <select\n      id=\"${htmlId}\"\n      class=\"appearance-none cursor-pointer border rounded bg-grey-10 hover:border-blue-50 focus:border-blue-50 pl-1 pr-8 py-1 my-1 h-8 dark:bg-grey-80\"\n      onchange=\"${choose}\"\n    >\n      ${options.map(\n        i =>\n          html`\n            <option value=\"${i}\" ${i === selected ? 'selected' : ''}\n              >${translate(i)}</option\n            >\n          `\n      )}\n    </select>\n  `;\n\n  function choose(event) {\n    const target = event.target;\n    const value = +target.value;\n\n    if (x !== value) {\n      x = value;\n      changed(value);\n    }\n  }\n};\n"
  },
  {
    "path": "app/ui/shareDialog.js",
    "content": "const html = require('choo/html');\n\nmodule.exports = function(name, url) {\n  const dialog = function(state, emit, close) {\n    return html`\n      <send-share-dialog\n        class=\"flex flex-col items-center text-center p-4 max-w-sm m-auto\"\n      >\n        <h1 class=\"text-3xl font-bold my-4\">\n          ${state.translate('notifyUploadEncryptDone')}\n        </h1>\n        <p class=\"font-normal leading-normal text-grey-80 dark:text-grey-40\">\n          ${state.translate('shareLinkDescription')}<br />\n          <span class=\"word-break-all\">${name}</span>\n        </p>\n        <input\n          type=\"text\"\n          id=\"share-url\"\n          class=\"w-full my-4 border rounded-lg leading-loose h-12 px-2 py-1 dark:bg-grey-80\"\n          value=\"${url}\"\n          readonly=\"true\"\n        />\n        <button\n          class=\"btn rounded-lg w-full flex-shrink-0 focus:outline\"\n          onclick=\"${share}\"\n          title=\"${state.translate('shareLinkButton')}\"\n        >\n          ${state.translate('shareLinkButton')}\n        </button>\n        <button\n          class=\"link-blue my-4 font-medium cursor-pointer focus:outline\"\n          onclick=\"${close}\"\n          title=\"${state.translate('okButton')}\"\n        >\n          ${state.translate('okButton')}\n        </button>\n      </send-share-dialog>\n    `;\n\n    async function share(event) {\n      event.stopPropagation();\n      try {\n        await navigator.share({\n          title: state.translate('-send-brand'),\n          text: state.translate('shareMessage', { name }),\n          url\n        });\n      } catch (e) {\n        if (e.code === e.ABORT_ERR) {\n          return;\n        }\n        console.error(e);\n      }\n      close();\n    }\n  };\n  dialog.type = 'share';\n  return dialog;\n};\n"
  },
  {
    "path": "app/ui/unsupported.js",
    "content": "const html = require('choo/html');\nconst modal = require('./modal');\n\nmodule.exports = function(state, emit) {\n  let strings = {};\n  let why = '';\n  let url = '';\n\n  if (state.params.reason !== 'outdated') {\n    strings = unsupportedStrings(state);\n    why = html`\n      <a\n        class=\"text-blue\"\n        href=\"https://github.com/mozilla/send/blob/master/docs/faq.md#why-is-my-browser-not-supported\"\n      >\n        ${state.translate('notSupportedLink')}\n      </a>\n    `;\n    url =\n      'https://www.mozilla.org/firefox/new/?utm_campaign=send-acquisition&utm_medium=referral&utm_source=send.firefox.com';\n  } else {\n    strings = outdatedStrings(state);\n    url = 'https://support.mozilla.org/kb/update-firefox-latest-version';\n  }\n\n  return html`\n    <main class=\"main\">\n      ${state.modal && modal(state, emit)}\n      <section\n        class=\"flex flex-col items-center justify-center text-center bg-white m-6 px-6 py-8 border border-grey-30 md:border-none md:px-12 md:py-16 shadow w-full md:h-full dark:bg-grey-90\"\n      >\n        <h1 class=\"text-3xl font-bold\">${strings.header}</h1>\n        <p class=\"mt-4 mb-8 max-w-md leading-normal\">${strings.description}</p>\n        ${why}\n        <a href=\"${url}\" class=\"btn rounded-lg mt-8 px-8\">\n          ${strings.button}\n        </a>\n      </section>\n    </main>\n  `;\n};\n\nfunction outdatedStrings(state) {\n  return {\n    header: state.translate('notSupportedHeader'),\n    description: state.translate('notSupportedOutdatedDetail'),\n    button: state.translate('updateFirefox')\n  };\n}\n\nfunction unsupportedStrings(state) {\n  return {\n    header: state.translate('notSupportedHeader'),\n    description: state.translate('notSupportedDescription'),\n    button: state.translate('downloadFirefox')\n  };\n}\n"
  },
  {
    "path": "app/user.js",
    "content": "import assets from '../common/assets';\nimport { getFileList, setFileList } from './api';\nimport { encryptStream, decryptStream } from './ece';\nimport { arrayToB64, b64ToArray, streamToArrayBuffer } from './utils';\nimport { blobStream } from './streams';\nimport { getFileListKey, prepareScopedBundleKey, preparePkce } from './fxa';\nimport storage from './storage';\n\nconst textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder();\nconst anonId = arrayToB64(crypto.getRandomValues(new Uint8Array(16)));\n\nasync function hashId(id) {\n  const d = new Date();\n  const month = d.getUTCMonth();\n  const year = d.getUTCFullYear();\n  const encoded = textEncoder.encode(`${id}:${year}:${month}`);\n  const hash = await crypto.subtle.digest('SHA-256', encoded);\n  return arrayToB64(new Uint8Array(hash.slice(16)));\n}\n\nexport default class User {\n  constructor(storage, limits, authConfig) {\n    this.authConfig = authConfig;\n    this.limits = limits;\n    this.storage = storage;\n    this.data = storage.user || {};\n  }\n\n  get info() {\n    return this.data || this.storage.user || {};\n  }\n\n  set info(data) {\n    this.data = data;\n    this.storage.user = data;\n  }\n\n  get firstAction() {\n    return this.storage.get('firstAction');\n  }\n\n  set firstAction(action) {\n    this.storage.set('firstAction', action);\n  }\n\n  get surveyed() {\n    return this.storage.get('surveyed');\n  }\n\n  set surveyed(yes) {\n    this.storage.set('surveyed', yes);\n  }\n\n  get avatar() {\n    const defaultAvatar = assets.get('user.svg');\n    if (this.info.avatarDefault) {\n      return defaultAvatar;\n    }\n    return this.info.avatar || defaultAvatar;\n  }\n\n  get name() {\n    return this.info.displayName;\n  }\n\n  get email() {\n    return this.info.email;\n  }\n\n  get loggedIn() {\n    return !!this.info.access_token;\n  }\n\n  get bearerToken() {\n    return this.info.access_token;\n  }\n\n  get refreshToken() {\n    return this.info.refresh_token;\n  }\n\n  get maxSize() {\n    return this.loggedIn\n      ? this.limits.MAX_FILE_SIZE\n      : this.limits.ANON.MAX_FILE_SIZE;\n  }\n\n  get maxExpireSeconds() {\n    return this.loggedIn\n      ? this.limits.MAX_EXPIRE_SECONDS\n      : this.limits.ANON.MAX_EXPIRE_SECONDS;\n  }\n\n  get maxDownloads() {\n    return this.loggedIn\n      ? this.limits.MAX_DOWNLOADS\n      : this.limits.ANON.MAX_DOWNLOADS;\n  }\n\n  get loginRequired() {\n    return this.authConfig && this.authConfig.fxa_required;\n  }\n\n  async metricId() {\n    return this.loggedIn ? hashId(this.info.uid) : undefined;\n  }\n\n  async deviceId() {\n    return this.loggedIn ? hashId(this.storage.id) : hashId(anonId);\n  }\n\n  async startAuthFlow(trigger, utms = {}) {\n    this.utms = utms;\n    this.trigger = trigger;\n    try {\n      const params = new URLSearchParams({\n        entrypoint: `send-${trigger}`,\n        form_type: 'email',\n        utm_source: utms.source || 'send',\n        utm_campaign: utms.campaign || 'none'\n      });\n      const res = await fetch(\n        `${this.authConfig.issuer}/metrics-flow?${params.toString()}`,\n        {\n          mode: 'cors'\n        }\n      );\n      const { flowId, flowBeginTime } = await res.json();\n      this.flowId = flowId;\n      this.flowBeginTime = flowBeginTime;\n    } catch (e) {\n      console.error(e);\n      this.flowId = null;\n      this.flowBeginTime = null;\n    }\n  }\n\n  async login(email) {\n    const state = arrayToB64(crypto.getRandomValues(new Uint8Array(16)));\n    storage.set('oauthState', state);\n    const keys_jwk = await prepareScopedBundleKey(this.storage);\n    const code_challenge = await preparePkce(this.storage);\n    const options = {\n      action: 'email',\n      access_type: 'offline',\n      client_id: this.authConfig.client_id,\n      code_challenge,\n      code_challenge_method: 'S256',\n      response_type: 'code',\n      scope: `profile ${this.authConfig.key_scope}`,\n      state,\n      keys_jwk\n    };\n    if (email) {\n      options.email = email;\n    }\n    if (this.flowId && this.flowBeginTime) {\n      options.flow_id = this.flowId;\n      options.flow_begin_time = this.flowBeginTime;\n    }\n    if (this.trigger) {\n      options.entrypoint = `send-${this.trigger}`;\n    }\n    if (this.utms) {\n      options.utm_campaign = this.utms.campaign || 'none';\n      options.utm_content = this.utms.content || 'none';\n      options.utm_medium = this.utms.medium || 'none';\n      options.utm_source = this.utms.source || 'send';\n      options.utm_term = this.utms.term || 'none';\n    }\n    const params = new URLSearchParams(options);\n    location.assign(\n      `${this.authConfig.authorization_endpoint}?${params.toString()}`\n    );\n  }\n\n  async finishLogin(code, state) {\n    const localState = storage.get('oauthState');\n    storage.remove('oauthState');\n    if (state !== localState) {\n      throw new Error('state mismatch');\n    }\n    const tokenResponse = await fetch(this.authConfig.token_endpoint, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json'\n      },\n      body: JSON.stringify({\n        code,\n        client_id: this.authConfig.client_id,\n        code_verifier: this.storage.get('pkceVerifier')\n      })\n    });\n    const auth = await tokenResponse.json();\n    const infoResponse = await fetch(this.authConfig.userinfo_endpoint, {\n      method: 'GET',\n      headers: {\n        Authorization: `Bearer ${auth.access_token}`\n      }\n    });\n    const userInfo = await infoResponse.json();\n    userInfo.access_token = auth.access_token;\n    userInfo.refresh_token = auth.refresh_token;\n    userInfo.fileListKey = await getFileListKey(this.storage, auth.keys_jwe);\n    this.info = userInfo;\n    this.storage.remove('pkceVerifier');\n  }\n\n  async refresh() {\n    if (!this.refreshToken) {\n      return false;\n    }\n    try {\n      const tokenResponse = await fetch(this.authConfig.token_endpoint, {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json'\n        },\n        body: JSON.stringify({\n          client_id: this.authConfig.client_id,\n          grant_type: 'refresh_token',\n          refresh_token: this.refreshToken\n        })\n      });\n      if (tokenResponse.ok) {\n        const auth = await tokenResponse.json();\n        const info = { ...this.info, access_token: auth.access_token };\n        this.info = info;\n        return true;\n      }\n    } catch (e) {\n      console.error(e);\n    }\n    await this.logout();\n    return false;\n  }\n\n  async logout() {\n    try {\n      if (this.refreshToken) {\n        await fetch(this.authConfig.revocation_endpoint, {\n          method: 'POST',\n          headers: {\n            'Content-Type': 'application/json'\n          },\n          body: JSON.stringify({\n            refresh_token: this.refreshToken\n          })\n        });\n      }\n      if (this.bearerToken) {\n        await fetch(this.authConfig.revocation_endpoint, {\n          method: 'POST',\n          headers: {\n            'Content-Type': 'application/json'\n          },\n          body: JSON.stringify({\n            token: this.bearerToken\n          })\n        });\n      }\n    } catch (e) {\n      console.error(e);\n      // oh well, we tried\n    }\n    this.storage.clearLocalFiles();\n    this.info = {};\n  }\n\n  async syncFileList() {\n    let changes = { incoming: false, outgoing: false, downloadCount: false };\n    if (!this.loggedIn) {\n      return this.storage.merge();\n    }\n    let list = [];\n    const key = b64ToArray(this.info.fileListKey);\n    const sha = await crypto.subtle.digest('SHA-256', key);\n    const kid = arrayToB64(new Uint8Array(sha)).substring(0, 16);\n    const retry = async () => {\n      const refreshed = await this.refresh();\n      if (refreshed) {\n        return await this.syncFileList();\n      } else {\n        return { incoming: true };\n      }\n    };\n    try {\n      const encrypted = await getFileList(this.bearerToken, kid);\n      const decrypted = await streamToArrayBuffer(\n        decryptStream(blobStream(encrypted), key)\n      );\n      list = JSON.parse(textDecoder.decode(decrypted));\n    } catch (e) {\n      if (e.message === '401') {\n        return retry(e);\n      }\n    }\n    changes = await this.storage.merge(list);\n    if (!changes.outgoing) {\n      return changes;\n    }\n    try {\n      const blob = new Blob([\n        textEncoder.encode(JSON.stringify(this.storage.files))\n      ]);\n      const encrypted = await streamToArrayBuffer(\n        encryptStream(blobStream(blob), key)\n      );\n      await setFileList(this.bearerToken, kid, encrypted);\n    } catch (e) {\n      if (e.message === '401') {\n        return retry(e);\n      }\n    }\n    return changes;\n  }\n\n  toJSON() {\n    return this.info;\n  }\n}\n"
  },
  {
    "path": "app/utils.js",
    "content": "/* global Android */\nlet html;\ntry {\n  html = require('choo/html');\n} catch (e) {\n  // running in the service worker\n}\nconst b64 = require('base64-js');\n\nfunction arrayToB64(array) {\n  return b64\n    .fromByteArray(array)\n    .replace(/\\+/g, '-')\n    .replace(/\\//g, '_')\n    .replace(/=/g, '');\n}\n\nfunction b64ToArray(str) {\n  return b64.toByteArray(str + '==='.slice((str.length + 3) % 4));\n}\n\nfunction locale() {\n  return document.querySelector('html').lang;\n}\n\nfunction loadShim(polyfill) {\n  return new Promise((resolve, reject) => {\n    const shim = document.createElement('script');\n    shim.src = polyfill;\n    shim.addEventListener('load', () => resolve(true));\n    shim.addEventListener('error', () => resolve(false));\n    document.head.appendChild(shim);\n  });\n}\n\nfunction isFile(id) {\n  return /^[0-9a-fA-F]{10,16}$/.test(id);\n}\n\nfunction copyToClipboard(str) {\n  const aux = document.createElement('input');\n  aux.setAttribute('value', str);\n  aux.contentEditable = true;\n  aux.readOnly = true;\n  document.body.appendChild(aux);\n  if (navigator.userAgent.match(/iphone|ipad|ipod/i)) {\n    const range = document.createRange();\n    range.selectNodeContents(aux);\n    const sel = getSelection();\n    sel.removeAllRanges();\n    sel.addRange(range);\n    aux.setSelectionRange(0, str.length);\n  } else {\n    aux.select();\n  }\n  const result = document.execCommand('copy');\n  document.body.removeChild(aux);\n  return result;\n}\n\nconst LOCALIZE_NUMBERS = !!(\n  typeof Intl === 'object' &&\n  Intl &&\n  typeof Intl.NumberFormat === 'function' &&\n  typeof navigator === 'object'\n);\n\nconst UNITS = ['bytes', 'kb', 'mb', 'gb'];\nfunction bytes(num) {\n  if (num < 1) {\n    return '0B';\n  }\n  const exponent = Math.min(Math.floor(Math.log10(num) / 3), UNITS.length - 1);\n  const n = Number(num / Math.pow(1024, exponent));\n  const decimalDigits = Math.floor(n) === n ? 0 : 1;\n  let nStr = n.toFixed(decimalDigits);\n  if (LOCALIZE_NUMBERS) {\n    try {\n      nStr = n.toLocaleString(locale(), {\n        minimumFractionDigits: decimalDigits,\n        maximumFractionDigits: decimalDigits\n      });\n    } catch (e) {\n      // fall through\n    }\n  }\n  return translate('fileSize', {\n    num: nStr,\n    units: translate(UNITS[exponent])\n  });\n}\n\nfunction percent(ratio) {\n  if (LOCALIZE_NUMBERS) {\n    try {\n      return ratio.toLocaleString(locale(), { style: 'percent' });\n    } catch (e) {\n      // fall through\n    }\n  }\n  return `${Math.floor(ratio * 100)}%`;\n}\n\nfunction number(n) {\n  if (LOCALIZE_NUMBERS) {\n    return n.toLocaleString(locale());\n  }\n  return n.toString();\n}\n\nfunction allowedCopy() {\n  const support = !!document.queryCommandSupported;\n  return support ? document.queryCommandSupported('copy') : false;\n}\n\nfunction delay(delay = 100) {\n  return new Promise(resolve => setTimeout(resolve, delay));\n}\n\nfunction fadeOut(selector) {\n  const classes = document.querySelector(selector).classList;\n  classes.remove('effect--fadeIn');\n  classes.add('effect--fadeOut');\n  return delay(300);\n}\n\nfunction openLinksInNewTab(links, should = true) {\n  links = links || Array.from(document.querySelectorAll('a:not([target])'));\n  if (should) {\n    links.forEach(l => {\n      l.setAttribute('target', '_blank');\n      l.setAttribute('rel', 'noopener noreferrer');\n    });\n  } else {\n    links.forEach(l => {\n      l.removeAttribute('target');\n      l.removeAttribute('rel');\n    });\n  }\n  return links;\n}\n\nfunction browserName() {\n  try {\n    // order of these matters\n    if (/firefox/i.test(navigator.userAgent)) {\n      return 'firefox';\n    }\n    if (/edge/i.test(navigator.userAgent)) {\n      return 'edge';\n    }\n    if (/edg/i.test(navigator.userAgent)) {\n      return 'edgium';\n    }\n    if (/trident/i.test(navigator.userAgent)) {\n      return 'ie';\n    }\n    if (/chrome/i.test(navigator.userAgent)) {\n      return 'chrome';\n    }\n    if (/safari/i.test(navigator.userAgent)) {\n      return 'safari';\n    }\n    if (/send android/i.test(navigator.userAgent)) {\n      return 'android-app';\n    }\n    return 'other';\n  } catch (e) {\n    return 'unknown';\n  }\n}\n\nasync function streamToArrayBuffer(stream, size) {\n  const reader = stream.getReader();\n  let state = await reader.read();\n\n  if (size) {\n    const result = new Uint8Array(size);\n    let offset = 0;\n    while (!state.done) {\n      result.set(state.value, offset);\n      offset += state.value.length;\n      state = await reader.read();\n    }\n    return result.buffer;\n  }\n\n  const parts = [];\n  let len = 0;\n  while (!state.done) {\n    parts.push(state.value);\n    len += state.value.length;\n    state = await reader.read();\n  }\n  let offset = 0;\n  const result = new Uint8Array(len);\n  for (const part of parts) {\n    result.set(part, offset);\n    offset += part.length;\n  }\n  return result.buffer;\n}\n\nfunction list(items, ulStyle = '', liStyle = '') {\n  const lis = items.map(\n    i =>\n      html`\n        <li class=\"${liStyle}\">${i}</li>\n      `\n  );\n  return html`\n    <ul class=\"${ulStyle}\">\n      ${lis}\n    </ul>\n  `;\n}\n\nfunction secondsToL10nId(seconds) {\n  if (seconds < 3600) {\n    return { id: 'timespanMinutes', num: Math.floor(seconds / 60) };\n  } else if (seconds < 86400) {\n    return { id: 'timespanHours', num: Math.floor(seconds / 3600) };\n  } else {\n    return { id: 'timespanDays', num: Math.floor(seconds / 86400) };\n  }\n}\n\nfunction timeLeft(milliseconds) {\n  if (milliseconds < 1) {\n    return { id: 'linkExpiredAlt' };\n  }\n  const minutes = Math.floor(milliseconds / 1000 / 60);\n  const hours = Math.floor(minutes / 60);\n  const days = Math.floor(hours / 24);\n  if (days >= 1) {\n    return {\n      id: 'expiresDaysHoursMinutes',\n      days,\n      hours: hours % 24,\n      minutes: minutes % 60\n    };\n  }\n  if (hours >= 1) {\n    return {\n      id: 'expiresHoursMinutes',\n      hours,\n      minutes: minutes % 60\n    };\n  } else if (hours === 0) {\n    if (minutes === 0) {\n      return { id: 'expiresMinutes', minutes: '< 1' };\n    }\n    return { id: 'expiresMinutes', minutes };\n  }\n  return null;\n}\n\nfunction platform() {\n  if (typeof Android === 'object') {\n    return 'android';\n  }\n  return 'web';\n}\n\nconst ECE_RECORD_SIZE = 1024 * 64;\nconst TAG_LENGTH = 16;\nfunction encryptedSize(size, rs = ECE_RECORD_SIZE, tagLength = TAG_LENGTH) {\n  const chunk_meta = tagLength + 1; // Chunk metadata, tag and delimiter\n  return 21 + size + chunk_meta * Math.ceil(size / (rs - chunk_meta));\n}\n\nlet translate = function() {\n  throw new Error('uninitialized translate function. call setTranslate first');\n};\nfunction setTranslate(t) {\n  translate = t;\n}\n\nfunction concat(b1, b2) {\n  const result = new Uint8Array(b1.length + b2.length);\n  result.set(b1, 0);\n  result.set(b2, b1.length);\n  return result;\n}\n\nmodule.exports = {\n  concat,\n  locale,\n  fadeOut,\n  delay,\n  allowedCopy,\n  bytes,\n  percent,\n  number,\n  copyToClipboard,\n  arrayToB64,\n  b64ToArray,\n  loadShim,\n  isFile,\n  openLinksInNewTab,\n  browserName,\n  streamToArrayBuffer,\n  list,\n  secondsToL10nId,\n  timeLeft,\n  platform,\n  encryptedSize,\n  setTranslate\n};\n"
  },
  {
    "path": "app/zip.js",
    "content": "import crc32 from './crc32';\n\nconst encoder = new TextEncoder();\n\nfunction dosDateTime(dateTime = new Date()) {\n  const year = (dateTime.getFullYear() - 1980) << 9;\n  const month = (dateTime.getMonth() + 1) << 5;\n  const day = dateTime.getDate();\n  const date = year | month | day;\n  const hour = dateTime.getHours() << 11;\n  const minute = dateTime.getMinutes() << 5;\n  const second = Math.floor(dateTime.getSeconds() / 2);\n  const time = hour | minute | second;\n\n  return { date, time };\n}\n\nclass File {\n  constructor(info) {\n    this.name = encoder.encode(info.name);\n    this.size = info.size;\n    this.bytesRead = 0;\n    this.crc = null;\n    this.dateTime = dosDateTime();\n  }\n\n  get header() {\n    const h = new ArrayBuffer(30 + this.name.byteLength);\n    const v = new DataView(h);\n    v.setUint32(0, 0x04034b50, true); // sig\n    v.setUint16(4, 20, true); // version\n    v.setUint16(6, 8, true); // bit flags (8 = use data descriptor)\n    v.setUint16(8, 0, true); // compression\n    v.setUint16(10, this.dateTime.time, true); // modified time\n    v.setUint16(12, this.dateTime.date, true); // modified date\n    v.setUint32(14, 0, true); // crc32 (in descriptor)\n    v.setUint32(18, 0, true); // compressed size (in descriptor)\n    v.setUint32(22, 0, true); // uncompressed size (in descriptor)\n    v.setUint16(26, this.name.byteLength, true); // name length\n    v.setUint16(28, 0, true); // extra field length\n    for (let i = 0; i < this.name.byteLength; i++) {\n      v.setUint8(30 + i, this.name[i]);\n    }\n    return new Uint8Array(h);\n  }\n\n  get dataDescriptor() {\n    const dd = new ArrayBuffer(16);\n    const v = new DataView(dd);\n    v.setUint32(0, 0x08074b50, true); // sig\n    v.setUint32(4, this.crc, true); // crc32\n    v.setUint32(8, this.size, true); // compressed size\n    v.setUint32(12, this.size, true); // uncompressed size\n    return new Uint8Array(dd);\n  }\n\n  directoryRecord(offset) {\n    const dr = new ArrayBuffer(46 + this.name.byteLength);\n    const v = new DataView(dr);\n    v.setUint32(0, 0x02014b50, true); // sig\n    v.setUint16(4, 20, true); // version made\n    v.setUint16(6, 20, true); // version required\n    v.setUint16(8, 8, true); // bit flags (8 = use data descriptor)\n    v.setUint16(10, 0, true); // compression\n    v.setUint16(12, this.dateTime.time, true); // modified time\n    v.setUint16(14, this.dateTime.date, true); // modified date\n    v.setUint32(16, this.crc, true); // crc\n    v.setUint32(20, this.size, true); // compressed size\n    v.setUint32(24, this.size, true); // uncompressed size\n    v.setUint16(28, this.name.byteLength, true); // name length\n    v.setUint16(30, 0, true); // extra length\n    v.setUint16(32, 0, true); // comment length\n    v.setUint16(34, 0, true); // disk number\n    v.setUint16(36, 0, true); // internal file attrs\n    v.setUint32(38, 0, true); // external file attrs\n    v.setUint32(42, offset, true); // file offset\n    for (let i = 0; i < this.name.byteLength; i++) {\n      v.setUint8(46 + i, this.name[i]);\n    }\n    return new Uint8Array(dr);\n  }\n\n  get byteLength() {\n    return this.size + this.name.byteLength + 30 + 16;\n  }\n\n  append(data, controller) {\n    this.bytesRead += data.byteLength;\n    const endIndex = data.byteLength - Math.max(this.bytesRead - this.size, 0);\n    const buf = data.slice(0, endIndex);\n    this.crc = crc32(buf, this.crc);\n    controller.enqueue(buf);\n    if (endIndex < data.byteLength) {\n      return data.slice(endIndex, data.byteLength);\n    }\n  }\n}\n\nfunction centralDirectory(files, controller) {\n  let directoryOffset = 0;\n  let directorySize = 0;\n  for (let i = 0; i < files.length; i++) {\n    const file = files[i];\n    const record = file.directoryRecord(directoryOffset);\n    directoryOffset += file.byteLength;\n    controller.enqueue(record);\n    directorySize += record.byteLength;\n  }\n  controller.enqueue(eod(files.length, directorySize, directoryOffset));\n}\n\nfunction eod(fileCount, directorySize, directoryOffset) {\n  const e = new ArrayBuffer(22);\n  const v = new DataView(e);\n  v.setUint32(0, 0x06054b50, true); // sig\n  v.setUint16(4, 0, true); // disk number\n  v.setUint16(6, 0, true); // directory disk\n  v.setUint16(8, fileCount, true); // number of records\n  v.setUint16(10, fileCount, true); // total records\n  v.setUint32(12, directorySize, true); // size of directory\n  v.setUint32(16, directoryOffset, true); // offset of directory\n  v.setUint16(20, 0, true); // comment length\n  return new Uint8Array(e);\n}\n\nclass ZipStreamController {\n  constructor(files, source) {\n    this.files = files;\n    this.fileIndex = 0;\n    this.file = null;\n    this.reader = source.getReader();\n    this.nextFile();\n    this.extra = null;\n  }\n\n  nextFile() {\n    this.file = this.files[this.fileIndex++];\n  }\n\n  async pull(controller) {\n    if (!this.file) {\n      // end of archive\n      centralDirectory(this.files, controller);\n      return controller.close();\n    }\n    if (this.file.bytesRead === 0) {\n      // beginning of file\n      controller.enqueue(this.file.header);\n      if (this.extra) {\n        this.extra = this.file.append(this.extra, controller);\n      }\n    }\n    if (this.file.bytesRead >= this.file.size) {\n      // end of file\n      controller.enqueue(this.file.dataDescriptor);\n      this.nextFile();\n      return this.pull(controller);\n    }\n    const data = await this.reader.read();\n    if (data.done) {\n      this.nextFile();\n      return this.pull(controller);\n    }\n    this.extra = this.file.append(data.value, controller);\n  }\n}\n\nexport default class Zip {\n  constructor(manifest, source) {\n    this.files = manifest.files.map(info => new File(info));\n    this.source = source;\n  }\n\n  get stream() {\n    return new ReadableStream(new ZipStreamController(this.files, this.source));\n  }\n\n  get size() {\n    const entries = this.files.reduce(\n      (total, file) => total + file.byteLength * 2 - file.size,\n      0\n    );\n    const eod = 22;\n    return entries + eod;\n  }\n}\n"
  },
  {
    "path": "browserslist",
    "content": "last 2 chrome versions\nlast 2 firefox versions\nlast 2 safari versions\nlast 2 edge versions\nedge 18\nfirefox esr\n"
  },
  {
    "path": "build/android_index_plugin.js",
    "content": "const path = require('path');\nconst html = require('choo/html');\nconst NAME = 'AndroidIndexPlugin';\n\nfunction chunkFileNames(compilation) {\n  const names = {};\n  for (const chunk of compilation.chunks) {\n    for (const file of chunk.files) {\n      if (!/\\.map$/.test(file)) {\n        names[`${chunk.name}${path.extname(file)}`] = file;\n      }\n    }\n  }\n  return names;\n}\nclass AndroidIndexPlugin {\n  apply(compiler) {\n    compiler.hooks.emit.tap(NAME, compilation => {\n      const files = chunkFileNames(compilation);\n      const page = html`\n        <html lang=\"en-US\">\n          <head>\n            <title>Send</title>\n            <meta charset=\"utf-8\" />\n            <meta\n              name=\"viewport\"\n              content=\"width=device-width, initial-scale=1\"\n            />\n            <base href=\"file:///android_asset/\" />\n            <link href=\"${files['app.css']}\" rel=\"stylesheet\" />\n            <script src=\"${files['android.js']}\"></script>\n          </head>\n          <body></body>\n        </html>\n      `\n        .toString()\n        .replace(/\\n\\s{6}/g, '\\n');\n      compilation.assets['android.html'] = {\n        source() {\n          return page;\n        },\n        size() {\n          return page.length;\n        }\n      };\n    });\n  }\n}\n\nmodule.exports = AndroidIndexPlugin;\n"
  },
  {
    "path": "build/readme.md",
    "content": "# Custom Loaders\n\n## Android Index Plugin\n\nGenerates the `index.html` page for the native android client\n\n## Version Plugin\n\nCreates a `version.json` file that gets exposed by the `/__version__` route from the `package.json` file and current git commit hash.\n\n# See Also\n\n- [docs/build.md](../docs/build.md)\n- [webpack.config.js](../webpack.config.js)"
  },
  {
    "path": "build/version_plugin.js",
    "content": "const gitRevSync = require('git-rev-sync');\nconst pkg = require('../package.json');\n\nlet commit = 'unknown';\n\ntry {\n  commit = gitRevSync.short();\n} catch (e) {\n  console.warn('Error fetching current git commit: ' + e);\n}\n\nconst version = JSON.stringify({\n  commit,\n  source: pkg.homepage,\n  version: process.env.CIRCLE_TAG || `v${pkg.version}`\n});\n\nclass VersionPlugin {\n  apply(compiler) {\n    compiler.hooks.emit.tap('VersionPlugin', compilation => {\n      compilation.assets['version.json'] = {\n        source() {\n          return version;\n        },\n        size() {\n          return version.length;\n        }\n      };\n    });\n  }\n}\n\nmodule.exports = VersionPlugin;\n"
  },
  {
    "path": "common/assets.js",
    "content": "const genmap = require('./generate_asset_map');\nconst isServer = typeof genmap === 'function';\nlet prefix = '';\nlet manifest = {};\ntry {\n  //eslint-disable-next-line node/no-missing-require\n  manifest = require('../dist/manifest.json');\n} catch (e) {\n  // use middleware\n}\n\nconst assets = isServer ? manifest : genmap;\n\nfunction getAsset(name) {\n  return prefix + assets[name];\n}\n\nfunction setPrefix(name) {\n  prefix = name;\n}\n\nfunction getMatches(match) {\n  return Object.keys(assets)\n    .filter(k => match.test(k))\n    .map(getAsset);\n}\n\nconst instance = {\n  setPrefix: setPrefix,\n  get: getAsset,\n  match: getMatches,\n  setMiddleware: function(middleware) {\n    function getManifest() {\n      return JSON.parse(\n        middleware.fileSystem.readFileSync(\n          middleware.getFilenameFromUrl('/manifest.json')\n        )\n      );\n    }\n    if (middleware) {\n      instance.get = function getAssetWithMiddleware(name) {\n        const m = getManifest();\n        return prefix + m[name];\n      };\n      instance.match = function matchAssetWithMiddleware(match) {\n        const m = getManifest();\n        return Object.keys(m)\n          .filter(k => match.test(k))\n          .map(k => prefix + m[k]);\n      };\n    }\n  }\n};\n\nmodule.exports = instance;\n"
  },
  {
    "path": "common/generate_asset_map.js",
    "content": "/*\n  This code is included by both the server and frontend via\n  common/assets.js\n\n  When included from the server the export will be the function.\n\n  When included from the frontend (via webpack) the export will\n  be an object mapping file names to hashed file names. Example:\n  \"send_logo.svg\": \"send_logo.5fcfdf0e.svg\"\n*/\n\nconst fs = require('fs');\nconst path = require('path');\n\nfunction kv(f) {\n  return `\"${f}\": require('../assets/${f}')`;\n}\n\nmodule.exports = function() {\n  const files = fs.readdirSync(path.join(__dirname, '..', 'assets'));\n  const code = `module.exports = {\n    ${files.map(kv).join(',\\n')}\n  };`;\n  return {\n    code,\n    dependencies: files.map(f => require.resolve('../assets/' + f)),\n    cacheable: true\n  };\n};\n"
  },
  {
    "path": "common/readme.md",
    "content": "# Common Code\n\nThis directory contains code loaded by both the frontend `app` and backend `server`. The code here can be challenging to understand at first because the contexts for the two (three counting the dev server) environments that include them are quite different, but the purpose of these modules are quite simple, to provide mappings from the source assets (`copy-16.png`) to the concrete production assets (`copy-16.db66e0bf.svg`).\n\n## Generate Asset Map\n\nThis loader enumerates all the files in `assets/` so that `common/assets.js` can provide mappings from the source filename to the hashed filename used on the site."
  },
  {
    "path": "docker-compose.yml",
    "content": "version: \"3\"\nservices:\n  web:\n    build: .\n    links:\n      - redis\n    ports:\n      - \"1443:1443\"\n    environment:\n      - REDIS_HOST=redis\n  redis:\n    image: redis:alpine\n  selenium-firefox:\n    image: b4handjr/selenium-firefox\n    ports:\n      - \"${VNC_PORT:-5900}:5900\"\n    shm_size: 2g\n    volumes:\n      - .:/code\n"
  },
  {
    "path": "docs/CODEOWNERS",
    "content": "# flod as main contact for string changes\npublic/locales/en-US/*.ftl @flodolo\n"
  },
  {
    "path": "docs/acceptance-mobile.md",
    "content": "# Send V2 UX Mobile Acceptance and Spec Annotations\n\n`Date Created: 8/20/2018`\n\n## Acceptance Criteria\n\nAdapted from [this spreadsheet](https://airtable.com/shrkcBPOLkvNFOrpp)\n\n- [ ] It should look and feel of an Android App\n- [ ] It should look and feel like the Firefox Send Web Client\n\n### Main Screen\n- [ ] It should clearly Indicate the name of the product\n- [ ] If user has no existing Sends, it should make clear the primary benefits of the service (private, e2e encrypted, self-destructing file sharing)\n- [ ] It should allow users to access the file picker to create Send links\n- [ ] If the user has existing Sends, it should display a card-based list view of each [see Cards section below]\n\n### Non-Authenticated Users\n- [ ] It should make clear the benefits of a Firefox Account\n- [ ] It should allow users to log into or create a Firefox account\n- [ ] It should allow users to select and send multiple files in one URL\n- [ ] It should limit the sendable file size to 1GB\n- [ ] It should allow users to set an expiration time of 5 minutes, 1 hour, or 24 hours\n- [ ] It should allow users to set a download count of 1 downloads\n\n### Authenticated Users\n- [ ] It should indicate that the user is signed in via Firefox Account\n- [ ] It should allow the user to sign out\n- [ ] It should allow users to select and send multiple files in one URL\n- [ ] It should limit users to sending 2.5GB per Send\n- [ ] It should allow users to extend Send times up to 1 Week\n- [ ] It should allow users to extend Send download counts up to 100 times\n\n### Cards\n- [ ] It should display the name of the sent file/files\n- [ ] It should display the time remaining before expiration\n- [ ] It should display the number of downloads remaining before expiration\n- [ ] It should have a button that lets the user copy the send link to their clipboard\n- [ ] It should show a preview icon (not a thumbnail) that has some relationship to the file types or content being sent* (see 5.1 in spec)\n- [ ] It should have an overflow (meatball) menu that when triggered, gives the user share or delete buttons\n- [ ] While encrypting / pushing to server, it should display a progress meter and a cancel button\n- [ ] For authenticated users, it should be expandable to display all files in a send (5.1.1)\n- [ ] If user cancels Send, or Upload fails, it should display a warning in the card\n- [ ] It should display expired Sends below current sends with their UI greyed out and an expiration warning for 24 hours after expiration\n- [ ] It should remove expired cards from display after 24 hours\n- [ ] It should let users permanently delete records expired sends\n- [ ] It should display a visual indicator when a Send is password protected\n- [ ] It should allow the user to share via a native Android share sheet\n- [ ] It should allow me to create Send links through intents from other apps\n\n### General/other\n- [ ] It should allow users to set passwords to protect their Sends\n- [ ] It should warn users when they are trying to upload files larger than their share limit\n\n### Stretch\n- [ ] It should allow users to use the photo gallery to create Send links\n- [ ] It should allow users to use their camera to create Send links\n- [ ] It should allow users to opt into notification when a share link expires\n- [ ] It should allow users to opt into notifications when their link is downloaded\n\n## Annotations on Mobile Spec\nThis document tracks differences between the UX spec for Firefox Send and the intended MVP.\n\n[Spec Link](https://mozilla.invisionapp.com/share/GNN6KKOQ5XS)\n\n* 1.1: Spec describes toolbar which may not be possible given the application framework we're using. In particular, issues with the spec include the color, logo and different font weights may be an issue.\n* 1.2: Spec's treatment of FxA UI may be difficult to match. We should use the default OAuth implementation and re-evaluate UX once we see an implementation demo. Also, the landing page UI should display a log-in CTA directly and not require users click into the hamburger menu.\n* 2.1: MVP will only include file picker. Signed in users will be able to select multiple files. File selection flow will be Android-native. Probably don't have the ability to add notifications as in the last screen on this page.\n* 2.1: @fzzzy will provide screenshots of this flow for UX evaluation and comment.\n* 3.1.4: The spec shows deleting the last item in an unshared set returning the user to the picker menu. Instead, it should return to the app home page.\n* 3.1.5: Same as 3.1.5 notes. Both cases should show the warning dialog.\n* 4.1: We may not be able to do a thumbnail here. Instead we should specify a set of icons to be displayed.\n* 6.3: We're not going to allow cards to be edited. This page is deprecated.\n* 6.4: Swiping cards to delete is stretched.\n* 6.5: We're not 100% sure what happens on network connectivity errors, we should test this and adapt UX as necessary.\n* 7.1: The last screen on this page depicts a network error notification on the selection screen. Instead the user should hit the send button, be taken back to the cards and display the card as in 5.1.2\n* 7.3: May not be necessary...we can ask for permissions on install.\n* 8.1: Notifications do not block launch\n"
  },
  {
    "path": "docs/acceptance-web.md",
    "content": "# Send V2 UX Web Acceptance Criteria\n\n## General\n\n- [ ] It should match the spec provided.\n- [ ] It should have a feedback button\n- [ ] It should provide links to relevant legal documentation\n\n### Non-Authenticated Users\n\n- [ ] It should make clear the benefits of a Firefox Account\n- [ ] It should allow users to log into or create a Firefox account\n- [ ] It should allow users to select and send multiple files in one URL\n- [ ] It should limit the sendable file size to 1GB\n- [ ] It should allow users to set an expiration time of 5 minutes, 1 hour, or 24 hours\n- [ ] It should allow users to set an download count of 1 downloads\n\n### Authenticated Users\n\n- [ ] It should indicate that the user is signed in via Firefox Account\n- [ ] It should allow the user to sign out\n- [ ] It should allow users to select and send multiple files in one URL\n- [ ] It should limit users to sending 2.5GB per Send\n- [ ] It should allow users to extend Send times up to 1 Week\n- [ ] It should allow users to extend Send download counts up to 100 times\n\n### Main Screen\n\n- [ ] It should clearly indicate the name of the product\n- [ ] If user has no existing Sends, it should make clear the primary benefits of the service (private, e2e encrypted, self-destructing file sharing)\n- [ ] It should allow users to access the file picker to create Send links\n- [ ] It should allow users to drag and drop files\n- [ ] It should provide affordances to sign in to Send\n- [ ] If the user has existing Sends, it should display a card-based list view of each\n\n### Upload UI\n\n- [ ] It should allow users to continue to add files to their upload up to a set limit\n- [ ] It should allow users to set a password\n- [ ] It should let users delete items from their upload bundle\n\n### Uploading UI\n\n- [ ] It should display an affordance to demonstrate the status of an upload\n\n### Share UI\n\n- [ ] It should provide a copiable URL to the bundle\n\n### Download UI\n\n- [ ] It should prompt the user for a password if one is required\n- [ ] It should provide feedback for incorrect passwords\n- [ ] It should provide a description of Send to make clear what this service is\n- [ ] It should let the user see the files they are downloading\n- [ ] It should let the user download their files\n\n### Download Complete UI\n\n- [ ] It should indicate that a download is complete\n- [ ] It should provide a description of the Send service\n- [ ] It should provide a link back to the upload UI\n\n### Expiry UI\n\n- [ ] It should provide a generic message indicating a share has expired\n- [ ] It should allow the user to navigate back to the upload page\n\n### In Memory DL Page\n\n- [ ] It should show in case a user tries to download a large file on a suboptimal client\n- [ ] It should suggest the user use Firefox\n- [ ] It should let the user copy the download url"
  },
  {
    "path": "docs/build.md",
    "content": "Send has two build configurations, development and production. Both can be run via `npm` scripts, `npm start` for development and `npm run build` for production. Webpack is our only build tool and all configuration lives in [webpack.config.js](../webpack.config.js).\n\n# Development\n\n`npm start` launches a `webpack-dev-server` on port 8080 that compiles the assets and watches files for changes. It also serves the backend API and frontend unit tests via the `server/bin/dev.js` entrypoint. The frontend tests can be run in the browser by navigating to http://localhost:8080/test and will rerun automatically as the watched files are saved with changes.\n\n# Production\n\n`npm run build` compiles the assets and writes the files to the `dist/` directory. `npm run prod` launches an Express server on port 1443 that serves the backend API and frontend static assets from `dist/` via the `server/bin/prod.js` entrypoint.\n\n# Notable differences\n\n- Development compiles assets in memory, so no `dist/` directory is generated\n- Development does not enable CSP headers\n- Development frontend source is instrumented for code coverage\n- Only development includes sourcemaps\n- Only development exposes the `/test` route\n- Production sets Cache-Control immutable headers on the hashed static assets\n\n# Custom Loaders\n\nThe `build/` directory contains custom webpack loaders specific to Send. See [build/readme.md](../build/readme.md) for details on each loader."
  },
  {
    "path": "docs/deployment.md",
    "content": "## Requirements\nThis document describes how to do a full deployment of Firefox Send on your own Linux server. You will need:\n\n* A working (and ideally somewhat recent) installation of NodeJS and NPM\n* GIT\n* An Apache webserver\n* Optionally telnet, to be able to quickly check your installation\n\nFor Debian/Ubuntu systems this probably just means something like this:\n\n* apt install git apache2 nodejs npm telnet\n\n## Building\n* We assume an already configured virtual-host on your webserver with an existing empty htdocs folder\n* First, remove that htdocs folder - we will replace it with Firefox Send's version now\n* git clone https://github.com/mozilla/send.git htdocs\n* Make now sure you are NOT root but rather the user your webserver is serving files under (e.g. \"su www-data\" or whoever the owner of your htdocs folder is)\n* npm install\n* npm run build\n\n## Running\nTo have a permanently running version of Firefox Send as a background process:\n\n* Create a file \"run.sh\" with:\n```\n#!/bin/bash\nnohup su www-data -c \"npm run prod\" 2>/dev/null &\n```\n* chmod +x run.sh\n* ./run.sh\n\nNow the Firefox Send backend should be running on port 1443. You can check with:\n* telnet localhost 1443\n\n## Reverse Proxy\nOf course, we don't want to expose the service on port 1443. Instead we want our normal webserver to forward all requests to Firefox send (\"Reverse proxy\").\n\n# Apache webserver\n\n* a2enmod proxy\n* a2enmod proxy_http\n* a2enmod proxy_wstunnel\n\nIn your Apache virtual host configuration file, insert this:\n\n```\n    # Enable rewrite engine\n    RewriteEngine on\n\n    # Make sure the original domain name is forwarded to Send\n    # Otherwise the generated URLs will be wrong\n    ProxyPreserveHost on\n\n    # Make sure the generated URL is https://\n    RequestHeader set X-Forwarded-Proto https\n\n    # If it's a normal file (e.g. PNG, CSS) just return it\n    RewriteCond %{REQUEST_FILENAME} -f\n    RewriteRule .* - [L]\n\n    # If it's a websocket connection, redirect it to a Send WS connection\n    RewriteCond %{HTTP:Upgrade} =websocket [NC]\n    RewriteRule /(.*) ws://127.0.0.1:1443/$1 [P,L]\n\n    # Otherwise redirect it to a normal HTTP connection\n    RewriteRule ^/(.*)$ http://127.0.0.1:1443/$1 [P,QSA]\n    ProxyPassReverse  \"/\" \"http://127.0.0.1:1443\"\n```\n"
  },
  {
    "path": "docs/docker.md",
    "content": "## Setup\n\nRun `docker build -t send:latest .` to create an image or `docker-compose up` to run a full testable stack. *We don't recommend using docker-compose for production.*\n\n## Environment variables:\n\n| Name             | Description\n|------------------|-------------|\n| `PORT`           | Port the server will listen on (defaults to 1443).\n| `S3_BUCKET`  | The S3 bucket name.\n| `REDIS_HOST` | Host name of the Redis server.\n| `SENTRY_CLIENT` | Sentry Client ID\n| `SENTRY_DSN` | Sentry DSN\n| `MAX_FILE_SIZE` | in bytes (defaults to 2147483648)\n| `NODE_ENV`       | \"production\"\n| `BASE_URL`       | The HTTPS URL where traffic will be served (e.g. `https://send.firefox.com`)\n\n## Example:\n\n```sh\n$ docker run --net=host -e 'NODE_ENV=production' \\\n  -e 'S3_BUCKET=testpilot-p2p-dev' \\\n  -e 'REDIS_HOST=dyf9s2r4vo3.bolxr4.0001.usw2.cache.amazonaws.com' \\\n  -e 'SENTRY_CLIENT=https://51e23d7263e348a7a3b90a5357c61cb2@sentry.prod.mozaws.net/168' \\\n  -e 'SENTRY_DSN=https://51e23d7263e348a7a3b90a5357c61cb2:65e23d7263e348a7a3b90a5357c61c44@sentry.prod.mozaws.net/168' \\\n  -e 'BASE_URL=https://send.firefox.com' \\\n  mozilla/send:latest\n```\n"
  },
  {
    "path": "docs/encryption.md",
    "content": "# File Encryption\n\nSend use 128-bit AES-GCM encryption via the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) to encrypt files in the browser before uploading them to the server. The code is in [app/keychain.js](../app/keychain.js).\n\n## Steps\n\n### Uploading\n\n1. A new secret key is generated with `crypto.getRandomValues`\n2. The secret key is used to derive more keys via HKDF SHA-256\n    - a series of encryption keys for the file, via [ECE](https://tools.ietf.org/html/rfc8188) (AES-GCM)\n    - an encryption key for the file metadata (AES-GCM)\n    - a signing key for request authentication (HMAC SHA-256)\n3. The file and metadata are encrypted with their corresponding keys\n4. The encrypted data and signing key are uploaded to the server\n5. An owner token and the share url are returned by the server and stored in local storage\n6. The secret key is appended to the share url as a [#fragment](https://en.wikipedia.org/wiki/Fragment_identifier) and presented to the UI\n\n### Downloading\n\n1. The browser loads the share url page, which includes an authentication nonce\n2. The browser imports the secret key from the url fragment\n3. The same 3 keys as above are derived\n4. The browser signs the nonce with its signing key and requests the metadata\n5. The encrypted metadata is decrypted and presented on the page\n6. The browser makes another authenticated request to download the encrypted file\n7. The browser downloads and decrypts the file\n8. The file prompts the save dialog or automatically saves depending on the browser settings\n\n### Passwords\n\nA password may optionally be set to authenticate the download request. When a password is set the following steps occur.\n\n#### Sender\n\n1. The original signing key derived from the secret key is discarded\n2. A new signing key is generated via PBKDF2 from the user entered password and the full share url (including secret key fragment)\n3. The new key is sent to the server, authenticated by the owner token\n4. The server stores the new key and marks the record as needing a password\n\n#### Downloader\n\n1. The browser loads the share url page, which includes an authentication nonce and indicator that the file requires a password\n2. The user is prompted for the password and the signing key is derived\n3. The browser requests the metadata using the key to sign the nonce\n4. If the password was correct the metadata is returned, otherwise a 401\n"
  },
  {
    "path": "docs/experiments.md",
    "content": "# A/B experiment testing\n\nWe're using Google Analytics Experiments for A/B testing.\n\n## Creating an experiment\n\nNavigate to the Behavior > Experiments section of Google Analytics and click the \"Create experiment\" button.\n\nThe \"Objective for this experiment\" is the most complicated part. See the \"Promo click (Goal ID 4 / Goal Set 1)\" for an example.\n\nIn step 2 add as many variants as you plan to test. The urls are not important since we aren't using their js library to choose the variants. The name will show up in the report so choose good ones. \"Original page\" becomes variant 0 and each variant increments by one. We'll use the numbers in our `app/experiments.js` code.\n\nStep 3 contains some script that we'll ignore. The important thing here is the **Experiment ID**. This is the value we need to name our experiment in `app/experiments.js`. Save the changes so far and wait until the code containing the experiment has been deployed to production **before** starting the experiment.\n\n## Experiment code\n\nCode for experiments live in [app/experiments.js](../app/experiments.js). There's an `experiments` object that contains the logic for deciding whether an experiment should run, which variant to use, and what to do. Each object needs to have these functions:\n\n### `eligible` function\n\nThis function returns a boolean of whether this experiment should be active for this session. Any data available to the page can be used determine the result.\n\n### `variant` function\n\nThis function returns which experimental group this session is placed in. The variant values need to match the values set up in Google Analytics, usually 0 thru N-1. This value is usually picked at random based on what percentage of each variant is desired.\n\n### `run` function\n\nThis function gets the `variant` value chosen by the variant function and the `state` and `emitter` objects from the app. This function can do anything needed to change the app based on the experiment. A common pattern is to set or change a value on `state` that will be picked up by other parts of the app, like ui templates, to change how it looks or behaves.\n\n### Example\n\nHere's a full example of the experiment object:\n\n```js\nconst experiments = {\n  S9wqVl2SQ4ab2yZtqDI3Dw: { // The Experiment ID from Google Analytics\n    id: 'S9wqVl2SQ4ab2yZtqDI3Dw',\n    run: function(variant, state, emitter) {\n      switch (variant) {\n        case 1:\n          state.promo = 'blue';\n          break;\n        case 2:\n          state.promo = 'pink';\n          break;\n        default:\n          state.promo = 'grey';\n      }\n      emitter.emit('render');\n    },\n    eligible: function() {\n      return (\n        !/firefox|fxios/i.test(navigator.userAgent) &&\n        document.querySelector('html').lang === 'en-US'\n      );\n    },\n    variant: function(state) {\n      const n = this.luckyNumber(state);\n      if (n < 0.33) {\n        return 0;\n      }\n      return n < 0.66 ? 1 : 2;\n    },\n    luckyNumber: function(state) {\n      return luckyNumber(\n        `${this.id}:${state.storage.get('testpilot_ga__cid')}`\n      );\n    }\n  }\n};\n```\n\n## Reporting results\n\nAll metrics pings will include the variant and experiment id, but it's usually important to trigger a specific event to be counted as the experiment goal (the \"Objective for this experiment\" part from setup). Use an 'experiment' event to do this. For example:\n\n```js\nemit('experiment', { cd3: 'promo' });\n```\n\nwhere `emit` is the app emitter function passed to the [route handler](https://github.com/choojs/choo#approuteroutename-handlerstate-emit)\n\nThe second argument can be an object with any additional parameters. It  usually includes a custom dimension that we chose to filter on while creating the experiment in Google Analytics."
  },
  {
    "path": "docs/faq.md",
    "content": "## How big of a file can I transfer with Firefox Send?\n\nThere is a 2.5GB file size limit built in to Send(1GB for non-signed in users), however, in practice you may\nbe unable to send files that large.  Send encrypts and decrypts the files in\nthe browser which is great for security but will tax your system resources.  In\nparticular you can expect to see your memory usage go up by at least the size\nof the file when the transfer is processing.  You can see [the results of some\ntesting](https://github.com/mozilla/send/issues/170#issuecomment-314107793).\nFor the most reliable operation on common computers, it’s probably best to stay\nunder a few hundred megabytes.\n\n## Why is my browser not supported?\n\nWe’re using the [Web Cryptography JavaScript API with the AES-GCM\nalgorithm](https://www.w3.org/TR/WebCryptoAPI/#aes-gcm) for our encryption.\nMany browsers support this standard and should work fine, but some have not\nimplemented it yet (mobile browsers lag behind on this, in\nparticular).\n\n## Why does Firefox Send require JavaScript?\n\nFirefox Send uses JavaScript to:\n\n- Encrypt and decrypt files locally on the client instead of the server.\n- Render the user interface.\n- Manage translations on the website into [various different languages](https://github.com/mozilla/send#localization).\n- Collect data to help us improve Send in accordance with our [Terms & Privacy](https://send.firefox.com/legal).\n\nSince Send is an open source project, you can see all of the cool ways we use JavaScript by [examining our code](https://github.com/mozilla/send/).\n\n## How long are files available for?\n\nFiles are available to be downloaded for 24 hours, after which they are removed\nfrom the server.  They are also removed immediately once the download limit is reached.\n\n## Can a file be downloaded more than once?\n\nYes, once a file is submitted to Send you can select the download limit.\n\n\n*Disclaimer: Send is an experiment and under active development.  The answers\nhere may change as we get feedback from you and the project matures.*\n"
  },
  {
    "path": "docs/localization.md",
    "content": "# Localization\n\nSend is localized in over 50 languages. We use the [fluent](http://projectfluent.org/) library and store our translations in [FTL](http://projectfluent.org/fluent/guide/) files in `public/locales/`. `en-US` is our base language, and other languages are managed by [pontoon](https://pontoon.mozilla.org/projects/test-pilot-firefox-send/).\n\n## Process\n\nStrings are added or removed from [public/locales/en-US/send.ftl] as needed. Strings **MUST NOT** be *changed* after they've been commited and pushed to master. Changing a string requires creating a new ID with a new name (preferably descriptive instead of incremented) and deletion of the obsolete ID. It's often useful to add a comment above the string with info about how and where the string is used.\n\nOnce new strings are commited to master they are available for translators in Pontoon. All languages other than `en-US` should be edited via Pontoon. Translations get automatically commited to the github master branch.\n\n### Activation\n\nThe development environment includes all locales in `public/locales` via the `L10N_DEV` environment variable. Production uses `package.json` as the list of locales to use. Once a locale has enough string coverage it should be added to `package.json`.\n\n## Code\n\nIn `app/` we use the `state.translate()` function to translate strings to the best matching language base on the user's `Accept-Language` header. It's a wrapper around fluent's [FluentBundle.format](http://projectfluent.org/fluent.js/fluent/FluentBundle.html). It works the same for both server and client side rendering.\n\n### Examples\n\n```js\n// simple string\nconst finishedString = state.translate('downloadFinish')\n// with parameters\nconst progressString = state.translate('downloadingPageProgress', {\n  filename: state.fileInfo.name,\n  size: bytes(state.fileInfo.size)\n})\n```\n"
  },
  {
    "path": "docs/metrics.md",
    "content": "# Send V2 Metrics Definitions\n\n## Key Value Prop\n\nQuickly and privately transfer large files from any device to any device.\n\n## Key Business Question to Answer\n\nIs the value proposition of a large encrypted file transfer service enough to drive Firefox Account relationships for non-Firefox users.\n\n## Hypotheses to Test\n\n### Primary - In support of Relationships KPI\n\nWe believe that a privacy-respecting file transfer service can drive Firefox Accounts beyond the Firefox Browser.\n\nWe will know this to be true when we see 250k Firefox Account creations from non-Firefox contexts w/in six months of launch.\n\n### Secondary - In support of Revenue KPI\n\nWe believe that a privacy respecting service accessible beyond the reach of Firefox will provide a valuable platform to research, communicate with, and market to conscious choosers we have traditionally found hard to reach.\n\nWe will know this to be true when we can conduct six research tasks (surveys, A/B tests, fake doors, etc) in support of premium services KPIs in the first six months after launch.\n\n## Overview of Key Measures\n\n* Number of people using the service to send and receive files\n  * Why: measure of service size. Important for understanding addressable market size\n* Percent of users who have or create an FxAccount via Send\n  * Why: representation of % of any service users who might be amenable to an upsell\n* % of downloaders who convert into uploaders\n  * Why: represents a measure of our key growth-loop potential\n* Count of uploads and size\n  * Why: Represents cost of service on a running basis\n\n## Key Funnels\n* App Open or Visit `--- DESIRED OUTCOME --->` Successful Upload\n* Download UI Visit `--- DESIRED OUTCOME --->` Successful Download\n* FxA UI Engagement `--- DESIRED OUTCOME --->` Authenticate\n* **STRETCH** App Open or Visit `--- DESIRED OUTCOME --->` Successful Download\n\n## Amplitude Schema\n\nPlease see, **See Amplitude HTTP API**(https://amplitude.zendesk.com/hc/en-us/articles/204771828) for HTTP API reference.\n\n## Metric Events\n\nIn support of our KPIs we collect events from two separate contexts, server and client. The events are designed to have minimal correlation between contexts.\n\nServer events collect lifecycle information about individual uploads but no user information; also time precision is truncated to hour increments. Client events collect information about how users interact with the UI but no upload identifiers.\n\n### Server Events\n\nServer events allow us to aggregate data about file lifecycle without collecting data about individual users. In this context `user_id` and `user_properties` describe the uploaded archive.\n\n* `session_id` -1 (not part of a session)\n* `user_id` hash of (archive_id + owner_id)\n* `app_version` package.json version\n* `time` timestamp truncated to hour precision\n* `country`\n* `region`\n* `event_type` [server_upload | server_download | server_delete]\n* `user_properties`\n  * `download_limit` set number of downloads\n  * `time_limit` set expiry duration\n  * `size` approximate size (log10)\n  * `anonymous` true if anonymous, false if fxa\n* `event_properties`\n  * `download_count` downloads completed\n  * `ttl` time remaining before expiry truncated to hour\n  * `agent` the browser name or first 6 characters of the user agent that made the request\n\n### Client Events\n\nClient events allow us to aggregate data about how the user interface is being used without tracking the lifecycle of individual files. In this context `user_id` and `user_properties` describe the user. The `user_id` and `device_id` change for all users at the beginning of each month.\n\n* `session_id` timestamp\n* `user_id` hash of (fxa_id + Date.year + Date.month)\n* `device_id` hash of (localStorage random id + Date.year + Date.month)\n* `platform` [web | android]\n* `country`\n* `region`\n* `language`\n* `time` timestamp\n* `os_name`\n* `event_type` [client_visit | client_upload | client_download | client_delete | client_login | client_logout]\n* `event_properties`\n  * `browser`\n  * `browser_version`\n  * `status` [ ok | error | cancel ]\n  * Event specific properties (see below)\n* `user_properties`\n  * `active_count` number of active uploads\n  * `anonymous` true if anonymous, false if fxa\n  * `experiments` list of experiment ids the user is participating in\n  * `first_action` how this use came to Send the first time [ upload | download ]\n\n#### Visit Event\n\n  * `entrypoint` [ upload | download ]\n\n#### Upload Event\n\n  * `download_limit` download limit\n  * `file_count` number of files\n  * `password_protected` boolean\n  * `size` approximate size (log10)\n  * `time_limit` time limit\n  * `duration` approximate transfer duration (log10)\n\n#### Download Event\n\n  * `password_protected` boolean\n  * `size` approximate size (log10)\n  * `duration` approximate transfer duration (log10)\n\n#### Delete Event\n\n  * `age` hours since uploaded\n  * `downloaded` downloaded at least once\n\n#### Login Event\n\n  * `trigger` [button | time | count | size]\n\n#### Logout Event\n\n  * `trigger` [button | timeout]\n"
  },
  {
    "path": "docs/notes/streams.md",
    "content": "# Web Streams\n\n- API\n  - https://developer.mozilla.org/en-US/docs/Web/API/Streams_API\n- Reference Implementation\n  - https://github.com/whatwg/streams/tree/master/reference-implementation\n- Examples\n  - https://github.com/mdn/dom-examples/tree/master/streams\n- Polyfill\n  - https://github.com/MattiasBuelens/web-streams-polyfill\n\n# Encrypted Content Encoding\n\n- Spec\n  - https://trac.tools.ietf.org/html/rfc8188\n- node.js implementation\n  - https://github.com/web-push-libs/encrypted-content-encoding/tree/master/nodejs\n\n# Other APIs\n\n- Blobs\n  - https://developer.mozilla.org/en-US/docs/Web/API/Blob\n- ArrayBuffers, etc\n  - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer\n  - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array\n- FileReader\n  - https://developer.mozilla.org/en-US/docs/Web/API/FileReader\n\n# Other\n\n- node.js Buffer browser library\n  - https://github.com/feross/buffer\n- StreamSaver\n  - https://github.com/jimmywarting/StreamSaver.js\n"
  },
  {
    "path": "docs/takedowns.md",
    "content": "## Take-down process\n\nIn cases of a DMCA notice, or other abuse yet to be determined, a file has to be removed from the service.\n\nFiles can be delisted and made inaccessible by removing their record from Redis.\n\nSend share links contain the `id` of the file, for example `https://send.firefox.com/download/3d9d2bb9a1`\n\nFrom a host with access to the Redis server run a `DEL` command with the file id.\n\nFor example:\n\n```sh\nredis-cli DEL 3d9d2bb9a1\n```\n\nOther redis-cli parameters like `-h` may also be required. See [redis-cli docs](https://redis.io/topics/rediscli) for more info.\n\nThe encrypted file resides on S3 as the same `id` under the bucket that the app was configured with as `S3_BUCKET`. The file can be managed if it has not already expired with the [AWS cli](https://docs.aws.amazon.com/cli/latest/reference/s3/index.html) or AWS web console."
  },
  {
    "path": "ios/generate-bundle.js",
    "content": "const child_process = require('child_process');\nconst fs = require('fs');\nconst path = require('path');\n\nchild_process.execSync('npm run build');\n\nconst prefix = path.join('..', 'dist');\nconst json_string = fs.readFileSync(path.join(prefix, 'manifest.json'));\nconst manifest = JSON.parse(json_string);\n\nconst ios_filename = manifest['ios.js'];\nfs.writeFileSync(\n  'send-ios/assets/ios.js',\n  fs.readFileSync(`${prefix}${ios_filename}`)\n);\n\nconst vendor_filename = manifest['vendor.js'];\nfs.writeFileSync(\n  'send-ios/assets/vendor.js',\n  fs.readFileSync(`${prefix}${vendor_filename}`)\n);\n"
  },
  {
    "path": "ios/ios.js",
    "content": "/* global window, document, fetch */\n\nconst MAXFILESIZE = 1024 * 1024 * 1024 * 2;\n\nconst EventEmitter = require('events');\nconst emitter = new EventEmitter();\n\nfunction dom(tagName, attributes, children = []) {\n  const node = document.createElement(tagName);\n  for (const name in attributes) {\n    if (name.indexOf('on') === 0) {\n      node[name] = attributes[name];\n    } else if (name === 'htmlFor') {\n      node.htmlFor = attributes.htmlFor;\n    } else if (name === 'className') {\n      node.className = attributes.className;\n    } else {\n      node.setAttribute(name, attributes[name]);\n    }\n  }\n  if (!(children instanceof Array)) {\n    children = [children];\n  }\n  for (let child of children) {\n    if (typeof child === 'string') {\n      child = document.createTextNode(child);\n    }\n    node.appendChild(child);\n  }\n  return node;\n}\n\nfunction uploadComplete(file) {\n  document.body.innerHTML = '';\n  const input = dom('input', { id: 'url', value: file.url });\n  const copy = dom(\n    'button',\n    {\n      id: 'copy-button',\n      className: 'button',\n      onclick: () => {\n        window.webkit.messageHandlers['copy'].postMessage(input.value);\n        copy.textContent = 'Copied!';\n        setTimeout(function() {\n          copy.textContent = 'Copy to clipboard';\n        }, 2000);\n      }\n    },\n    'Copy to clipboard'\n  );\n  const node = dom(\n    'div',\n    { id: 'striped' },\n    dom('div', { id: 'white' }, [\n      input,\n      copy,\n      dom(\n        'button',\n        { id: 'send-another', className: 'button', onclick: render },\n        'Send another file'\n      )\n    ])\n  );\n  document.body.appendChild(node);\n}\n\nconst state = {\n  storage: {\n    files: [],\n    remove: function(fileId) {\n      console.log('REMOVE FILEID', fileId);\n    },\n    writeFile: function(file) {\n      console.log('WRITEFILE', file);\n    },\n    addFile: uploadComplete,\n    totalUploads: 0\n  },\n  transfer: null,\n  uploading: false,\n  settingPassword: false,\n  passwordSetError: null,\n  route: '/'\n};\n\nfunction upload(event) {\n  console.log('UPLOAD');\n  event.preventDefault();\n  const target = event.target;\n  const file = target.files[0];\n  if (file.size === 0) {\n    return;\n  }\n  if (file.size > MAXFILESIZE) {\n    console.log('file too big (no bigger than ' + MAXFILESIZE + ')');\n    return;\n  }\n\n  emitter.emit('upload', { file: file, type: 'click' });\n}\n\nfunction render() {\n  document.body.innerHTML = '';\n  const striped = dom(\n    'div',\n    { id: 'striped' },\n    dom('div', { id: 'white' }, [\n      dom('label', { id: 'label', htmlFor: 'input' }, 'Choose file'),\n      dom('input', {\n        id: 'input',\n        type: 'file',\n        name: 'input',\n        onchange: upload\n      })\n    ])\n  );\n  document.body.appendChild(striped);\n}\n\nemitter.on('render', function() {\n  document.body.innerHTML = '';\n  const percent =\n    (state.transfer.progress[0] / state.transfer.progress[1]) * 100;\n  const node = dom(\n    'div',\n    { style: 'background-color: white; width: 100%' },\n    dom('span', {\n      style: `display: inline-block; width: ${percent}%; background-color: blue`\n    })\n  );\n  document.body.appendChild(node);\n});\n\nemitter.on('pushState', function(path) {\n  console.log('pushState ' + path + ' ' + JSON.stringify(state));\n});\n\nconst controller = require('../app/controller').default;\ntry {\n  controller(state, emitter);\n} catch (e) {\n  console.error('error' + e);\n  console.error(e);\n}\n\nfunction sendBase64EncodedFromSwift(encoded) {\n  fetch(encoded)\n    .then(res => res.blob())\n    .then(blob => {\n      emitter.emit('upload', { file: blob, type: 'share' });\n    });\n}\n\nwindow.sendBase64EncodedFromSwift = sendBase64EncodedFromSwift;\n\nrender();\n\nwindow.webkit.messageHandlers['loaded'].postMessage('');\n"
  },
  {
    "path": "ios/send-ios/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  send-ios\n//\n//  Created by Donovan Preston on 7/19/18.\n//\n\nimport UIKit\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {\n        // Override point for customization after application launch.\n        return true\n    }\n\n    func applicationWillResignActive(_ application: UIApplication) {\n        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n    }\n\n    func applicationDidEnterBackground(_ application: UIApplication) {\n        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n    }\n\n    func applicationWillEnterForeground(_ application: UIApplication) {\n        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n    }\n\n    func applicationDidBecomeActive(_ application: UIApplication) {\n        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n    }\n\n    func applicationWillTerminate(_ application: UIApplication) {\n        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n    }\n\n\n}\n\n"
  },
  {
    "path": "ios/send-ios/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "ios/send-ios/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "ios/send-ios/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" systemVersion=\"17A277\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "ios/send-ios/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14113\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14088\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" customModule=\"send_ios\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <wkWebView contentMode=\"scaleToFill\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ZDA-L3-KYx\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"20\" width=\"375\" height=\"647\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMinX=\"YES\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\" flexibleMaxY=\"YES\"/>\n                                <color key=\"backgroundColor\" red=\"0.36078431370000003\" green=\"0.38823529410000002\" blue=\"0.4039215686\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                <wkWebViewConfiguration key=\"configuration\">\n                                    <audiovisualMediaTypes key=\"mediaTypesRequiringUserActionForPlayback\" none=\"YES\"/>\n                                    <wkPreferences key=\"preferences\"/>\n                                </wkWebViewConfiguration>\n                            </wkWebView>\n                        </subviews>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                    <connections>\n                        <outlet property=\"webView\" destination=\"ZDA-L3-KYx\" id=\"I8v-hp-8pp\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"136.80000000000001\" y=\"110.19490254872565\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "ios/send-ios/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "ios/send-ios/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  send-ios\n//\n//  Created by Donovan Preston on 7/19/18.\n//\n\nimport UIKit\nimport WebKit\n\nclass ViewController: UIViewController, WKScriptMessageHandler {\n    @IBOutlet var webView: WKWebView!\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        self.webView.frame = self.view.bounds\n        self.webView?.configuration.userContentController.add(self, name: \"loaded\")\n        self.webView?.configuration.userContentController.add(self, name: \"copy\")\n        if let url = Bundle.main.url(\n            forResource: \"index\",\n            withExtension: \"html\",\n            subdirectory: \"assets\") {\n            webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())\n        }\n    }\n\n    public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {\n        print(\"Message received: \\(message.name) with body: \\(message.body)\")\n        UIPasteboard.general.string = \"\\(message.body)\"\n    }\n\n    override func didReceiveMemoryWarning() {\n        super.didReceiveMemoryWarning()\n        // Dispose of any resources that can be recreated.\n    }\n\n\n}\n\n"
  },
  {
    "path": "ios/send-ios/assets/index.css",
    "content": "body {\n  background: url('background_1.jpg');\n  display: flex;\n  flex-direction: row;\n  flex: auto;\n  justify-content: center;\n  align-items: center;\n  padding: 0 20px;\n  box-sizing: border-box;\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n}\n\n#striped {\n  background-image: repeating-linear-gradient(\n    45deg,\n    white,\n    white 5px,\n    #ea000e 5px,\n    #ea000e 25px,\n    white 25px,\n    white 30px,\n    #0083ff 30px,\n    #0083ff 50px\n  );\n  height: 350px;\n  width: 480px;\n}\n\n#white {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  flex-direction: column;\n  height: 100%;\n  background-color: white;\n  margin: 0 10px;\n  padding: 1px 10px 0 10px;\n}\n\n#label {\n  background: #0297f8;\n  border: 1px solid #0297f8;\n  color: white;\n  font-size: 24px;\n  font-weight: 500;\n  height: 60px;\n  width: 200px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n\n#input {\n  display: none;\n}\n\n#url {\n  flex: 1;\n  width: 100%;\n  height: 32px;\n  font-size: 24px;\n  margin-top: 1em;\n}\n\n.button {\n  flex: 1;\n  display: block;\n  background: #0297f8;\n  border: 1px solid #0297f8;\n  color: white;\n  font-size: 24px;\n  font-weight: 500;\n  width: 95%;\n  height: 32px;\n  margin-top: 1em;\n}\n\n#send-another {\n  margin-bottom: 1em;\n}\n"
  },
  {
    "path": "ios/send-ios/assets/index.html",
    "content": "\n  <!DOCTYPE html>\n  <html lang=\"en-US\">\n  <head>\n    <title>Send</title>\n    <link href=\"index.css\" rel=\"stylesheet\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\" />\n  </head>\n  <body>\n<script>\n  const EXPIRE_SECONDS = 86400;\n</script>\n<script src=\"vendor.js\"></script>\n<script src=\"ios.js\"></script>\n  </body>\n  </html>\n  \n"
  },
  {
    "path": "ios/send-ios/help.html",
    "content": "<doctype html>\n    <body>\n        HELLO WORLD\n    </body>\n</html>\n"
  },
  {
    "path": "ios/send-ios-action-extension/ActionViewController.swift",
    "content": "//\n//  ActionViewController.swift\n//  send-ios-action-extension\n//\n//  Created by Donovan Preston on 7/26/18.\n//\n\nimport UIKit\nimport WebKit\nimport MobileCoreServices\n\nvar typesToLoad = [(\"com.adobe.pdf\", \"application/pdf\"), (\"public.png\", \"image/png\"),\n                   (\"public.jpeg\", \"image/jpeg\"), (\"public.jpeg-2000\", \"image/jp2\"),\n                   (\"com.compuserve.gif\", \"image/gif\"), (\"com.microsoft.bmp\", \"image/bmp\"),\n                   (\"public.plain-text\", \"text/plain\")]\n\nclass ActionViewController: UIViewController, WKScriptMessageHandler {\n\n    @IBOutlet var webView: WKWebView!\n    var typeToSend: String?\n    var dataToSend: Data?\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        self.webView.frame = self.view.bounds\n        self.webView?.configuration.userContentController.add(self, name: \"loaded\")\n        self.webView?.configuration.userContentController.add(self, name: \"copy\")\n\n        if let url = Bundle.main.url(\n            forResource: \"index\",\n            withExtension: \"html\",\n            subdirectory: \"assets\") {\n            self.webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())\n        }\n        // Get the item[s] we're handling from the extension context.\n        \n        for item in self.extensionContext!.inputItems as! [NSExtensionItem] {\n            for provider in item.attachments! as! [NSItemProvider] {\n                for (type, mimeType) in typesToLoad {\n                    if provider.hasItemConformingToTypeIdentifier(type) {\n                        provider.loadDataRepresentation(forTypeIdentifier: type, completionHandler: { (data, error) in\n                            OperationQueue.main.addOperation {\n                                self.typeToSend = mimeType\n                                self.dataToSend = data\n                            }\n                        })\n                        return\n                    }\n                }\n            }\n        }\n    }\n\n    public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {\n        print(\"Message received: \\(message.name) with body: \\(message.body)\")\n        if (message.name == \"loaded\") {\n                let stringToSend = \"window.sendBase64EncodedFromSwift('data:\\(self.typeToSend ?? \"application/octet-stream\");base64,\\(self.dataToSend?.base64EncodedString() ?? \"\")')\";\n                self.webView.evaluateJavaScript(stringToSend) { (object: Any?, error: Error?) -> Void in\n                    print(\"completed\")\n                }\n        } else if (message.name == \"copy\") {\n            UIPasteboard.general.string = \"\\(message.body)\"\n        }\n    }\n\n    override func didReceiveMemoryWarning() {\n        super.didReceiveMemoryWarning()\n        // Dispose of any resources that can be recreated.\n    }\n\n    @IBAction func done() {\n        // Return any edited content to the host app.\n        // This template doesn't do anything, so we just echo the passed in items.\n        self.extensionContext!.completeRequest(returningItems: self.extensionContext!.inputItems, completionHandler: nil)\n    }\n\n}\n"
  },
  {
    "path": "ios/send-ios-action-extension/Base.lproj/MainInterface.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14113\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"ObA-dk-sSI\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14088\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Image-->\n        <scene sceneID=\"7MM-of-jgj\">\n            <objects>\n                <viewController title=\"Image\" id=\"ObA-dk-sSI\" customClass=\"ActionViewController\" customModule=\"send_ios_action_extension\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"zMn-AG-sqS\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"528\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <navigationBar contentMode=\"scaleToFill\" horizontalCompressionResistancePriority=\"751\" verticalCompressionResistancePriority=\"751\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"NOA-Dm-cuz\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"20\" width=\"320\" height=\"44\"/>\n                                <items>\n                                    <navigationItem id=\"3HJ-uW-3hn\">\n                                        <barButtonItem key=\"leftBarButtonItem\" title=\"Done\" style=\"done\" id=\"WYi-yp-eM6\">\n                                            <connections>\n                                                <action selector=\"done\" destination=\"ObA-dk-sSI\" id=\"Qdu-qn-U6V\"/>\n                                            </connections>\n                                        </barButtonItem>\n                                    </navigationItem>\n                                </items>\n                            </navigationBar>\n                            <wkWebView contentMode=\"scaleToFill\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"evD-vF-hKQ\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"64\" width=\"320\" height=\"464\"/>\n                                <autoresizingMask key=\"autoresizingMask\"/>\n                                <color key=\"backgroundColor\" red=\"0.36078431370000003\" green=\"0.38823529410000002\" blue=\"0.4039215686\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                <wkWebViewConfiguration key=\"configuration\">\n                                    <audiovisualMediaTypes key=\"mediaTypesRequiringUserActionForPlayback\" none=\"YES\"/>\n                                    <wkPreferences key=\"preferences\"/>\n                                </wkWebViewConfiguration>\n                            </wkWebView>\n                        </subviews>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <constraints>\n                            <constraint firstItem=\"VVe-Uw-JpX\" firstAttribute=\"trailing\" secondItem=\"NOA-Dm-cuz\" secondAttribute=\"trailing\" id=\"A05-Pj-hrr\"/>\n                            <constraint firstItem=\"NOA-Dm-cuz\" firstAttribute=\"leading\" secondItem=\"VVe-Uw-JpX\" secondAttribute=\"leading\" id=\"HxO-8t-aoh\"/>\n                            <constraint firstItem=\"NOA-Dm-cuz\" firstAttribute=\"top\" secondItem=\"VVe-Uw-JpX\" secondAttribute=\"top\" id=\"we0-1t-bgp\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"VVe-Uw-JpX\"/>\n                    </view>\n                    <freeformSimulatedSizeMetrics key=\"simulatedDestinationMetrics\"/>\n                    <size key=\"freeformSize\" width=\"320\" height=\"528\"/>\n                    <connections>\n                        <outlet property=\"view\" destination=\"zMn-AG-sqS\" id=\"Qma-de-2ek\"/>\n                        <outlet property=\"webView\" destination=\"evD-vF-hKQ\" id=\"DVP-CH-cJP\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"X47-rx-isc\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"137.59999999999999\" y=\"98.950524737631198\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "ios/send-ios-action-extension/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleDisplayName</key>\n\t<string>send-ios-action-extension</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>XPC!</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>NSExtension</key>\n\t<dict>\n\t\t<key>NSExtensionAttributes</key>\n\t\t<dict>\n\t\t\t<key>NSExtensionActivationRule</key>\n\t\t\t<string>SUBQUERY (\n            extensionItems,\n            $extensionItem,\n            SUBQUERY (\n            $extensionItem.attachments,\n            $attachment,\n            (\n            ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;com.adobe.pdf&quot;\n            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;public.image&quot;\n            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;public.plain-text&quot;\n            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;public.png&quot;\n            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;public.jpeg&quot;\n            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;public.jpeg-2000&quot;\n            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;com.compuserve.gif&quot;\n            || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;com.microsoft.bmp&quot;\n            )\n            ).@count == 1\n            ).@count == 1</string>\n\t\t</dict>\n\t\t<key>NSExtensionMainStoryboard</key>\n\t\t<string>MainInterface</string>\n\t\t<key>NSExtensionPointIdentifier</key>\n\t\t<string>com.apple.ui-services</string>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "ios/send-ios.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 50;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\tE34149C621017A3A00930775 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E34149C521017A3A00930775 /* AppDelegate.swift */; };\n\t\tE34149C821017A3A00930775 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E34149C721017A3A00930775 /* ViewController.swift */; };\n\t\tE34149CB21017A3A00930775 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E34149C921017A3A00930775 /* Main.storyboard */; };\n\t\tE34149CD21017A3D00930775 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E34149CC21017A3D00930775 /* Assets.xcassets */; };\n\t\tE34149D021017A3D00930775 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E34149CE21017A3D00930775 /* LaunchScreen.storyboard */; };\n\t\tE355478521028193009D206E /* help.html in Resources */ = {isa = PBXBuildFile; fileRef = E355478421028193009D206E /* help.html */; };\n\t\tE355478921092E22009D206E /* assets in Resources */ = {isa = PBXBuildFile; fileRef = E355478821092E22009D206E /* assets */; };\n\t\tE355478C210A534F009D206E /* ios.js in Resources */ = {isa = PBXBuildFile; fileRef = E355478B210A534F009D206E /* ios.js */; };\n\t\tE355478E210A5357009D206E /* generate-bundle.js in Resources */ = {isa = PBXBuildFile; fileRef = E355478D210A5357009D206E /* generate-bundle.js */; };\n\t\tE397A0B2210A641C00A978D4 /* ActionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E397A0B1210A641C00A978D4 /* ActionViewController.swift */; };\n\t\tE397A0B5210A641C00A978D4 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E397A0B3210A641C00A978D4 /* MainInterface.storyboard */; };\n\t\tE397A0B9210A641C00A978D4 /* send-ios-action-extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = E397A0AF210A641C00A978D4 /* send-ios-action-extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };\n\t\tE397A0BF210A6B5500A978D4 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = E397A0BE210A6B5500A978D4 /* assets */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\tE397A0B7210A641C00A978D4 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = E34149BA21017A3900930775 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = E397A0AE210A641C00A978D4;\n\t\t\tremoteInfo = \"send-ios-action-extension\";\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\tE397A0BD210A641C00A978D4 /* Embed App Extensions */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 13;\n\t\t\tfiles = (\n\t\t\t\tE397A0B9210A641C00A978D4 /* send-ios-action-extension.appex in Embed App Extensions */,\n\t\t\t);\n\t\t\tname = \"Embed App Extensions\";\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\tE34149C221017A3900930775 /* send-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = \"send-ios.app\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tE34149C521017A3A00930775 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\tE34149C721017A3A00930775 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\tE34149CA21017A3A00930775 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\tE34149CC21017A3D00930775 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\tE34149CF21017A3D00930775 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\tE34149D121017A3D00930775 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tE355478421028193009D206E /* help.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = help.html; sourceTree = \"<group>\"; };\n\t\tE355478821092E22009D206E /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = \"<group>\"; };\n\t\tE355478B210A534F009D206E /* ios.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = ios.js; sourceTree = SOURCE_ROOT; };\n\t\tE355478D210A5357009D206E /* generate-bundle.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = \"generate-bundle.js\"; sourceTree = SOURCE_ROOT; };\n\t\tE397A0AF210A641C00A978D4 /* send-ios-action-extension.appex */ = {isa = PBXFileReference; explicitFileType = \"wrapper.app-extension\"; includeInIndex = 0; path = \"send-ios-action-extension.appex\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tE397A0B1210A641C00A978D4 /* ActionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionViewController.swift; sourceTree = \"<group>\"; };\n\t\tE397A0B4210A641C00A978D4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = \"<group>\"; };\n\t\tE397A0B6210A641C00A978D4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tE397A0BE210A6B5500A978D4 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = assets; path = \"send-ios/assets\"; sourceTree = SOURCE_ROOT; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tE34149BF21017A3900930775 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tE397A0AC210A641C00A978D4 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tE34149B921017A3900930775 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tE34149C421017A3900930775 /* send-ios */,\n\t\t\t\tE397A0B0210A641C00A978D4 /* send-ios-action-extension */,\n\t\t\t\tE34149C321017A3900930775 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tE34149C321017A3900930775 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tE34149C221017A3900930775 /* send-ios.app */,\n\t\t\t\tE397A0AF210A641C00A978D4 /* send-ios-action-extension.appex */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tE34149C421017A3900930775 /* send-ios */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tE355478D210A5357009D206E /* generate-bundle.js */,\n\t\t\t\tE355478B210A534F009D206E /* ios.js */,\n\t\t\t\tE34149C521017A3A00930775 /* AppDelegate.swift */,\n\t\t\t\tE34149C721017A3A00930775 /* ViewController.swift */,\n\t\t\t\tE34149C921017A3A00930775 /* Main.storyboard */,\n\t\t\t\tE34149CC21017A3D00930775 /* Assets.xcassets */,\n\t\t\t\tE34149CE21017A3D00930775 /* LaunchScreen.storyboard */,\n\t\t\t\tE34149D121017A3D00930775 /* Info.plist */,\n\t\t\t\tE355478421028193009D206E /* help.html */,\n\t\t\t\tE355478821092E22009D206E /* assets */,\n\t\t\t);\n\t\t\tpath = \"send-ios\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tE397A0B0210A641C00A978D4 /* send-ios-action-extension */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tE397A0BE210A6B5500A978D4 /* assets */,\n\t\t\t\tE397A0B1210A641C00A978D4 /* ActionViewController.swift */,\n\t\t\t\tE397A0B3210A641C00A978D4 /* MainInterface.storyboard */,\n\t\t\t\tE397A0B6210A641C00A978D4 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = \"send-ios-action-extension\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\tE34149C121017A3900930775 /* send-ios */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = E34149D421017A3D00930775 /* Build configuration list for PBXNativeTarget \"send-ios\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tE355478A210A4C43009D206E /* ShellScript */,\n\t\t\t\tE34149BE21017A3900930775 /* Sources */,\n\t\t\t\tE34149BF21017A3900930775 /* Frameworks */,\n\t\t\t\tE34149C021017A3900930775 /* Resources */,\n\t\t\t\tE397A0BD210A641C00A978D4 /* Embed App Extensions */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tE397A0B8210A641C00A978D4 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"send-ios\";\n\t\t\tproductName = \"send-ios\";\n\t\t\tproductReference = E34149C221017A3900930775 /* send-ios.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\tE397A0AE210A641C00A978D4 /* send-ios-action-extension */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = E397A0BC210A641C00A978D4 /* Build configuration list for PBXNativeTarget \"send-ios-action-extension\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tE397A0AB210A641C00A978D4 /* Sources */,\n\t\t\t\tE397A0AC210A641C00A978D4 /* Frameworks */,\n\t\t\t\tE397A0AD210A641C00A978D4 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"send-ios-action-extension\";\n\t\t\tproductName = \"send-ios-action-extension\";\n\t\t\tproductReference = E397A0AF210A641C00A978D4 /* send-ios-action-extension.appex */;\n\t\t\tproductType = \"com.apple.product-type.app-extension\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tE34149BA21017A3900930775 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 0940;\n\t\t\t\tLastUpgradeCheck = 0940;\n\t\t\t\tORGANIZATIONNAME = \"Donovan Preston\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tE34149C121017A3900930775 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 9.4.1;\n\t\t\t\t\t};\n\t\t\t\t\tE397A0AE210A641C00A978D4 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 9.4.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = E34149BD21017A3900930775 /* Build configuration list for PBXProject \"send-ios\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = E34149B921017A3900930775;\n\t\t\tproductRefGroup = E34149C321017A3900930775 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tE34149C121017A3900930775 /* send-ios */,\n\t\t\t\tE397A0AE210A641C00A978D4 /* send-ios-action-extension */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tE34149C021017A3900930775 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tE355478C210A534F009D206E /* ios.js in Resources */,\n\t\t\t\tE355478921092E22009D206E /* assets in Resources */,\n\t\t\t\tE355478E210A5357009D206E /* generate-bundle.js in Resources */,\n\t\t\t\tE34149D021017A3D00930775 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\tE355478521028193009D206E /* help.html in Resources */,\n\t\t\t\tE34149CD21017A3D00930775 /* Assets.xcassets in Resources */,\n\t\t\t\tE34149CB21017A3A00930775 /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tE397A0AD210A641C00A978D4 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tE397A0B5210A641C00A978D4 /* MainInterface.storyboard in Resources */,\n\t\t\t\tE397A0BF210A6B5500A978D4 /* assets in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\tE355478A210A4C43009D206E /* ShellScript */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"node generate-bundle.js\\n\";\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tE34149BE21017A3900930775 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tE34149C821017A3A00930775 /* ViewController.swift in Sources */,\n\t\t\t\tE34149C621017A3A00930775 /* AppDelegate.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tE397A0AB210A641C00A978D4 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tE397A0B2210A641C00A978D4 /* ActionViewController.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\tE397A0B8210A641C00A978D4 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = E397A0AE210A641C00A978D4 /* send-ios-action-extension */;\n\t\t\ttargetProxy = E397A0B7210A641C00A978D4 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\tE34149C921017A3A00930775 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tE34149CA21017A3A00930775 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tE34149CE21017A3D00930775 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tE34149CF21017A3D00930775 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tE397A0B3210A641C00A978D4 /* MainInterface.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tE397A0B4210A641C00A978D4 /* Base */,\n\t\t\t);\n\t\t\tname = MainInterface.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\tE34149D221017A3D00930775 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 11.4;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tE34149D321017A3D00930775 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 11.4;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tE34149D521017A3D00930775 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = \"send-ios/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.mozilla.send-ios\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tE34149D621017A3D00930775 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = \"send-ios/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.mozilla.send-ios\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tE397A0BA210A641C00A978D4 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = \"send-ios-action-extension/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@executable_path/../../Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.mozilla.send-ios.send-ios-action-extension\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tE397A0BB210A641C00A978D4 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = \"send-ios-action-extension/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@executable_path/../../Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.mozilla.send-ios.send-ios-action-extension\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tE34149BD21017A3900930775 /* Build configuration list for PBXProject \"send-ios\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tE34149D221017A3D00930775 /* Debug */,\n\t\t\t\tE34149D321017A3D00930775 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tE34149D421017A3D00930775 /* Build configuration list for PBXNativeTarget \"send-ios\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tE34149D521017A3D00930775 /* Debug */,\n\t\t\t\tE34149D621017A3D00930775 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tE397A0BC210A641C00A978D4 /* Build configuration list for PBXNativeTarget \"send-ios-action-extension\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tE397A0BA210A641C00A978D4 /* Debug */,\n\t\t\t\tE397A0BB210A641C00A978D4 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = E34149BA21017A3900930775 /* Project object */;\n}\n"
  },
  {
    "path": "ios/send-ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:send-ios.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "ios/send-ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "l10n.toml",
    "content": "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\nbasepath = \".\"\n\n[env]\n    l = \"{l10n_base}/public/locales/{locale}/\"\n\n[[paths]]\n    reference = \"public/locales/en-US/**\"\n    l10n = \"{l}**\"\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"firefox-send\",\n  \"description\": \"File Sharing Experiment\",\n  \"version\": \"3.0.22\",\n  \"author\": \"Mozilla (https://mozilla.org)\",\n  \"repository\": \"mozilla/send\",\n  \"homepage\": \"https://github.com/mozilla/send/\",\n  \"license\": \"MPL-2.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"clean\": \"rimraf dist\",\n    \"build\": \"npm run clean && webpack\",\n    \"lint\": \"npm-run-all lint:*\",\n    \"lint:css\": \"stylelint app/*.css app/**/*.css\",\n    \"lint:js\": \"eslint .\",\n    \"lint-locales\": \"node scripts/lint-locales\",\n    \"lint-locales:dev\": \"npm run lint-locales\",\n    \"lint-locales:prod\": \"npm run lint-locales -- --production\",\n    \"format\": \"prettier '**/*.js' 'assets/*.css' --single-quote --write\",\n    \"get-prod-locales\": \"node scripts/get-prod-locales\",\n    \"get-prod-locales:write\": \"npm run get-prod-locales -- --write\",\n    \"contributors\": \"git shortlog -s | awk -F\\\\t '{print $2}' > CONTRIBUTORS\",\n    \"release\": \"npm-run-all contributors changelog\",\n    \"test\": \"npm-run-all test:*\",\n    \"test:backend\": \"nyc --reporter=lcovonly mocha --reporter=min test/backend\",\n    \"test:frontend\": \"cross-env NODE_ENV=development FXA_REQUIRED=false node test/frontend/runner.js\",\n    \"test:report\": \"nyc report --reporter=html\",\n    \"test-integration\": \"cross-env NODE_ENV=development wdio test/wdio.docker.conf.js\",\n    \"circleci-test-integration\": \"echo 'webdriverio tests need to be updated to node 12'\",\n    \"start\": \"npm run clean && cross-env NODE_ENV=development L10N_DEV=true FXA_CLIENT_ID=fced6b5e3f4c66b9 BASE_URL=http://localhost:1337 webpack-dev-server --port=1337 --mode=development\",\n    \"android\": \"cross-env ANDROID=1 npm start\",\n    \"prod\": \"node server/bin/prod.js\"\n  },\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"lint-staged\",\n      \"pre-push\": \"npm test\",\n      \"post-merge\": \"npm install\",\n      \"post-checkout\": \"scripts/sync-npm-dependencies.sh\"\n    }\n  },\n  \"lint-staged\": {\n    \"*.js\": [\n      \"prettier --single-quote --write\",\n      \"eslint\",\n      \"git add\"\n    ],\n    \"*.css\": [\n      \"prettier --single-quote --write\",\n      \"stylelint\",\n      \"git add\"\n    ]\n  },\n  \"nyc\": {\n    \"reporter\": [\n      \"text\"\n    ],\n    \"cache\": true\n  },\n  \"engines\": {\n    \"node\": \"^12.16.3\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.10.5\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.10.4\",\n    \"@babel/plugin-syntax-dynamic-import\": \"^7.2.0\",\n    \"@babel/preset-env\": \"^7.10.4\",\n    \"@dannycoates/webcrypto-liner\": \"^0.1.37\",\n    \"@fullhuman/postcss-purgecss\": \"^1.3.0\",\n    \"@mattiasbuelens/web-streams-polyfill\": \"0.2.1\",\n    \"@sentry/browser\": \"^5.20.1\",\n    \"asmcrypto.js\": \"^0.22.0\",\n    \"babel-loader\": \"^8.0.6\",\n    \"babel-plugin-istanbul\": \"^5.2.0\",\n    \"base64-js\": \"^1.3.1\",\n    \"content-disposition\": \"^0.5.3\",\n    \"copy-webpack-plugin\": \"^5.0.5\",\n    \"core-js\": \"^3.4.0\",\n    \"cross-env\": \"^6.0.3\",\n    \"css-loader\": \"^3.2.0\",\n    \"css-mqpacker\": \"^7.0.0\",\n    \"cssnano\": \"^4.1.10\",\n    \"eslint\": \"^6.6.0\",\n    \"eslint-config-prettier\": \"^6.5.0\",\n    \"eslint-plugin-mocha\": \"^6.2.1\",\n    \"eslint-plugin-node\": \"^10.0.0\",\n    \"eslint-plugin-security\": \"^1.4.0\",\n    \"expose-loader\": \"^0.7.5\",\n    \"extract-loader\": \"^3.1.0\",\n    \"extract-text-webpack-plugin\": \"^4.0.0-beta.0\",\n    \"fast-text-encoding\": \"^1.0.3\",\n    \"file-loader\": \"^4.2.0\",\n    \"git-rev-sync\": \"^1.12.0\",\n    \"html-loader\": \"^0.5.5\",\n    \"http_ece\": \"^1.1.0\",\n    \"husky\": \"^3.0.9\",\n    \"intl-pluralrules\": \"^1.1.1\",\n    \"lint-staged\": \"^9.4.2\",\n    \"mocha\": \"^6.2.2\",\n    \"morgan\": \"^1.9.1\",\n    \"nanobus\": \"^4.4.0\",\n    \"nanohtml\": \"^1.9.0\",\n    \"nanotiming\": \"^7.3.1\",\n    \"npm-run-all\": \"^4.1.5\",\n    \"nyc\": \"^14.1.1\",\n    \"postcss-loader\": \"^3.0.0\",\n    \"postcss-preset-env\": \"^6.7.0\",\n    \"prettier\": \"^1.19.1\",\n    \"proxyquire\": \"^2.1.3\",\n    \"puppeteer\": \"^2.0.0\",\n    \"raw-loader\": \"^3.1.0\",\n    \"redis-mock\": \"^0.47.0\",\n    \"rimraf\": \"^3.0.0\",\n    \"script-loader\": \"^0.7.2\",\n    \"sinon\": \"^7.5.0\",\n    \"string-hash\": \"^1.1.3\",\n    \"stylelint\": \"^11.1.1\",\n    \"stylelint-config-standard\": \"^19.0.0\",\n    \"stylelint-no-unsupported-browser-features\": \"^3.0.2\",\n    \"svgo\": \"^1.3.2\",\n    \"svgo-loader\": \"^2.2.1\",\n    \"tailwindcss\": \"^1.1.3\",\n    \"val-loader\": \"^1.1.1\",\n    \"webpack\": \"4.38.0\",\n    \"webpack-cli\": \"^3.3.12\",\n    \"webpack-dev-middleware\": \"^3.7.2\",\n    \"webpack-dev-server\": \"^3.11.0\",\n    \"webpack-manifest-plugin\": \"^2.2.0\",\n    \"webpack-unassert-loader\": \"^1.2.0\"\n  },\n  \"dependencies\": {\n    \"@dannycoates/express-ws\": \"^5.0.3\",\n    \"@fluent/bundle\": \"^0.13.0\",\n    \"@fluent/langneg\": \"^0.3.0\",\n    \"@google-cloud/storage\": \"^5.1.2\",\n    \"@peculiar/webcrypto\": \"^1.1.1\",\n    \"@sentry/node\": \"^5.20.1\",\n    \"aws-sdk\": \"^2.568.0\",\n    \"body-parser\": \"^1.19.0\",\n    \"choo\": \"^7.0.0\",\n    \"cldr-core\": \"^35.1.0\",\n    \"configstore\": \"github:dannycoates/configstore#master\",\n    \"convict\": \"^5.2.0\",\n    \"express\": \"^4.17.1\",\n    \"helmet\": \"^3.23.3\",\n    \"mkdirp\": \"^0.5.1\",\n    \"mozlog\": \"^2.2.0\",\n    \"node-fetch\": \"^2.6.0\",\n    \"redis\": \"^3.0.2\",\n    \"selenium-standalone\": \"^6.15.6\",\n    \"ua-parser-js\": \"^0.7.21\"\n  },\n  \"availableLanguages\": [\n    \"en-US\",\n    \"an\",\n    \"ar\",\n    \"ast\",\n    \"azz\",\n    \"be\",\n    \"bn\",\n    \"br\",\n    \"ca\",\n    \"cak\",\n    \"cs\",\n    \"cy\",\n    \"da\",\n    \"de\",\n    \"dsb\",\n    \"el\",\n    \"en-CA\",\n    \"en-GB\",\n    \"es-AR\",\n    \"es-CL\",\n    \"es-ES\",\n    \"es-MX\",\n    \"et\",\n    \"eu\",\n    \"fa\",\n    \"fi\",\n    \"fr\",\n    \"fy-NL\",\n    \"gn\",\n    \"he\",\n    \"hr\",\n    \"hsb\",\n    \"hu\",\n    \"hus\",\n    \"hy-AM\",\n    \"ia\",\n    \"id\",\n    \"it\",\n    \"ja\",\n    \"ka\",\n    \"kab\",\n    \"ko\",\n    \"lt\",\n    \"meh\",\n    \"mix\",\n    \"ml\",\n    \"nb-NO\",\n    \"nl\",\n    \"nn-NO\",\n    \"oc\",\n    \"pa-IN\",\n    \"pl\",\n    \"ppl\",\n    \"pt-BR\",\n    \"pt-PT\",\n    \"quc\",\n    \"ro\",\n    \"ru\",\n    \"sk\",\n    \"sl\",\n    \"sq\",\n    \"sr\",\n    \"su\",\n    \"sv-SE\",\n    \"te\",\n    \"th\",\n    \"tr\",\n    \"uk\",\n    \"vi\",\n    \"zgh\",\n    \"zh-CN\",\n    \"zh-TW\"\n  ]\n}\n"
  },
  {
    "path": "postcss.config.js",
    "content": "class TailwindExtractor {\n  static extract(content) {\n    return content.match(/[A-Za-z0-9-_:/]+/g) || [];\n  }\n}\n\nconst options = {\n  plugins: [\n    require('tailwindcss')('./tailwind.config.js'),\n    require('postcss-preset-env')\n  ]\n};\n\nif (process.env.NODE_ENV === 'development') {\n  options.map = { inline: true };\n} else {\n  options.plugins.push(\n    require('@fullhuman/postcss-purgecss')({\n      content: [\n        './app/*.js',\n        './app/ui/*.js',\n        './android/*.js',\n        './android/pages/*.js'\n      ],\n      extractors: [\n        {\n          extractor: TailwindExtractor,\n          extensions: ['js']\n        }\n      ]\n    })\n  );\n  options.plugins.push(\n    require('cssnano')({\n      preset: 'default'\n    })\n  );\n}\n\nmodule.exports = options;\n"
  },
  {
    "path": "public/contribute.json",
    "content": "{\n  \"name\": \"firefox-send\",\n  \"description\": \"File Sharing Experiment\",\n  \"repository\": {\n    \"url\": \"https://github.com/mozilla/send/\",\n    \"license\": \"MPL-2.0\"\n  },\n    \"participate\": {\n      \"home\": \"https://github.com/mozilla/send/blob/master/README.md\",\n      \"docs\": \"https://github.com/mozilla/send/blob/master/README.md\"\n    },\n    \"bugs\": {\n      \"list\": \"https://github.com/mozilla/send/issues\",\n      \"report\": \"https://github.com/mozilla/send/issues/new\"\n    },\n    \"urls\": {\n      \"prod\": \"https://send.firefox.com/\",\n      \"stage\": \"https://stage.send.nonprod.cloudops.mozgcp.net/\",\n      \"dev\": \"https://send2.dev.lcip.org/\"\n    },\n  \"keywords\": [\n    \"JavaScript\",\n    \"jQuery\",\n    \"Node\",\n    \"Redis\"\n  ]\n}\n"
  },
  {
    "path": "public/inter.css",
    "content": "@font-face {\n  font-family: 'Inter';\n  font-style: normal;\n  font-weight: 100;\n  font-display: optional;\n  src: url('Inter-Thin.woff2') format('woff2'),\n    url('Inter-Thin.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: italic;\n  font-weight: 100;\n  font-display: optional;\n  src: url('Inter-ThinItalic.woff2') format('woff2'),\n    url('Inter-ThinItalic.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: normal;\n  font-weight: 200;\n  font-display: optional;\n  src: url('Inter-ExtraLight.woff2') format('woff2'),\n    url('Inter-ExtraLight.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: italic;\n  font-weight: 200;\n  font-display: optional;\n  src: url('Inter-ExtraLightItalic.woff2') format('woff2'),\n    url('Inter-ExtraLightItalic.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: normal;\n  font-weight: 300;\n  font-display: optional;\n  src: url('Inter-Light.woff2') format('woff2'),\n    url('Inter-Light.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: italic;\n  font-weight: 300;\n  font-display: optional;\n  src: url('Inter-LightItalic.woff2') format('woff2'),\n    url('Inter-LightItalic.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: normal;\n  font-weight: 400;\n  font-display: optional;\n  src: url('Inter-Regular.woff2') format('woff2'),\n    url('Inter-Regular.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: italic;\n  font-weight: 400;\n  font-display: optional;\n  src: url('Inter-Italic.woff2') format('woff2'),\n    url('Inter-Italic.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: normal;\n  font-weight: 500;\n  font-display: optional;\n  src: url('Inter-Medium.woff2') format('woff2'),\n    url('Inter-Medium.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: italic;\n  font-weight: 500;\n  font-display: optional;\n  src: url('Inter-MediumItalic.woff2') format('woff2'),\n    url('Inter-MediumItalic.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: normal;\n  font-weight: 600;\n  font-display: optional;\n  src: url('Inter-SemiBold.woff2') format('woff2'),\n    url('Inter-SemiBold.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: italic;\n  font-weight: 600;\n  font-display: optional;\n  src: url('Inter-SemiBoldItalic.woff2') format('woff2'),\n    url('Inter-SemiBoldItalic.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: normal;\n  font-weight: 700;\n  font-display: optional;\n  src: url('Inter-Bold.woff2') format('woff2'),\n    url('Inter-Bold.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: italic;\n  font-weight: 700;\n  font-display: optional;\n  src: url('Inter-BoldItalic.woff2') format('woff2'),\n    url('Inter-BoldItalic.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: normal;\n  font-weight: 800;\n  font-display: optional;\n  src: url('Inter-ExtraBold.woff2') format('woff2'),\n    url('Inter-ExtraBold.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: italic;\n  font-weight: 800;\n  font-display: optional;\n  src: url('Inter-ExtraBoldItalic.woff2') format('woff2'),\n    url('Inter-ExtraBoldItalic.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: normal;\n  font-weight: 900;\n  font-display: optional;\n  src: url('Inter-Black.woff2') format('woff2'),\n    url('Inter-Black.woff') format('woff');\n}\n\n@font-face {\n  font-family: 'Inter';\n  font-style: italic;\n  font-weight: 900;\n  font-display: optional;\n  src: url('Inter-BlackItalic.woff2') format('woff2'),\n    url('Inter-BlackItalic.woff') format('woff');\n}\n"
  },
  {
    "path": "public/locales/an/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Se ye importando…\nencryptingFile = Se ye cifrando…\ndecryptingFile = Se ye descifrando…\ndownloadCount =\n    { $num ->\n        [one] 1 descarga\n       *[other] { $num } descargas\n    }\ntimespanHours =\n    { $num ->\n        [one] hora\n       *[other] { $num } horas\n    }\ncopiedUrl = Copiau!\nunlockInputPlaceholder = Clau\nunlockButtonLabel = Desblocar\ndownloadButtonLabel = Descargar\ndownloadFinish = Descarga completa\nfileSizeProgress = ({ $partialSize } de { $totalSize })\nsendYourFilesLink = Preba Send\nerrorPageHeader = I ha habiu bell problema!\nfileTooBig = Ixe fichero ye masiau gran pa cargar-lo. Ha de tener menos de { $size }\nlinkExpiredAlt = Lo vinclo ye caducau\nnotSupportedHeader = Lo suyo navegador no ye compatible\nnotSupportedLink = Per qué no ye compatible lo mío navegador?\nnotSupportedOutdatedDetail = Esta versión de Firefox no admite la tecnolochía web con que funciona lo Send. Habrás d'esviellar lo navegador.\nupdateFirefox = Esviellar Firefox\ndeletePopupCancel = Cancelar\ndeleteButtonHover = Borrar\nfooterLinkLegal = Aviso legal\nfooterLinkPrivacy = Privacidat\nfooterLinkCookies = Cookies\npasswordTryAgain = La contrasenya ye incorrecta. Torne-lo a intentar.\njavascriptRequired = Send necesita JavaScript\nwhyJavascript = Per qué Send necesita JavaScript?\nenableJavascript = Activa JavaScript y torna-lo a intentar.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } h { $minutes } min\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } min\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maxima lonchitut d'a clau: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = No s'ha puesto definir la clau\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Compartición de fichers simpla y privada\nintroDescription = { -send-brand } te permite de compartir fichers cifraus de cabo a cabo, y tamién un vinclo que expira automaticament. Asinas, puetz mantener en privau lo que compartes y asegurar-te de que los tuyos contenius no se quedan pa cutio en linia.\nnotifyUploadEncryptDone = Lo fichero s'ha cifrau y ye presto pa ninviar-se\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Caduca dimpués de { $downloadCount } u { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuto\n       *[other] { $num } minutos\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 día\n       *[other] { $num } días\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 semana\n       *[other] { $num } semanas\n    }\nfileCount =\n    { $num ->\n        [one] 1 fichero\n       *[other] { $num } fichers\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Mida total: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copiar lo vinclo que quiers compartir\ncopyLinkButton = Copiar lo vinclo\ndownloadTitle = Descargar los fichers\ndownloadDescription = Este fichero s'ha compartiu per medio de { -send-brand } con cifrau de cabo a cabo y un vinclo que caduca automaticament.\ntrySendDescription = Preba { -send-brand } pa una compartición de fichers simpla y segura.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Nomás se puet puyar 1 fitxer de vez.\n       *[other] Nomás se pueden puyar  { $count } fichers de vez.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Nomás se permite 1 ficher.\n       *[other] Nomás se permiten { $count } fichers.\n    }\nexpiredTitle = Este vinclo ye caducau.\nnotSupportedDescription = { -send-brand } no funcionará con este navegador. { -send-short-brand } funciona millor con a zaguera versión de { -firefox } y funcionará con a versión mas recient d'a mayor parte de navegadors.\ndownloadFirefox = Descargar { -firefox }\nlegalTitle = Aviso de privacidat de { -send-short-brand }\nlegalDateStamp = Versió 1.0, con data d'o 12 de marzo de 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } d { $hours } h { $minutes } min\naddFilesButton = Triar los fichers a cargar\ntrustWarningMessage = Asegura-te de que confías en o destinatario quan compartas datos confidencials.\nuploadButton = Cargar\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Arrociega y suelta los fichers\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = u fes clic aquí pa ninviar dica { $size }\naddPassword = Protecher con una clau\nemailPlaceholder = Escribe la tuya adreza de correu\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Inicia una sesión pa ninviar dica { $size }\nsignInOnlyButton = Iniciar la sesión\naccountBenefitTitle = Crea una cuenta de { -firefox } u dentra-ie\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Compartir fichers dica { $size }\naccountBenefitDownloadCount = Compartir fichers con mas chent\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Mantiene los vinclos activos dica 1 dia\n       *[other] Mantiene los vinclos activos dica { $count } días\n    }\naccountBenefitSync = Chestiona los fichers compartius dende qualsequier dispositivo\naccountBenefitMoz = Descubre mas cosas sobre los atros servicios de { -mozilla }\nsignOut = Zarrar la sesión\nokButton = Vale\ndownloadingTitle = Se ye descargando\nnoStreamsWarning = Este navegador talment no pueda descifrar un fichero tant gran.\nnoStreamsOptionCopy = Copia lo vinclo pa ubrir-lo en belatro navegador\nnoStreamsOptionFirefox = Preba lo nuestro navegador favorito\nnoStreamsOptionDownload = Continar con este navegador\ndownloadFirefoxPromo = Lo nuevo { -firefox } t'ofreix { -send-short-brand }.\n# the next line after the colon contains a file name\nshareLinkDescription = Comparte lo vinclo enta lo tuyo fichero:\nshareLinkButton = Compartir lo vinclo\n# $name is the name of the file\nshareMessage = Baixa-te «{ $name }» con { -send-brand }: compartición de fiches simpla y segura\ntrailheadPromo = I hai una manera de protecher la tuya privacidat. Une-te a Firefox.\nlearnMore = Mas información\ndownloadFlagged = Este vinclo s'ha desactivau per violar las condiciones d'uso.\ndownloadConfirmTitle = Una coseta mas\ndownloadConfirmDescription = Asegura-te de que confías en a persona que t'ha ninviau este fichero, perque no podemos verificar que no danyará lo tuyo dispositivo.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Confío en a persona que ha ninviau este fichero\n       *[other] Confío en a persona que ha ninviau estes fichers\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Sinyalar este fichero como sospeitoso\n       *[other] Sinyalar estes fichers como sospeitoso\n    }\nreportDescription = Aduya-nos a comprender qué ha pasau. Quál creyes que ye lo problema con estes fichers?\nreportUnknownDescription = Vest ta la URL d'o vinclo que quiers sinyalar y fe clic en « { reportFile } ».\nreportButton = Informar\nreportReasonMalware = Estes fichers contienen malware u fan parte d'un ataque de phishing.\nreportReasonPii = Estes fichers contienen información personal identificable sobre yo.\nreportReasonAbuse = Estes fichers contienen conteniu ilegal u abusivo.\nreportReasonCopyright = Pa informar sobre una violación de dreitos d'autor u de marca, sigue lo procedimiento descrito en <a>esta pachina</a>.\nreportedTitle = Fichers sinyalaus\nreportedDescription = Gracias. Hemos recibiu lo tuyo informe sobre estes fichers.\n"
  },
  {
    "path": "public/locales/ar/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = فَيَرفُكس سِنْد\nsiteFeedback = الانطباعات\nimportingFile = يستورد…\nencryptingFile = يعمّي…\ndecryptingFile = يفك التعمية…\ndownloadCount =\n    { $num ->\n        [zero] لا تنزيلات\n        [one] تنزيل واحد\n        [two] تنزيلين\n        [few] { $num } تنزيلات\n        [many] { $num } تنزيلًا\n       *[other] { $num } تنزيل\n    }\ntimespanHours =\n    { $num ->\n        [zero] أقل من ساعة\n        [one] ساعة\n        [two] ساعتين\n        [few] { $num } ساعات\n        [many] { $num } ساعة\n       *[other] { $num } ساعة\n    }\ncopiedUrl = نُسخ!\nunlockInputPlaceholder = كلمة السر\nunlockButtonLabel = افتح القفل\ndownloadButtonLabel = نزّل\ndownloadFinish = اكتمل التنزيل\nfileSizeProgress = ({ $partialSize } من أصل { $totalSize })\nsendYourFilesLink = جرِّب «فَيَرفُكس سِنْد»\nerrorPageHeader = حدث خطب ما.\nfileTooBig = حجم الملف كبير للغاية لرفعه. يجب أن يكون أصغر من { $size }.\nlinkExpiredAlt = انتهت صلاحية الرابط\nnotSupportedHeader = متصفحك غير مدعوم.\nnotSupportedLink = لماذا متصفحي غير مدعوم؟\nnotSupportedOutdatedDetail = للأسف فإن إصدارة فَيَرفُكس هذه لا تدعم تقنية الوِب التي يعتمد عليها «فَيَرفُكس سِنْد». عليك تحديث متصفحك.\nupdateFirefox = حدّث فَيَرفُكس\ndeletePopupCancel = ألغِ\ndeleteButtonHover = احذف\nfooterLinkLegal = القانونية\nfooterLinkPrivacy = الخصوصية\nfooterLinkCookies = الكعكات\npasswordTryAgain = كلمة السر خاطئة. أعِد المحاولة.\njavascriptRequired = يتطلب فَيَرفُكس سِنْد جافاسكربت\nwhyJavascript = لماذا يتطلب فَيَرفُكس سِنْد جافاسكربت؟\nenableJavascript = رجاء فعّل جافاسكربت ثم أعد المحاولة.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }س { $minutes }د\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }د\n# A short status message shown when the user enters a long password\nmaxPasswordLength = أقصر طول لكلمة السر: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = يجب ألا تُضبط كلمة السر هذه\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = شارِك ملفاتك بلا عناء وبخصوصية تامة\nintroDescription = يتيح لك { -send-brand } مشاركة الملفات عبر تعميتها من الطرفين وإتاحتها في رابط ينقضي أجله تلقائيا. هكذا يمكنك إبقاء ما شاركته خاصًا فتضمن بأن ملفاتك لن تبقى في الوِب أبد الدهر.\nnotifyUploadEncryptDone = اكتملت تعمية الملف وأصبح جاهزًا لإرساله\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = ينقضي بعد { $downloadCount } أو { $timespan }\ntimespanMinutes =\n    { $num ->\n        [zero] أقل من دقيقة\n        [one] دقيقة واحدة\n        [two] دقيقتين اثنتين\n        [few] { $num } دقائق\n        [many] { $num } دقيقة\n       *[other] { $num } دقيقة\n    }\ntimespanDays =\n    { $num ->\n        [zero] أقل من يوم\n        [one] يوم واحد\n        [two] يومين اثنين\n        [few] { $num } أيام\n        [many] { $num } يومًا\n       *[other] { $num } يوم\n    }\ntimespanWeeks =\n    { $num ->\n        [zero] أقل من أسبوع\n        [one] أسبوع واحد\n        [two] أسبوعين اثنين\n        [few] { $num } أسابيع\n        [many] { $num } أسبوعًا\n       *[other] { $num } أسبوع\n    }\nfileCount =\n    { $num ->\n        [zero] { $num } ملف\n        [one] ملف واحد\n        [two] ملفان اثنان\n        [few] { $num } ملفات\n        [many] { $num } ملفًا\n       *[other] { $num } ملف\n    }\n# byte abbreviation\nbytes = بايت\n# kibibyte abbreviation\nkb = ك.بايت\n# mebibyte abbreviation\nmb = م.بايت\n# gibibyte abbreviation\ngb = ج.بايت\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = إجمالي الحجم: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = انسخ هذا الرابط لتُشارك الملف:\ncopyLinkButton = انسخ الرابط\ndownloadTitle = نزّل الملفات\ndownloadDescription = شارك أحد هذا الملف معك عبر { -send-brand } وعمّاه بتعمية من الطرفين وبرابط ينقضي أجله تلقائيا.\ntrySendDescription = جرِّب { -send-brand } وشارِك ملفاتك بلا عناء وبخصوصية تامة.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [zero] لا يمكنك تنزيل أي ملف في آن واحد.\n        [one] لا يمكنك تنزيل ما يزيد على ملف واحد في آن واحد.\n        [two] لا يمكنك تنزيل ما يزيد على ملفين اثنين في آن واحد.\n        [few] لا يمكنك تنزيل ما يزيد على { $count } ملفات في آن واحد.\n        [many] لا يمكنك تنزيل ما يزيد على { $count } ملفًا في آن واحد.\n       *[other] لا يمكنك تنزيل ما يزيد على { $count } ملف في آن واحد.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [zero] الأرشيفات ممنوعة.\n        [one] لا يُسمح إلا بأرشيف واحد.\n        [two] لا يُسمح إلا بأرشيفين اثنين.\n        [few] لا يُسمح إلا ب‍ { $count } أرشيفات.\n        [many] لا يُسمح إلا ب‍ { $count } أرشيفًا.\n       *[other] لا يُسمح إلا ب‍ { $count } أرشيف.\n    }\nexpiredTitle = انقضى وقت الرابط.\nnotSupportedDescription = لن يعمل { -send-brand } في هذا المتصفح. أفضل المتصفحات التي يعمل معها { -send-short-brand } هو { -firefox } بآخر إصدارة، كما وأحدث إصدارة من أغلب المتصفحات الموجودة.\ndownloadFirefox = نزِّل { -firefox }\nlegalTitle = تنويه خصوصية { -send-short-brand }\nlegalDateStamp = الإصدارة ١٫٠ بتاريخ ١٢ مارس ٢٠١٩\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }يوم { $hours }سا { $minutes }دق\naddFilesButton = حدّد الملفات التي تريد رفعها\nuploadButton = ارفع\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = اسحب الملفات وأفلِتها هنا\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = أو انقر لإرسال ملفات يصل حجمها { $size }\naddPassword = احمِه بكلمة سر\nemailPlaceholder = أدخل بريدك الإلكتروني\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = لِج وأرسِل ملفات يصل حجمها { $size }\nsignInOnlyButton = لِج\naccountBenefitTitle = أنشِئ حساب { -firefox } أو لِج إلى حسابك\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = شارِك ملفات يصل حجمها { $size }\naccountBenefitDownloadCount = شارِك الملفات مع أناس أكثر وأكثر\naccountBenefitTimeLimit =\n    { $count ->\n        [zero] لا تُبقِ أي روابط نشطة\n        [one] أبقِ الروابط نشطة لمدة تصل إلى يوم واحد\n        [two] أبقِ الروابط نشطة لمدة تصل إلى يومين اثنين\n        [few] أبقِ الروابط نشطة لمدة تصل إلى { $count } أيام\n        [many] أبقِ الروابط نشطة لمدة تصل إلى { $count } يومًا\n       *[other] أبقِ الروابط نشطة لمدة تصل إلى { $count } يوم\n    }\naccountBenefitSync = أدِر ملفاتك التي شاركتها من أيّ جهاز تريد\naccountBenefitMoz = اطّلع على المزيد حول خدمات { -mozilla }\nsignOut = اخرج\nokButton = حسنًا\ndownloadingTitle = يجري التنزيل\nnoStreamsWarning = هناك احتمال بألا يقدر هذا المتصفح على فكّ تعمية الملفات الكبيرة كهذا.\nnoStreamsOptionCopy = انسخ الرابط لتفتحه في متصفح آخر\nnoStreamsOptionFirefox = جرّب متصفّحنا المفضل\nnoStreamsOptionDownload = واصِل بهذا المتصفح\ndownloadFirefoxPromo = ‏{ -send-short-brand } تقدمة { -firefox } الجديد الأنيق.\n# the next line after the colon contains a file name\nshareLinkDescription = شارِك الرابط الذي يصل إلى الملف:\nshareLinkButton = شارِك الرابط\n# $name is the name of the file\nshareMessage = نزِّل ”{ $name }“ عبر { -send-brand }: خدمة لمشاركة الملفات بلا عناء وبخصوصية تامة\ntrailheadPromo = يمكنك حماية خصوصيتك، طبعا. انضم إلى فَيَرفُكس.\nlearnMore = اطّلع على المزيد.\n"
  },
  {
    "path": "public/locales/ast/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importando...\nencryptingFile = Cifrando...\ndecryptingFile = Descifrando...\ndownloadCount =\n    { $num ->\n        [one] 1 descarga\n       *[other] { $num } descargues\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hora\n       *[other] { $num } hores\n    }\ncopiedUrl = ¡Copióse!\nunlockInputPlaceholder = Contraseña\nunlockButtonLabel = Desbloquiar\ndownloadButtonLabel = Baxar\ndownloadFinish = Completóse la descarga\nfileSizeProgress = ({ $partialSize } de { $totalSize })\nsendYourFilesLink = Probar Send\nerrorPageHeader = ¡Asocedió daqué malo!\nfileTooBig = Esti ficheru ye mui grande como pa xubilu. Debería tener menos de { $size }.\nlinkExpiredAlt = Caducó l'enllaz\nnotSupportedHeader = El to restolador nun ta sofitáu.\nnotSupportedLink = ¿Por qué'l mio restolador nun ta sofitáu?\nnotSupportedOutdatedDetail = Desafortunadamente esta versión de Firefox nun sofita la teunoloxía web qu'usa Send. Vas precisar anovar el restolador.\nupdateFirefox = Anovar Firefox\ndeletePopupCancel = Encaboxar\ndeleteButtonHover = Desaniciar\nfooterLinkLegal = Llegal\nfooterLinkPrivacy = Privacidá\nfooterLinkCookies = Cookies\npasswordTryAgain = La contraseña ye incorreuta. Volvi tentalo.\njavascriptRequired = Send rique JavaScript\nwhyJavascript = ¿Por qué Send rique JavaScript?\nenableJavascript = Activa JavaScript y volvi tentalo, por favor.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Llargor máximu de la contraseña: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Nun pudo afitase esta contraseña\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Compartición de ficheros privada y cenciella\nintroDescription = { -send-brand } déxate compartir ficheros con cifráu puntu a puntu y un enllaz que caduca automáticamente. D'esti mou, asegúreste de que lo que compartes ye privao y nun va tar siempres en llinia.\nnotifyUploadEncryptDone = El ficheru ta cifráu y preparáu pa unviase\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Caduca dempués de { $downloadCount } ó { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minutu\n       *[other] { $num } minutos\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 día\n       *[other] { $num } díes\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 selmana\n       *[other] { $num } selmanes\n    }\nfileCount =\n    { $num ->\n        [one] 1 ficheru\n       *[other] { $num } ficheros\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Tamañu total: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copia l'enllaz pa compartir el ficheru:\ncopyLinkButton = Copiar l'enllaz\ndownloadTitle = Descarga de ficheros\ndownloadDescription = Esti ficheru compartióse per { -send-brand } con cifráu puntu a puntu y un enllaz que caduca automáticamente.\ntrySendDescription = Prueba { -send-brand } pa una compartición de ficheros cenciella y segura.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Namás pue xubise 1 ficheru al empar.\n       *[other] Namás puen xubise { $count } ficheros al empar.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Namás se permite 1 archivu\n       *[other] Namás se permiten { $count } archivos\n    }\nexpiredTitle = Esti enllaz caducó.\nnotSupportedDescription = { -send-brand } nun va funcionar con esti restolador. { -send-short-brand } funciona meyor cola última versión de { -firefox } y l'actual de la mayoría de restoladores.\ndownloadFirefox = Baxar { -firefox }\nlegalTitle = Avisu de privacidá de { -send-short-brand }\nlegalDateStamp = Versión 1.0, con data del 12 de marzu de 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Esbillar los ficheros a unviar\ntrustWarningMessage = Asegúrate de que t'enfotes nel destinatariu al compartir datos sensibles.\nuploadButton = Xubir\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Arrastra y suelta ficheros\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = o calca pa unviar hasta { $size }\naddPassword = Protexer con una contraseña\nemailPlaceholder = Introduz el to corréu\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Anicia sesión pa unviar hasta { $size }\nsignInOnlyButton = Aniciar sesión\naccountBenefitTitle = Creación d'una cuenta de { -firefox } o aniciu de sesión nella\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Comparti ficheros d'hasta { $size }\naccountBenefitDownloadCount = Comparti ficheros con más xente\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Caltién activos los enllaces demientres 1 día\n       *[other] Caltién activos los enllaces demientres { $count } díes\n    }\naccountBenefitSync = Xestiona los ficheros compartíos dende cualesquier preséu\naccountBenefitMoz = Deprendi más tocante a otros servicios de { -mozilla }\nsignOut = Zarrar sesión\nokButton = Aceutar\ndownloadingTitle = Baxando\nnoStreamsWarning = Esti restolador quiciabes nun seya a descifrar un ficheru d'esti tamañu.\ntrailheadPromo = Hai un mou de protexer la to privacidá. Xúnite a Firefox.\nlearnMore = Deprender más.\ndownloadFlagged = Esti enllaz desactivóse por violar los términos del serviciu.\ndownloadConfirmTitle = Una cosa más\nreportReasonMalware = Estos ficheros contienen malware o son parte d'un ataque de phishing\nreportReasonPii = Estos ficheros contienen información que m'identifica.\nreportReasonAbuse = Estos ficheros contienen conteníu illegal o abusivu.\nreportedDescription = Gracies. Recibiemos l'informe tocante a estos ficheros.\n"
  },
  {
    "path": "public/locales/az/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Geri dönüş\nimportingFile = İdxal edilir…\nencryptingFile = Şifrələnir...\ndecryptingFile = Şifrə açılır...\ndownloadCount =\n    { $num ->\n        [one] 1 endirmə\n       *[other] { $num } endirmə\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 saat\n       *[other] { $num } saat\n    }\ncopiedUrl = Köçürüldü!\nunlockInputPlaceholder = Parol\nunlockButtonLabel = Aç\ndownloadButtonLabel = Endir\ndownloadFinish = Endirmə Tamamlandı\nfileSizeProgress = ({ $partialSize } / { $totalSize })\nsendYourFilesLink = Send Yoxla\nerrorPageHeader = Nəsə səhv getdi!\nfileTooBig = Fayl yükləmək üçün çox böyükdür. Fayl { $size }-dan az olmalıdır.\nlinkExpiredAlt = Keçidin vaxtı çıxıb\nnotSupportedHeader = Səyyahınız dəstəklənmir.\nnotSupportedLink = Səyyahım niyə dəstəklənmir?\nnotSupportedOutdatedDetail = Heyf ki, Firefox səyyahının bu versiyası Send-ə güc verən web texnologiyalarını dəstəkləmir. Səyyahınızı yeniləməlisiniz.\nupdateFirefox = Firefox-u Yenilə\ndeletePopupCancel = Ləğv et\ndeleteButtonHover = Sil\nfooterLinkLegal = Hüquqi\nfooterLinkPrivacy = Məxfilik\nfooterLinkCookies = Çərəzlər\npasswordTryAgain = Səhv parol. Təkrar yoxlayın.\njavascriptRequired = Send üçün JavaScript lazımdır\nwhyJavascript = Send niyə JavaScript tələb edir?\nenableJavascript = Lütfən JavaScript-i aktiv edib təkrar yoxlayın.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } saat { $minutes } dəq\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } dəq\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maksimum parol uzunluğu: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Parol qurula bilmədi\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\ncopyLinkButton = Keçidi köçür\nuploadButton = Yüklə\nsignInOnlyButton = Daxil ol\nsignOut = Çıx\nokButton = Tamam\ndownloadingTitle = Endirilir\nshareLinkButton = Keçidi paylaş\n"
  },
  {
    "path": "public/locales/azz/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Nikan uelis tikijkuilos tein tiknemilijtos\nimportingFile = Mokalakijtok…\nencryptingFile = Motatijtok…\ndecryptingFile = Kichiujtok se uelis kiixtajtoltis ya…\ndownloadCount =\n    { $num ->\n       *[undefined] 1 kitemouijtok / { $num } kintemouijtok\n    }\ntimespanHours =\n    { $num ->\n       *[undefined] 1 hora / { $num } hora\n    }\ncopiedUrl = ¡Moixkopinak!\nunlockInputPlaceholder = Ichtakatajtol\nunlockButtonLabel = Xikajchiua tein amo kikaua maj tekiti\ndownloadButtonLabel = Xiktemoui\ndownloadFinish = Nochi motemouij ya\nfileSizeProgress = ({ $partialSize } itech { $totalSize })\nsendYourFilesLink = Xikejeko Send\nerrorPageHeader = ¡Tensa amo kuali kisak!\nfileTooBig = Nejin tajkuilol semi ueyi. Moneki amo panos { $size }\nlinkExpiredAlt = Nejin tein tikpatskilij amo tekititok ya\nnotSupportedHeader = Monavegador amo kualtia.\nnotSupportedLink = ¿Keyej nonavegador amo kualtia?\nnotSupportedOutdatedDetail = Tetayokoltij, Firefox tein tikuitok amo kiselia tepostekitilis tecnología web tein ika tekiti Send. Moneki tikyankuilis monavegador.\nupdateFirefox = Maj Firefox  moyankuili\ndeletePopupCancel = Maj motsakuili uan amo tami tein kichiujtok\ndeleteButtonHover = Maj majchiua\nfooterLinkLegal = Keniuj motekitiltis\nfooterLinkPrivacy = Keniuj tikyekpiaj tein tikseliaj\nfooterLinkCookies = Cookies\npasswordTryAgain = Amo yektik ichtakatajtol. Oksepa xikijkuilo.\njavascriptRequired = Send kineki maj moajsi JavaScript\nwhyJavascript = ¿Keyej Send kineki maj moajsi JavaScript?\nenableJavascript = Se kualtakayot, xikaua maj peua tekiti JavaScript uan oksepa xikejeko.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Keniuj ueyak ichtakatajtol, maj amo pano: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Nejin ichtakatajtol amo uel kiixtaliani\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Xiktitani\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Amo ouij uan ichtaka xikinpanoltili oksekin motajkuiloluan archivos\nintroDescription = { -send-brand } mitspaleuia uan ijkon tikinpanoltilis oksekin motajkuiloluan archivos ika tapoualmej tein amo aksa uelis kiajsikamatis, uan no kitemaka kampa se kipatskilis tein niman ixpoliui. Ijkuin uelis tikichtakaeuas tein tikintitanilis oksekin uan tikyekmatis tein moaxka amo nochipaya mokauas itech Internet.\nnotifyUploadEncryptDone = Moarchivo moijkuiloj ya kemej amo akin uelis kiixtajtoltis uan se uelis kititanis ya\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Poliui ijkuak tiajsis { $downloadCount } oso { $timespan }\ntimespanMinutes =\n    { $num ->\n       *[undefined] 1 minuto / { $num } minuto\n    }\ntimespanDays =\n    { $num ->\n       *[undefined] 1 tonal / { $num } tonalmej\n    }\ntimespanWeeks =\n    { $num ->\n       *[undefined] 1 semana / { $num } semana\n    }\nfileCount =\n    { $num ->\n       *[undefined] 1 archivo / { $num } archivos\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Nochi tamachiua: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Xikixkopina tein se kipatskilis uan xikinpanoltili oksekin moarchivo:\ncopyLinkButton = Xikixkopina tein se kipatskilis\ndownloadTitle = Xiktemoui tajkuilolmej archivos\ndownloadDescription = Nejin archivo mopanoltij itechkopa { -send-brand } ika tapoualmej tein amo aksa uelis kiajsikamatis, uan no tein ika se kipatskilis tein niman ixpoliui.\ntrySendDescription = Xikejeko { -send-brand } ijkon amo ouij uelis tikinpanoltilis oksekin motajkuiloluan archivos uan tikyekmatis ke amo tej kipanos.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n       *[other] Sayoj { $count } tajkuilolmej archivos uelis tikolochtejkoltis saj.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n       *[other] Sayoj { $count } tajkuilolmej archivos uelis moajsiskej saj.\n    }\nexpiredTitle = Nejin tein tikpatskilij amo tekititos ok.\nnotSupportedDescription = { -send-brand } amo tekiti ika nejin navegador. { -send-short-brand } okachi kuali tekiti tein ika okachi yankuik { -firefox }, uan no tekitis tein ika okachi yankuikej tel miak navegadores.\ndownloadFirefox = Xiktemoui { -firefox }\nlegalTitle = { -send-short-brand } tanauatia ika yekpialis tein moaxka itech tepos\nlegalDateStamp = Versión 1.0 tein kikixtijkej 12 tonal metsti marzo 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }t { $hours }h { $minutes }m\naddFilesButton = Xikinixpejpena tajkuilolmej archivos tein  tikintejkoltis\nuploadButton = Xiktejkolti\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Xikintilana uan xikinkajkaua tajkuilolmej archivos\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = oso xikpatskili uan tiktitanis, sayoj tein amo panoua  { $size }\naddPassword = Xikyekpia ika se ichtakatajtol\nemailPlaceholder = Xikijkuilo mocorreo itech tepos\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Xikalakteua uan uelis tiktitanis tein amo panos { $size }\nsignInOnlyButton = Kampa se kalakteua\naccountBenefitTitle = Ximochiuili se cuenta itech { -firefox } oso xikalakteua\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Xikintitani tajkuilolmej archivos tein amo panouaj  { $size }\naccountBenefitDownloadCount = Xikintitanili tajkuilolmej archivos oksekin\naccountBenefitTimeLimit =\n    { $count ->\n       *[undefined] Kampa se kipatskilis maj kisentokakan kualtiakan se tonal ok / { $count } tonalmej ok\n    }\naccountBenefitSync = Itech tein yeski tepos xikixyekana motajkuiloluan archivos tein tikinpanoltilij oksekin\naccountBenefitMoz = Okachi tikmatis okseki tapaleuilmej tein kitemaka { -mozilla }\nsignOut = Kampa se kisa\nokButton = Kuali yetok\ndownloadingTitle = Kitemouijtok\nnoStreamsWarning = Xa navegador amo uelis kitalij nejin tajkuilol archivo tein tel ueyi kemej se uelis kiyekixtajtoltis ya.\nnoStreamsOptionCopy = Xikixkopina tein se kipatskilis uan ijkon se uelis kitatapos itech okse navegador\nnoStreamsOptionFirefox = Xikejeko navegador tein semi techuelita\nnoStreamsOptionDownload = Maj niksentoka niktatekiujti nejin navegador\ndownloadFirefoxPromo = Yankuik { -firefox } mitsixpantilia { -send-short-brand }.\n# the next line after the colon contains a file name\nshareLinkDescription = Xikinpanoltili oksekin tein se kipatskilis uan teuika motajkuilol archivo:\nshareLinkButton = Kampa se kipatskilis tein uelis tikinpanoltilis oksekin\n# $name is the name of the file\nshareMessage = Xiktemoui “{ $name }” ika { -send-brand }: amo ouij uelis tikinpanoltilis oksekin motajkuiloluan archivos uan tikyekmatis ke amo tej kipanos\ntrailheadPromo = Kemaj, uelis tikyekpias tein moaxka itech tepos. Xipoui Firefox.\nlearnMore = Xiktemoui tajkuilolmej archivos.\n"
  },
  {
    "path": "public/locales/be/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Імпартаванне...\nencryptingFile = Зашыфроўка...\ndecryptingFile = Расшыфроўка...\ndownloadCount =\n    { $num ->\n        [one] { $num } сцягванне\n        [few] { $num } сцягванні\n       *[many] { $num } сцягванняў\n    }\ntimespanHours =\n    { $num ->\n        [one] { $num } гадзіна\n        [few] { $num } гадзіны\n       *[many] { $num } гадзін\n    }\ncopiedUrl = Скапіявана!\nunlockInputPlaceholder = Пароль\nunlockButtonLabel = Разблакаваць\ndownloadButtonLabel = Сцягнуць\ndownloadFinish = Сцягванне скончана\nfileSizeProgress = ({ $partialSize } з { $totalSize })\nsendYourFilesLink = Паспрабуйце Send\nerrorPageHeader = Нешта пайшло не так!\nfileTooBig = Гэты файл надта вялікі. Ён мусіць быць меншым за { $size }\nlinkExpiredAlt = Тэрмін дзеяння спасылкі сышоў\nnotSupportedHeader = Ваш браўзер не падтрымліваецца.\nnotSupportedLink = Чаму мой браўзер не падтрымліваецца?\nnotSupportedOutdatedDetail = На жаль, гэтая версія Firefox не падтрымлівае вэб-тэхналогію, што забяспечвае працу Send. Вам трэба абнавіць свой браўзер.\nupdateFirefox = Абнавіць Firefox\ndeletePopupCancel = Скасаваць\ndeleteButtonHover = Выдаліць\nfooterLinkLegal = Прававыя звесткі\nfooterLinkPrivacy = Прыватнасць\nfooterLinkCookies = Кукі\npasswordTryAgain = Некарэктны пароль. Паспрабуйце зноў.\njavascriptRequired = Для Send неабходны JavaScript\nwhyJavascript = Чаму для Send неабходны JavaScript?\nenableJavascript = Калі ласка, уключыце JavaScript і паспрабуйце зноў.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } г. { $minutes } хв.\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } хв.\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Максімальная даўжыня пароля: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Гэты пароль немагчыма паставіць\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Просты і прыватны абмен файламі\nintroDescription = { -send-brand } дазваляе вам абменьвацца файламі са скразным шыфраваннем і спасылкамі з абмежаваным тэрмінам дзеяння. Такім чынам, вы можаце дзяліцца файламі прыватна і быць упэўненым, што яны не застануцца ў сеціве назаўжды.\nnotifyUploadEncryptDone = Ваш файл зашыфраваны і гатовы да адпраўкі\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Тэрмін дзеяння сыдзе праз { $downloadCount } або { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] { $num } хвіліна\n        [few] { $num } хвіліны\n       *[many] { $num } хвілін\n    }\ntimespanDays =\n    { $num ->\n        [one] { $num } дзень\n        [few] { $num } дні\n       *[many] { $num } дзён\n    }\ntimespanWeeks =\n    { $num ->\n        [one] { $num } тыдзень\n        [few] { $num } тыдні\n       *[many] { $num } тыдняў\n    }\nfileCount =\n    { $num ->\n        [one] { $num } файл\n        [few] { $num } файлы\n       *[many] { $num } файлаў\n    }\n# byte abbreviation\nbytes = Б\n# kibibyte abbreviation\nkb = КБ\n# mebibyte abbreviation\nmb = МБ\n# gibibyte abbreviation\ngb = ГБ\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Агульны памер: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Скапіруйце спасылку, каб падзяліцца сваім файлам:\ncopyLinkButton = Скапіраваць спасылку\ndownloadTitle = Сцягнуць файлы\ndownloadDescription = Гэтым файлам падзяліліся праз { -send-brand } са скразным шыфраваннем і спасылкай з абмежаваным тэрмінам дзеяння.\ntrySendDescription = Паспрабуйце { -send-brand } для простага і бяспечнага абмену файламі.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Толькі { $count } файл можна загрузіць за раз.\n        [few] Толькі { $count } файлы можна загрузіць за раз.\n       *[many] Толькі { $count } файлаў можна загрузіць за раз.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Толькі { $count } архіў дазволены.\n        [few] Толькі { $count } архівы дазволены.\n       *[many] Толькі { $count } архіваў дазволена.\n    }\nexpiredTitle = Тэрмін дзеяння гэтай спасылкі сышоў.\nnotSupportedDescription = { -send-brand } не будзе працаваць у гэтым браўзеры. Лепей за ўсё { -send-short-brand } працуе з апошняй версіяй { -firefox } і будзе працаваць з бягучай версіяй большасці браўзераў.\ndownloadFirefox = Сцягнуць { -firefox }\nlegalTitle = Палітыка прыватнасці { -send-short-brand }\nlegalDateStamp = Версія 1.0 ад 12 сакавіка 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } д. { $hours } г. { $minutes } хв.\naddFilesButton = Выберыце файлы для загрузкі\ntrustWarningMessage = Пераканайцеся, што давяраеце атрымальніку, калі дзеліцеся канфідэнцыяльнымі звесткамі.\nuploadButton = Загрузіць\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Перацягніце файлы сюды\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = або клікніце, каб адправіць да { $size }:\naddPassword = Абараніць паролем\nemailPlaceholder = Увядзіце сваю электронную пошту\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Увайдзіце, каб адпраўляць да { $size }\nsignInOnlyButton = Увайсці\naccountBenefitTitle = Стварыце ўліковы запіс { -firefox } або ўвайдзіце\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Дзяліцеся файламі да { $size }\naccountBenefitDownloadCount = Дзяліцеся файламі з большай колькасцю людзей\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Трымайце спасылкі актыўнымі да { $count } дня\n        [few] Трымайце спасылкі актыўнымі да { $count } дзён\n       *[many] Трымайце спасылкі актыўнымі да { $count } дзён\n    }\naccountBenefitSync = Кіруйце адпраўленымі файламі з любой прылады\naccountBenefitMoz = Даведайцеся пра іншыя сэрвісы { -mozilla }\nsignOut = Выйсці\nokButton = ОК\ndownloadingTitle = Сцягваецца\nnoStreamsWarning = Гэты браўзер не мае магчымасці расшыфраваць такі вялікі файл.\nnoStreamsOptionCopy = Скапіруйце спасылку, каб адкрыць у іншым браўзеры\nnoStreamsOptionFirefox = Паспрабуйце наш любімы браўзер\nnoStreamsOptionDownload = Працягнуць з гэтым браўзерам\ndownloadFirefoxPromo = { -send-short-brand } прыйшоў да вас з цалкам новага { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Падзяліцеся спасылкай на свой файл:\nshareLinkButton = Падзяліцца спасылкай\n# $name is the name of the file\nshareMessage = Сцягніце «{ $name }» з { -send-brand }: простага і бяспечнага файлаабменніка\ntrailheadPromo = Ёсць спосаб абараніць вашу прыватнасць. Далучайцеся да Firefox.\nlearnMore = Падрабязней.\ndownloadFlagged = Гэта спасылка адключана за парушэнне ўмоў прадастаўлення паслуг.\ndownloadConfirmTitle = Яшчэ адна рэч\ndownloadConfirmDescription = Пераканайцеся, што давяраеце адпраўніку гэтага файла, бо мы не можам пераканацца, што ён не нашкодзіць Вашай прыладзе.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Я давяраю адпраўніку гэтага файла\n        [few] Я давяраю адпраўніку гэтых файлаў\n       *[many] Я давяраю адпраўніку гэтых файлаў\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Паведаміць, што гэты файл падазроныя\n        [few] Паведаміць, што гэтыя файлы падазроныя\n       *[many] Паведаміць, што гэтыя файлы падазроныя\n    }\nreportDescription = Дапамажыце нам зразумець, што адбываецца. Як вы лічыце, што не так з гэтымі файламі?\nreportUnknownDescription = Калі ласка, перайдзіце да адрасу спасылкі, пра якую хочаце паведаміць, і націсніце “{ reportFile }”.\nreportButton = Паведаміць\nreportReasonMalware = Гэтыя файлы ўтрымліваюць шкоднасныя праграмы альбо з'яўляюцца часткай фішынг-атакі.\nreportReasonPii = Гэтыя файлы ўтрымліваюць асабістую інфармацыю пра мяне.\nreportReasonAbuse = Гэтыя файлы ўтрымліваюць незаконнае альбо абразлівае змесціва.\nreportReasonCopyright = Каб паведаміць аб парушэнні аўтарскіх правоў або гандлёвых марак, скарыстайцеся алгарытмам, апісаным на <a>гэтай старонцы</a>.\nreportedTitle = Пра файлы паведамлена\nreportedDescription = Дзякуй. Мы атрымалі Вашу заяву наконт гэтых файлаў.\n"
  },
  {
    "path": "public/locales/bn/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = প্রতিক্রিয়া\nimportingFile = ইম্পোর্ট হচ্ছে...\nencryptingFile = ইনক্রিপট হচ্ছে...\ndecryptingFile = ডিক্রিপট হচ্ছে...\ndownloadCount =\n    { $num ->\n        [one] 1 ডাউনলোড\n       *[other] { $num } ডাউনলোডগুলো\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 ঘন্টা\n       *[other] { $num } ঘন্টা\n    }\ncopiedUrl = কপি করা হয়েছে!\nunlockInputPlaceholder = পাসওয়ার্ড\nunlockButtonLabel = আনলক করুন\ndownloadButtonLabel = ডাউনলোড\ndownloadFinish = ডাউনলোড সম্পন্ন\nfileSizeProgress = ({ $totalSize } এর { $partialSize })\nsendYourFilesLink = Send পরখ করে দেখুন\nerrorPageHeader = কোন সমস্যা হয়েছে!\nfileTooBig = ফাইলটি আপলোড করার জন্যে খুব বড়। এটি { $size } এর চেয়ে কম হওয়া উচিত।\nlinkExpiredAlt = লিঙ্ক মেয়াদউত্তীর্ণ হয়েছে\nnotSupportedHeader = আপনার ব্রাউজার সমর্থিত নয়।\nnotSupportedLink = আমার ব্রাউজার কেন সমর্থিত নয়?\nnotSupportedOutdatedDetail = দুর্ভাগ্যবশত Firefox এই সংস্করণটি ওয়েব প্রযুক্তিকে সমর্থন করে না যা Send কে সমর্থন করে। আপনাকে আপনার ব্রাউজারটি আপডেট করতে হবে।\nupdateFirefox = Firefox হালনাগাদ করুন\ndeletePopupCancel = বাতিল\ndeleteButtonHover = মুছে ফেলুন\nfooterLinkLegal = আইনগত\nfooterLinkPrivacy = গোপনীয়তা\nfooterLinkCookies = কুকি\npasswordTryAgain = ভুল পাসওয়ার্ড। আবার চেষ্টা করুন।\njavascriptRequired = Send এর জাভাস্ক্রিপ্ট প্রয়োজন।\nwhyJavascript = কেন Send এর জাভাস্ক্রিপ্ট প্রয়োজন?\nenableJavascript = জাভাস্ক্রিপ্ট সক্রিয় করুন এবং আবার চেষ্টা করুন।\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }ঘ { $minutes }মি\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }মি\n# A short status message shown when the user enters a long password\nmaxPasswordLength = সর্বোচ্চ পাসওয়ার্ড দৈর্ঘ্য:{ $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = এই পাসওয়ার্ড সেট করা যাবে না\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = প্রেরণ\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = সহজ, ব্যক্তিগত ফাইল শেয়ার\nintroDescription = { -send-brand } ফাইল এনক্রিপশন ও স্বয়ংক্রিয়ভাবে মেয়াদ শেষ হবে এমন একটি লিঙ্কের মাধ্যমে শুরু-থেকে-শেষ পর্যন্ত শেয়ার করতে দেয়। একারণে আপনি যা শেয়ার করেন তা গোপন রাখতে এবং আপনার জিনিস চিরদিনের জন্য অনলাইনে থাকবে না তা নিশ্চিত করতে পারেন।\nnotifyUploadEncryptDone = আপনার ফাইল এনক্রিপ্ট করা হয়েছে এবং প্রেরণ করতে প্রস্তুত\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = { $downloadCount } বা { $timespan } পরে মেয়াদ শেষ হবে\ntimespanMinutes =\n    { $num ->\n        [one] ১ মিনিট\n       *[other] { $num } মিনিট\n    }\ntimespanDays =\n    { $num ->\n        [one] ১ দিন\n       *[other] { $num } দিন\n    }\ntimespanWeeks =\n    { $num ->\n        [one] ১ সপ্তাহ\n       *[other] { $num } সপ্তাহ\n    }\nfileCount =\n    { $num ->\n        [one] ১টি ফাইল\n       *[other] { $num }টি ফাইল\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = মোট আকার: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = আপনার ফাইল শেয়ার করতে লিঙ্ক অনুলিপি করুন:\ncopyLinkButton = লিঙ্ক অনুলিপি\ndownloadTitle = ফাইল ডাউনলোড\ndownloadDescription = ফাইলটি { -send-brand } এর মাধ্যমে এনক্রিপশন ও স্বয়ংক্রিয় মেয়াদ শেষ হবে এমন একটি লিঙ্কের মাধ্যমে শুরু-থেকে-শেষ পর্যন্ত শেয়ার করা হয়েছে।\ntrySendDescription = সহজ ও নিরাপদ ফাইল শেয়ারের জন্য { -send-brand } ব্যবহার করুন।\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] একবারে কেবল ১টি ফাইল আপলোড করা যাবে।\n       *[other] একবারে কেবল { $count }টি ফাইল আপলোড করা যাবে।\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] কেবল ১টি আর্কাইভ অনুমোদিত।\n       *[other] কেবল { $count } আর্কাইভ অনুমোদিত।\n    }\nexpiredTitle = এই লিঙ্কের মেয়াদ শেষ হয়ে গেছে।\nnotSupportedDescription = { -send-brand } এই ব্রাউজারের সাথে কাজ করবে না। { -firefox } এর সাম্প্রতিকতম সংস্করণে { -send-short-brand } সর্বোত্তমভাবে কাজ করবে, এবং এটি বেশিরভাগ ব্রাউজারের বর্তমান সংস্করণে কাজ করবে।\ndownloadFirefox = { -firefox } ডাউনলোড করুন\nlegalTitle = { -send-short-brand } গোপনীয়তা নোটিশ\nlegalDateStamp = সংস্করণ ১.০, ১২ মার্চ, ২০১৯ তারিখ\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }দি { $hours }ঘ { $minutes }মি\naddFilesButton = আপলোডের জন্য ফাইল নির্বাচন করুন\nuploadButton = আপলোড\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = ফাইল টেনে এনে ছাড়ুন\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = বা সর্বোচ্চ { $size } আকারের ফাইল পাঠাতে ক্লিক করুন\naddPassword = পাসওয়ার্ড দ্বারা সুরক্ষিত রাখুন\nemailPlaceholder = আপনার ইমেইল দিন\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = সর্বোচ্চ { $size } আকারের ফাইল প্রেরণ করতে সাইন ইন করুন\nsignInOnlyButton = সাইন ইন\naccountBenefitTitle = { -firefox } অ্যাকাউন্ট তৈরি অথবা সাইন ইন করুন\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = সর্বোচ্চ { $size } আকারের ফাইল শেয়ার করুন\naccountBenefitDownloadCount = আরও মানুষের সাথে ফাইল শেয়ার করুন\naccountBenefitTimeLimit =\n    { $count ->\n        [one] ১ দিন পর্যন্ত লিঙ্ক সক্রিয় রাখুন\n       *[other] { $count } দিন পর্যন্ত লিঙ্ক সক্রিয় রাখুন\n    }\naccountBenefitSync = যেকোন ডিভাইস থেকে শেয়ার করা ফাইল পরিচালনা করুন\naccountBenefitMoz = অন্যান্য { -mozilla } সেবা সম্পর্কে জানুন\nsignOut = সাইন আউট\nokButton = ঠিক আছে\ndownloadingTitle = ডাউনলোড হচ্ছে\nnoStreamsWarning = এই ব্রাউজার এতো বড় একটি ফাইল ডিক্রিপ্ট করতে সক্ষম নয়।\nnoStreamsOptionCopy = অন্য ব্রাউজারে খুলতে লিঙ্ক অনুলিপি করুন\nnoStreamsOptionFirefox = আমাদের জনপ্রিয় ব্রাউজার ব্যবহার করুন\nnoStreamsOptionDownload = এই ব্রাউজার ব্যবহার অব্যহত রাখুন\ndownloadFirefoxPromo = { -send-short-brand } আপনারদের জন্য নিয়ে এসেছে একেবারে নতুন { -firefox }।\n# the next line after the colon contains a file name\nshareLinkDescription = আপনার ফাইলে লিঙ্ক শেয়ার করুন:\nshareLinkButton = লিঙ্ক শেয়ার করুন\n# $name is the name of the file\nshareMessage = { -send-brand } এর মাধ্যমে \"{ $name }\" ডাউনলোড করুন: সরল, নিরাপদ ফাইল শেয়ারিং\ntrailheadPromo = আপনার গোপনীয়তা রক্ষা করার একটি উপায় আছে। Firefox এ যোগ দিন।\nlearnMore = আরও জানুন।\n"
  },
  {
    "path": "public/locales/br/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Oc'h enporzhiañ …\nencryptingFile = Oc'h enrinegañ..\ndecryptingFile = Oc'h ezrinegañ...\ndownloadCount =\n    { $num ->\n        [one] { $num } bellgargadenn\n        [two] { $num } bellgargadenn\n        [few] { $num } fellgargadenn\n        [many] { $num } a bellgargadennoù\n       *[other] { $num } pellgargadenn\n    }\ntimespanHours =\n    { $num ->\n        [one] { $num } eur\n        [two] { $num } eur\n        [few] { $num } eur\n        [many] { $num } a eurioù\n       *[other] { $num } eur\n    }\ncopiedUrl = Eilet!\nunlockInputPlaceholder = Ger-tremen\nunlockButtonLabel = Dibrennañ\ndownloadButtonLabel = Pellgargañ\ndownloadFinish = Pellgargadur echu\nfileSizeProgress = ({ $partialSize } war { $totalSize })\nsendYourFilesLink = Esaeit Send\nerrorPageHeader = Degouezhet ez eus bet ur fazi!\nfileTooBig = Re vras eo ar restr-mañ evit e pellgas. Rankout a ra bezañ nebeutoc'h eget { $size }\nlinkExpiredAlt = Ere diamzeret\nnotSupportedHeader = N'eo ket skoret ho merdeer.\nnotSupportedLink = Perak n'eo ket skoret ma merdeer?\nnotSupportedOutdatedDetail = Siwazh n'eo ket skoret ar c'halvezerezhioù implijet evit Send gant an handelv-mañ eus Firefox. Ret e vo deoc'h hizivaat ho merdeer.\nupdateFirefox = Hizivaat Firefox\ndeletePopupCancel = Nullañ\ndeleteButtonHover = Dilemel\nfooterLinkLegal = Lezennel\nfooterLinkPrivacy = Buhez prevez\nfooterLinkCookies = Toupinoù\npasswordTryAgain = Ger-tremen direizh. Klaskit en-dro.\njavascriptRequired = Send a azgoulenn Javascript\nwhyJavascript = Perak e azgoulenn Send Javascript?\nenableJavascript = Gweredekait Javascript ha klaskit en-dro.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }e { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Hirder brasañ aotreet evit ar ger-tremen: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = N'haller ket despizañ ar ger-tremen\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Rannañ restroù en un doare eeun ha prevez\nintroDescription = A-drugarez da { -send-brand } a c'hallit rannañ restroù gant un enrinegañ penn-ouzh-penn hag un ere a ziamzero ent emgefreek. Evel-se e c'hallit mirout ar pezh a rannit prevez ha bezañ sur ne chomo ket ho traoù enlinenn da viken.\nnotifyUploadEncryptDone = Enrineget eo ho restr ha prest eo da vezañ kaset\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Diamzeriñ a raio goude { $downloadCount } pe { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] { $num } vunutenn\n        [two] { $num } vunutenn\n        [few] { $num } munutenn\n        [many] { $num } a vunutennoù\n       *[other] { $num } munutenn\n    }\ntimespanDays =\n    { $num ->\n        [one] { $num } devezh\n        [two] { $num } zevezh\n        [few] { $num } devezh\n        [many] { $num } a zevezhioù\n       *[other] { $num } devezh\n    }\ntimespanWeeks =\n    { $num ->\n        [one] { $num } sizhun\n        [two] { $num } sizhun\n        [few] { $num } sizhun\n        [many] { $num } a sizhunioù\n       *[other] { $num } sizhun\n    }\nfileCount =\n    { $num ->\n        [one] { $num } restr\n        [two] { $num } restr\n        [few] { $num } restr\n        [many] { $num } a restroù\n       *[other] { $num } restr\n    }\n# byte abbreviation\nbytes = e\n# kibibyte abbreviation\nkb = Ke\n# mebibyte abbreviation\nmb = Me\n# gibibyte abbreviation\ngb = Ge\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Ment hollek: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Eilit an ere evit rannañ ho restr\ncopyLinkButton = Eilañ an ere\ndownloadTitle = Pellgargañ ar restroù\ndownloadDescription = Dre { -send-brand } eo bet rannet ar restr-mañ, gant un enrinegañ penn-ouzh-penn hag un ere a ziamzer ent emgefreek.\ntrySendDescription = Esaeit { -send-brand } evit rannañ restroù en un doare eeun ha prevez.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] N'haller pellgas nemet { $count } restr er memes mare.\n        [two] N'haller pellgas nemet { $count } restr er memes mare.\n        [few] N'haller pellgas nemet { $count } restr er memes mare.\n        [many] N'haller pellgas nemet { $count } a restroù er memes mare.\n       *[other] N'haller pellgas nemet { $count } restr er memes mare.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Aotreet eo{ $count } diell nemetken.\n        [two] Aotreet eo{ $count } ziell nemetken.\n        [few] Aotreet eo{ $count } diell nemetken.\n        [many] Aotreet eo{ $count } a zielloù nemetken.\n       *[other] Aotreet eo{ $count } diell nemetken.\n    }\nexpiredTitle = Diamzeret eo an ere.\nnotSupportedDescription = { -send-brand } n'aio ket en-dro war ar merdeer-mañ. { -send-short-brand } a za en-dro gwelloc'h gant handelv diwezhañ { -firefox }, ha mont a raio en-dro gant handelv bremanel lodenn vrasañ ar merdeerioù.\ndownloadFirefox = Pellgargañ { -firefox }\nlegalTitle = Evezhiadenn a fed buhez prevez { -send-short-brand }\nlegalDateStamp = Handelv 1.0, d'an 12 a viz Meurzh 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }e { $minutes }m\naddFilesButton = Diuzit ur restr da bellgas\ntrustWarningMessage = Bezit sur ho peus fiziañs en ho tegemerer pa rannit roadennoù kizidik.\nuploadButton = Pellgas\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Riklit ha laoskit restroù\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = pe klikit evit kas betek { $size }\naddPassword = Gwareziñ gant ur ger-tremen\nemailPlaceholder = Enankit ho chomlec'h postel\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Kennaskit evit kas betek { $size }\nsignInOnlyButton = Kennaskañ\naccountBenefitTitle = Krouit ur gont { -firefox } pe kennaskit\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Rannit restroù betek { $size }\naccountBenefitDownloadCount = Rannit restroù gant muioc'h a dud\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Dalc'hit an ereoù oberiant e-pad { $count } devezh\n        [two] Dalc'hit an ereoù oberiant e-pad { $count } zevezh\n        [few] Dalc'hit an ereoù oberiant e-pad { $count } devezh\n        [many] Dalc'hit an ereoù oberiant e-pad { $count } a zevezhioù\n       *[other] Dalc'hit an ereoù oberiant e-pad { $count } devezh\n    }\naccountBenefitSync = Merit ar restroù rannet gant forzh peseurt trevnad\naccountBenefitMoz = Gouzout hiroc'h a-zivout gwazerezhioù all { -mozilla }\nsignOut = Digennaskañ\nokButton = Mat eo\ndownloadingTitle = O pellgargañ\nnoStreamsWarning = Posupl eo ne vefe ket gouest ar merdeer-mañ da ezrinegañ ur restr ken bras.\nnoStreamsOptionCopy = Eilit an ere evit digeriñ anezhañ en ur merdeer all\nnoStreamsOptionFirefox = Esaeit hor merdeer karetañ\nnoStreamsOptionDownload = Kenderc'hel gant ar merdeer-mañ\ndownloadFirefoxPromo = { -send-short-brand } a zo kinniget deoc'h gant ar { -firefox } nevez-flamm.\n# the next line after the colon contains a file name\nshareLinkDescription = Rannit an ere etrezek ho restr:\nshareLinkButton = Rannañ an ere\n# $name is the name of the file\nshareMessage = Pellgargañ \"{ $name }\" gant { -send-brand }: rannañ restroù en un doare eeun ha prevez\ntrailheadPromo = Un doare a zo da wareziñ ho puhez prevez. Tremenit da Firefox.\nlearnMore = Gouzout hiroc'h.\ndownloadFlagged = Diweredekaet eo bet an ere-se dre ma ne zouje ket ouzh an divizoù arver.\ndownloadConfirmTitle = Un draig ouzhpenn\ndownloadConfirmDescription = Bezit sur ho peus fiziañs en deus en deus kaset ar restr-mañ dre ma n'haller ket gwiriañ ne freuzo ket ho trevnad.\n"
  },
  {
    "path": "public/locales/bs/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteSubtitle = web eksperiment\nsiteFeedback = Povratne informacije\nuploadPageHeader = Privatno, šifrovano dijeljenje datoteka\nuploadPageExplainer = Pošaljite datoteke putem sigurne, privatne i šifrovane veze koja automatski ističe kako bi se osiguralo da vaše stvari ne ostaju na mreži zauvijek.\nuploadPageLearnMore = Saznajte više\nuploadPageDropMessage = Prevucite vaše datoteke ovdje da biste počeli sa otpremanjem\nuploadPageSizeMessage = Za bolji rad predlažemo da datoteka ne bude veća od 1GB\nuploadPageBrowseButton = Odaberite datoteku na računaru\nuploadPageBrowseButton1 = Odaberite datoteku za otpremanje\nuploadPageMultipleFilesAlert = Otpremanje direktorija ili više datoteka trenutno nije podržano.\nuploadPageBrowseButtonTitle = Otpremi datoteku\nuploadingPageProgress = Otpremam { $filename } ({ $size })\nimportingFile = Uvozim...\nverifyingFile = Potvrđujem...\nencryptingFile = Šifrujem...\ndecryptingFile = Dešifrujem...\nnotifyUploadDone = Vaše otpremanje je završeno.\nuploadingPageMessage = Nakon što se vaša datoteka otpremi, moći ćete da podesite opcije isteka.\nuploadingPageCancel = Otkaži otpremanje\nuploadCancelNotification = Vaše otpremanje je otkazano.\nuploadingPageLargeFileMessage = Ova datoteka je velika i otpremanje može potrajati. Budite strpljivi!\nuploadingFileNotification = Obavijesti me kada otpremanje bude gotovo.\nuploadSuccessConfirmHeader = Spremno za slanje\nuploadSvgAlt = Otpremi\nuploadSuccessTimingHeader = Veza prema vašoj datoteci će isteći nakon prvog preuzimanja ili za 24 sata.\nexpireInfo = Link za vašu datoteku će isteći nakon { $downloadCount } ili { $timespan }.\ndownloadCount =\n    { $num ->\n        [one] 1 preuzimanja\n        [few] { $num } preuzimanja\n       *[other] { $num } preuzimanja\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 sat\n        [few] { $num } sata\n       *[other] { $num } sati\n    }\ncopyUrlFormLabelWithName = Iskopirajte i podijelite vezu da biste poslali datoteku: { $filename }\ncopyUrlFormButton = Kopiraj u međuspremnik\ncopiedUrl = Kopirano!\ndeleteFileButton = Izbriši datoteku\nsendAnotherFileLink = Pošalji drugu datoteku\n# Alternative text used on the download link/button (indicates an action).\ndownloadAltText = Preuzmi\ndownloadsFileList = Preuzimanja\n# Used as header in a column indicating the amount of time left before a\n# download link expires (e.g. \"10h 5m\")\ntimeFileList = Vrijeme\n# Used as header in a column indicating the number of times a file has been\n# downloaded\ndownloadFileName = Preuzmi { $filename }\ndownloadFileSize = ({ $size })\nunlockInputLabel = Unesite lozinku\nunlockInputPlaceholder = Lozinka\nunlockButtonLabel = Otključaj\ndownloadFileTitle = Preuzmi šifrovanu datoteku\n# Send is a brand name and should not be localized.\ndownloadMessage = Vaš prijatelj vam je poslao datoteku preko usluge Send koja vam omogućava da dijelite datoteke preko sigurne, privatne i šifrovane veze koja samostalno ističe da vaše stvari ne ostanu zauvijek na internetu.\n# Text and title used on the download link/button (indicates an action).\ndownloadButtonLabel = Preuzmi\ndownloadNotification = Vaše preuzimanje je završeno.\ndownloadFinish = Preuzimanje završeno\n# This message is displayed when uploading or downloading a file, e.g. \"(1,3 MB of 10 MB)\".\nfileSizeProgress = ({ $partialSize } od { $totalSize })\n# Send is a brand name and should not be localized.\nsendYourFilesLink = Probajte Send\ndownloadingPageProgress = Preuzimanje { $filename } ({ $size })\ndownloadingPageMessage = Ostavite ovaj tab otvorenim dok ne dobavimo vašu datoteku i dok je ne dešifrujemo.\nerrorAltText = Greška pri otpremanju\nerrorPageHeader = Nešto nije uredu!\nerrorPageMessage = Dogodila se greška pri otpremanju datoteke.\nerrorPageLink = Pošalji drugu datoteku\nfileTooBig = Ta datoteka je prevelika za otpremanje. Treba biti manja od { $size }.\nlinkExpiredAlt = Veza istekla\nexpiredPageHeader = Veza je istekla ili nikad nije postojala!\nnotSupportedHeader = Vaš pretraživač nije podržan.\n# Send is a brand name and should not be localized.\nnotSupportedDetail = Ovaj pretraživač nažalost ne podržava web tehnologiju koja omogućava Send. Trebate probati drugi pretraživač. Preporučujemo Firefox!\nnotSupportedLink = Zašto moj pretraživač nije podržan?\nnotSupportedOutdatedDetail = Nažalost ova verzija Firefoxa ne podržava web tehnologiju koja omogućava Send. Morate ažurirati vaš pretraživač.\nupdateFirefox = Ažuriraj Firefox\ndownloadFirefoxButtonSub = Besplatno preuzimanje\nuploadedFile = Datoteka\ncopyFileList = Kopiraj URL\n# expiryFileList is used as a column header\nexpiryFileList = Ističe za\ndeleteFileList = Izbriši\nnevermindButton = Zanemari\nlegalHeader = Uslovi i privatnost\nlegalNoticeTestPilot = Send je trenutno Test Pilot eksperiment i podržan je <a>uslovima korištenja</a> i <a>obavještenjem o privatnosti</a>. Možete saznati više o ovom eksperimentu i o njegovom sakupljanju podataka <a>ovdje</a>.\nlegalNoticeMozilla = Korištenje Send web stranice podlaže Mozillinom <a>obavještenju o privatnosti na web stranicama</a> i <a>uslovima korištenja web stranica</a>.\ndeletePopupText = Izbrisati ovu datoteku?\ndeletePopupYes = Da\ndeletePopupCancel = Otkaži\ndeleteButtonHover = Izbriši\ncopyUrlHover = Kopiraj URL\nfooterLinkLegal = Pravno\n# Test Pilot is a proper name and should not be localized.\nfooterLinkAbout = O Test Pilotu\nfooterLinkPrivacy = Privatnost\nfooterLinkTerms = Uslovi\nfooterLinkCookies = Kolačići\nrequirePasswordCheckbox = Zahtjevaj lozinku za preuzimanje ove datoteke\naddPasswordButton = Dodaj lozinku\nchangePasswordButton = Promijeni\npasswordTryAgain = Netačna lozinka. Pokušajte ponovo.\nreportIPInfringement = Prijavite IP prekršaj\njavascriptRequired = Send zahtjeva JavaScript\nwhyJavascript = Zašto Send zahtjeva JavaScript?\nenableJavascript = Molimo omogućite JavaScript i pokušajte ponovo.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when a password is successfully set\npasswordIsSet = Lozinka postavljena\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maksimalna veličina lozinke: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Ova lozinka se ne može postaviti\n"
  },
  {
    "path": "public/locales/ca/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = S'està important…\nencryptingFile = S'està xifrant…\ndecryptingFile = S'està desxifrant…\ndownloadCount =\n    { $num ->\n        [one] 1 baixada\n       *[other] { $num } baixades\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hora\n       *[other] { $num } hores\n    }\ncopiedUrl = Copiat!\nunlockInputPlaceholder = Contrasenya\nunlockButtonLabel = Desbloca\ndownloadButtonLabel = Baixa\ndownloadFinish = Ha acabat la baixada\nfileSizeProgress = ({ $partialSize } de { $totalSize })\nsendYourFilesLink = Proveu el Send\nerrorPageHeader = Hi ha hagut un problema\nfileTooBig = Aquest fitxer és massa gros per pujar-lo. Ha de tenir menys de { $size }.\nlinkExpiredAlt = L'enllaç ha caducat\nnotSupportedHeader = El vostre navegador no és compatible.\nnotSupportedLink = Per què el meu navegador no és compatible?\nnotSupportedOutdatedDetail = Aquesta versió del Firefox no admet la tecnologia web amb què funciona el Send. Haureu d'actualitzar el navegador.\nupdateFirefox = Actualitza el Firefox\ndeletePopupCancel = Cancel·la\ndeleteButtonHover = Suprimeix\nfooterLinkLegal = Avís legal\nfooterLinkPrivacy = Privadesa\nfooterLinkCookies = Galetes\npasswordTryAgain = La contrasenya és incorrecta. Torneu-ho a provar.\njavascriptRequired = El Send necessita JavaScript\nwhyJavascript = Per què el Send necessita JavaScript?\nenableJavascript = Activeu el JavaScript i torneu-ho a provar.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } h { $minutes } min\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } min\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Longitud màxima de la contrasenya: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = No s'ha pogut definir la contrasenya\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Compartició de fitxers senzilla i privada\nintroDescription = El { -send-brand } permet compartir fitxers amb xifratge d'extrem a extrem mitjançant un enllaç que caduca automàticament. Per tant, us assegureu que tot allò que compartiu és privat i que no es mantindrà a Internet per sempre.\nnotifyUploadEncryptDone = El fitxer s'ha xifrat i està llest per enviar-se\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Caduca després de { $downloadCount } o { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minut\n       *[other] { $num } minuts\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 dia\n       *[other] { $num } dies\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 setmana\n       *[other] { $num } setmanes\n    }\nfileCount =\n    { $num ->\n        [one] 1 fitxer\n       *[other] { $num } fitxers\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = kB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Mida total: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copieu l'enllaç per compartir el fitxer:\ncopyLinkButton = Copia l'enllaç\ndownloadTitle = Baixa els fitxers\ndownloadDescription = Aquest fitxer s'ha compartit mitjançant el { -send-brand } amb xifratge d'extrem a extrem i un enllaç que caduca automàticament.\ntrySendDescription = Proveu el { -send-brand } per compartir fitxers de forma senzilla i privada.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Només es pot pujar 1 fitxer alhora.\n       *[other] Només es poden pujar { $count } fitxers alhora.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Només es permet 1 fitxer.\n       *[other] Només es permeten { $count } fitxers.\n    }\nexpiredTitle = Aquest enllaç ha caducat.\nnotSupportedDescription = El { -send-brand } no funcionarà amb aquest navegador. El { -send-short-brand } funciona millor amb l'última versió del { -firefox } i funcionarà amb la versió més recent de la majoria de navegadors.\ndownloadFirefox = Baixa el { -firefox }\nlegalTitle = Avís de privadesa del { -send-short-brand }\nlegalDateStamp = Versió 1.0, amb data del 12 de març de 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } d { $hours } h { $minutes } min\naddFilesButton = Seleccioneu els fitxers que voleu pujar\ntrustWarningMessage = Assegureu-vos que confieu en el destinatari quan compartiu dades confidencials.\nuploadButton = Puja\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Arrossegueu i deixeu anar els fitxers\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = o feu clic aquí per enviar fins a { $size }\naddPassword = Protegeix amb contrasenya\nemailPlaceholder = Introduïu la vostra adreça electrònica\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Inicieu la sessió per enviar fins a { $size }\nsignInOnlyButton = Inicia la sessió\naccountBenefitTitle = Creeu un compte del { -firefox } o inicieu la sessió\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Compartiu fitxers fins a { $size }\naccountBenefitDownloadCount = Compartiu fitxers amb més persones\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Manteniu els enllaços actius fins a 1 dia\n       *[other] Manteniu els enllaços actius fins a { $count } dies\n    }\naccountBenefitSync = Gestioneu els fitxers compartits des de qualsevol dispositiu\naccountBenefitMoz = Descobriu els altres serveis de { -mozilla }\nsignOut = Tanca la sessió\nokButton = D'acord\ndownloadingTitle = S'està baixant\nnoStreamsWarning = Pot ser que aquest navegador no pugui desxifrar un fitxer tan gran.\nnoStreamsOptionCopy = Copieu l'enllaç per obrir-lo en un altre navegador\nnoStreamsOptionFirefox = Proveu el nostre navegador preferit\nnoStreamsOptionDownload = Segueix amb aquest navegador\ndownloadFirefoxPromo = El nou { -firefox } us ofereix el { -send-short-brand }\n# the next line after the colon contains a file name\nshareLinkDescription = Compartiu l'enllaç al vostre fitxer:\nshareLinkButton = Comparteix l'enllaç\n# $name is the name of the file\nshareMessage = Baixeu «{ $name }» amb el { -send-brand }: compartició de fitxers senzilla i segura\ntrailheadPromo = Hi ha una manera de protegir la vostra privadesa. Uniu-vos al Firefox.\nlearnMore = Més informació.\ndownloadFlagged = Aquest enllaç s'ha desactivat per infringir les condicions del servei.\ndownloadConfirmTitle = Una cosa més\ndownloadConfirmDescription = Assegureu-vos que confieu en la persona que us ha enviat aquest fitxer, perquè nosaltres no podem verificar que no malmeti el vostre dispositiu.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Confio en la persona que ha enviat aquest fitxer\n       *[other] Confio en la persona que ha enviat aquests fitxers\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Informa que aquest fitxer és sospitós\n       *[other] Informa que aquests fitxers són sospitos\n    }\nreportDescription = Ajudeu-nos a entendre què passa. Quin problema creieu que tenen aquests fitxers?\nreportUnknownDescription = Aneu a l'URL de l'enllaç sobre el qual voleu informar i feu clic a «{ reportFile }».\nreportButton = Informa\nreportReasonMalware = Aquests fitxers contenen programari maliciós o formen part d'un atac de pesca electrònica.\nreportReasonPii = Aquests fitxers contenen informació d'identificació personal meva.\nreportReasonAbuse = Aquests fitxers inclouen contingut il·legal o abusiu.\nreportReasonCopyright = Per informar sobre una infracció de drets d’autor o de marca comercial, utilitzeu el procés descrit en <a>aquesta pàgina</a>.\nreportedTitle = S'ha informat d'aquests fitxers\nreportedDescription = Gràcies. Hem rebut el vostre informe sobre aquests fitxers.\n"
  },
  {
    "path": "public/locales/cak/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Rutzijol\nimportingFile = Tajin nijik…\nencryptingFile = Tajin newäx rusik'ixik…\ndecryptingFile = Tajin netamäx rusik'ixik...\ndownloadCount =\n    { $num ->\n        [one] 1 qasanïk\n       *[other] { $num } taq qasanïk\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 ramaj\n       *[other] { $num } taq ramaj\n    }\ncopiedUrl = ¡Xwachib'ëx!\nunlockInputPlaceholder = Ewan tzij\nunlockButtonLabel = Titzij chik\ndownloadButtonLabel = Tiqasäx\ndownloadFinish = Xtz'aqät qasanïk\nfileSizeProgress = ({ $partialSize } richin { $totalSize })\nsendYourFilesLink = Titojtob'ëx Send\nerrorPageHeader = ¡K'o ri man ütz ta xub'än!\nfileTooBig = Yalan nïm re yakb'äl re' richin nijotob'äx. K'o ta chi man nik'o ta chi re ri { $size }.\nlinkExpiredAlt = Xk'is ruq'ijul ri ximonel\nnotSupportedHeader = Man koch'el ta ri awokik'amaya'l.\nnotSupportedLink = ¿Achike ruma man nikoch' taq ri wokik'amaya'l?\nnotSupportedOutdatedDetail = K'ayew ruma re ruwäch Firefox re' man nuköch' ta ri ajk'amaya'l na'ob'äl nrajo' ri Send. Rajowaxik nak'ëx ri awokik'amaya'l.\nupdateFirefox = Tik'ex ri Firefox\ndeletePopupCancel = Tiq'at\ndeleteButtonHover = Tiyuj\nfooterLinkLegal = Taqanel tzijol\nfooterLinkPrivacy = Ichinanem\nfooterLinkCookies = Taq kaxlanwey\npasswordTryAgain = Itzel ri ewan tzij. Tatojtob'ej chik.\njavascriptRequired = K'atzinel JavaScript chi re ri Send\nwhyJavascript = ¿Achike ruma toq ri Send nrajo' JavaScript?\nenableJavascript = Titz'ij JavaScript richin nitojtob'ëx chik.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }r { $minutes }ch\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }ch\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Nïm raqän ewan tzij: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Man tikirel ta ninuk' re ewan tzij re'\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Titaq\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Kijunamaxik relik chuqa' ichinan yakb'äl\nintroDescription = { -send-brand } nuya' q'ij chawe ye'akomonij taq yakb'äl ri ewan kisik'ixik chijun chuqa' jun ximonel ri nik'is ruq'ijul pa ruyonil. Ke ri' nawichinaj ronojel ri nakomonij chuqa' yajike' chi ronojel ri  taq awachinaq man jumul ta kek'oje' pa k'amab'ey.\nnotifyUploadEncryptDone = Ewan chik rusik'ixik ri ayakb'al chuqa' ütz chik richin nitaq\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Nik'is ruq'ij chi rij { $downloadCount } o { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 ch'utiramaj\n       *[other] { $num } taq ch'utiramaj\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 q'ij\n       *[other] { $num } taq q'ij\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 wuqq'ij\n       *[other] { $num } taq wuqq'ij\n    }\nfileCount =\n    { $num ->\n        [one] 1 yakb'äl\n       *[other] { $num } taq yakb'äl\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Ronojel runimilem: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Tawachib'ej ri ximonel richin nakomonij ri ayakb'al:\ncopyLinkButton = Tiwachib'ëx ximonel\ndownloadTitle = Keqasäx taq yakb'äl\ndownloadDescription = Xkomonïx re yakb'äl re' pa { -send-brand } rik'in chijun ewan rusik'ixik chuqa' nik'is ruq'ijul pa ruyonil.\ntrySendDescription = Tatojtob'ej { -send-brand } richin chanin chuqa' jikïl ye'akomonij taq yakb'äl.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Xa xe 1 yakb'äl tikirel nijotob'äx pa ri ramaj.\n       *[other] Xa xe { $count } taq yakb'äl tikirel yejotob'äx pa ri ramaj.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Xa xe 1 yakb'äl niya' q'ij chi re.\n       *[other] Xa xe { $count } taq yakb'äl niya' q'ij chi ke.\n    }\nexpiredTitle = Xk'is yan ruq'ij re ximonel re'.\nnotSupportedDescription = Man xtisamäj ta ri { -send-brand } rik'in re okik'amaya'l re'. Nisamäj ütz ri { -send-short-brand } rik'in ri ruk'isib'äl ruwäch { -firefox }, chuqa' xtisamäj rik'in ri ruwäch k'o wakami pa ronojel okik'amaya'l.\ndownloadFirefox = Tiqasäx { -firefox }\nlegalTitle = Rutzijol Richinanem { -send-short-brand }\nlegalDateStamp = Ruwäch 1.0, ruq'ijul marso 12, 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }q { $hours }r { $minutes }ch'\naddFilesButton = Kecha' taq yakb'äl richin yejotob'äx\nuploadButton = Tijotob'äx\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Keqirirëx chuqa' ke'osq'opïx taq yakb'äl\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = o tapitz'a' richin natäq k'a { $size }\naddPassword = Tichajïx rik'in ewan tzij\nemailPlaceholder = Tatz'ib'aj ataqoya'l\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Tatikirisaj molojri'ïl richin natäq k'a { $size }\nsignInOnlyButton = Titikirisäx molojri'ïl\naccountBenefitTitle = Tatz'uku' jun { -firefox } Rub'i' Ataqoy'al o Tatikirisaj molojri'ïl\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Ke'akomonij taq yakb'äl k'a { $size }\naccountBenefitDownloadCount = Ke'akomonij taq yakb'äl kik'in ch'aqa' chik winaqi'\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Ke' atzija' ri taq ximonel chi 1 q'ij\n       *[other] Ke'atzija' ri taq ximonel chi { $count } taq q'ij\n    }\naccountBenefitSync = Ke'anuk'samajij komonin taq yakb'äl pa xab'achike okisab'äl\naccountBenefitMoz = Tawetamaj chij ch'aqa' chik { -mozilla } taq samaj\nsignOut = Titz'apïx molojri'ïl\nokButton = ÜTZ\ndownloadingTitle = Niqasäx\nnoStreamsWarning = Rik'in jub'a' re okik'amaya'l re' man nitikïr ta nretamaj rusik'ixik nima'q taq yakb'äl.\nnoStreamsOptionCopy = Tiwachib'ëx ri ximonel richin nijaq pa jun chik okik'amaya'l\nnoStreamsOptionFirefox = Tatojtob'ej ri jeb'ël qokik'amaya'l\nnoStreamsOptionDownload = Kisamäj na rik'in re okik'amaya'l re'\ndownloadFirefoxPromo = Ja ri k'ak'a' { -firefox } nusüj ri { -send-short-brand } chawe.\n# the next line after the colon contains a file name\nshareLinkDescription = Nakomonij ri ximonel rik'in ri awokisab'al:\nshareLinkButton = Tikomonïx ximonel\n# $name is the name of the file\nshareMessage = Tiqasäx \"{ $name }\" rik'in { -send-brand }: man k'ayew ta chuqa' ütz kikomonik ri yakb'äl\ntrailheadPromo = K'o jun rub'anikil richin nachajij ri awichinanem. Tatunu' awi' rik'in ri Firefox.\nlearnMore = Tetamäx ch'aqa' chik.\n"
  },
  {
    "path": "public/locales/ckb/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = ڕەخنەوپێشنیار\nimportingFile = هاوردەکردن...\nencryptingFile = بەهێماکردن...\ndecryptingFile = هێمالابردن...\ndownloadCount =\n    { $num ->\n        [one] 1 داگرتن\n       *[other] { $num } داگرتن\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 کاژێر\n       *[other] { $num } کاژێر\n    }\ncopiedUrl = لەبەرگیرا!\nunlockInputPlaceholder = وشەی تێپەڕبوون\nunlockButtonLabel = کردنەوە\ndownloadButtonLabel = داگرتن\ndownloadFinish = داگرتن تەواو  بوو\nfileSizeProgress = ({ $partialSize } لە { $totalSize })\nsendYourFilesLink = Firefox ناردن تاقیبکەرەوە\nerrorPageHeader = هەڵەیەک ڕوویدا\nfileTooBig = ئەم پەڕگەیە زۆر گەورەیە بۆ بارکردن. پێویستە لە { $size } بچووک تر بێت\nlinkExpiredAlt = بەستەر بەسەرچووە\nnotSupportedHeader = وێبگەڕەکەت پشتگیری ناکرێت\nnotSupportedLink = بۆ وێبگەڕەکەم پشتگیری ناکرێت؟\nnotSupportedOutdatedDetail = بەداخەوە ئەم وەشانەی Firefox پشتگیری ئەو جۆرە تەکنەلۆژییە ناکات کە پێویستە بۆ Send. پێویستە وێبگەڕەکەت نوێبکەیتەوە.\nupdateFirefox = فاەرفۆکس نوێبکەرەوە\ndeletePopupCancel = پاشگەزبوونەوە\ndeleteButtonHover = سڕینەوە\nfooterLinkLegal = یاسایی\nfooterLinkPrivacy = تایبەتیی\nfooterLinkCookies = شەکرۆکە\npasswordTryAgain = وشەی تێپەڕبوون هەڵەیە. هەوڵ بدەرەوە.\njavascriptRequired = فارفۆکسی ناردن پێویستە بە JavaScript هەیە\nwhyJavascript = بۆچی پێویستی بە JavaScript هەیە؟\nenableJavascript = تکایە JavaScript چالاک بکە وهەوڵ بدەرەوە.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }ک { $minutes }خ\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }خ\n# A short status message shown when the user enters a long password\nmaxPasswordLength = زۆرترین درێژی وشەی تێپەڕی ڕێگەپێدراو: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = ناتوانرێت وشەی تێپەڕ دابنرێت\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = سانا، بڵاوکەرەوەی پەڕگەی تایبەتیی\nintroDescription = { -send-brand } ڕێگەت دەدات پەڕگەکان بڵاوبکەیتەوە بە شێوەی هێما کردنی کۆتا-بۆ-کۆتا و بەستەرێک کە خۆکارانە بەسەردەچێت. بۆیە دەتوانیت ئاگاداری ئەوە بیت کە چ پەڕگەیەک بە تایبەتی بڵاودەکەیتەوە و دڵنیادەبیتەوە کە شتەکانت بە سەرهێڵی نامێننەوە هەتا کۆتایی.\nnotifyUploadEncryptDone = پەڕگەیە بەهێماکراوە ئێستا ئامادەیە بۆ ناردن\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = بەسەردەچێت دووای { $downloadCount } یان { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 خولەک\n       *[other] { $num } خولەک\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 ڕؤژ\n       *[other] { $num } ڕۆژ\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 هەفتە\n       *[other] { $num } هەفتە\n    }\nfileCount =\n    { $num ->\n        [one] 1 پەڕگە\n       *[other] { $num } پەڕگە\n    }\n# byte abbreviation\nbytes = بایت\n# kibibyte abbreviation\nkb = ک.بایت\n# mebibyte abbreviation\nmb = م.بایت\n# gibibyte abbreviation\ngb = گ.بایت\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = قەبارەی گشتی: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = بەستەر لەبەربگرەوە بۆ بڵاوکردنەوەی پەڕگە:\ncopyLinkButton = بەستەر لەبەربگرەوە\ndownloadTitle = پەڕگەکان دابگرە\ndownloadDescription = ئەم پەڕگەیە لە لایەن { -send-brand } بلاوکراوەتەوە کە بەهێماکراوە بە شێوەی کۆتا-بۆ-کۆتا بە بەستەرێک کە خۆکارانە بەسەردەچێت.\ntrySendDescription = { -send-brand } تاقیبکەرەوە بۆ سانایی، پارێزراو لە بڵاوکردنەوەی پەڕگە.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] تەنها 1 پەڕگە دەتوانیت باربکەیت لەم کاتەدا.\n       *[other] تەنها { $count } پەڕگە دەتوانی باربکەیت لەم کاتەدا.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] تەنها 1 ئەرشیف ڕێپێدراوە.\n       *[other] تەنها { $count } ئەرشیف ڕێپێدراوە.\n    }\nexpiredTitle = بەستەر بەسەرچووە.\nnotSupportedDescription = { -send-brand } کارنکات لەگەڵ ئەم وێبگەڕە. { -send-short-brand } باش کاردەکات لەگەڵ کۆتا وەشانی { -firefox }، وکاردەکات لەگەڵ زۆربەی وەشانی ئێستای وێبگەڕەکان.\ndownloadFirefox = { -firefox } دابگرە\nlegalTitle = تێبینی تایبەتیی { -send-short-brand }\nlegalDateStamp = وەشان 1.0، بەروار کراو لە 12 ئازار، 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } ڕ { $hours } ک{ $minutes } خ\naddFilesButton = پەڕگەکان هەڵبژێرە بۆ بارکردن\nuploadButton = بارکردن\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = ڕاکێشان و دانانی پەڕگەکان\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = یان کرتە بکە بۆ ناردنی قەبارەی تاوەکوو { $size }\naddPassword = بپارێزە لەگەڵ وشەی تێپەڕ\nemailPlaceholder = پۆستی ئەلکترۆنی بنووسە\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = بچۆژوورەوە بۆ ناردنی قەبارەی تاوەکوو { $size }\nsignInOnlyButton = بچۆژوورەوە\naccountBenefitTitle = هەژماری { -firefox } درووست بکە یان بچۆژوورەوە\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = پەڕگە بڵاوبکەرەوە تاوەکوو قەبارەی { $size }\naccountBenefitDownloadCount = پەڕگەکان لەگەڵ خەڵکی زیاتر بڵاوبکەرەوە\naccountBenefitTimeLimit =\n    { $count ->\n        [one] بەستەرەکان بەکارایی بهێڵەوە تا 1 ڕۆژ\n       *[other] بەستەرەکان بەکارایی بهێڵەوە تا { $count } ڕۆژ\n    }\naccountBenefitSync = پەڕگە بڵآوکراوەکان بەڕێوەبەرە لەهەر ئامێرێکەوە\naccountBenefitMoz = زیاتر بزانە دەربارەی خزمەتگوزارییەکانی تری { -mozilla }\nsignOut = بچۆ دەرەوە\nokButton = باشە\ndownloadingTitle = دادەگیرێت...\nnoStreamsWarning = لەوانەیە ئەم وێبگەڕە نەتوانێت پەڕگەی وا گەورە بە هێما بکات.\nnoStreamsOptionCopy = بەستەر لەبەربگرەوە بۆ کردنەوەی لە وێبگەڕێکی تر\nnoStreamsOptionFirefox = وێبگەڕی دڵخوازی ئێمە تاقیبکەرەوە\nnoStreamsOptionDownload = بەردەوام بە لەگەڵ ئەم وێبگەڕە\ndownloadFirefoxPromo = { -send-short-brand } پیشکەش کراوە بە تۆ لە لایەن { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = بەستەر بڵاوبکەرەوە بۆ پەڕگەکەت:\nshareLinkButton = بەستەر بڵاوبکەرەوە\n# $name is the name of the file\nshareMessage = “{ $name }” دابگرە لەگەڵ { -send-brand }: سانا، پاریزراو لە بڵاوکردنەوەی پەڕگە\ntrailheadPromo = ڕێگەیەک هەیە بۆ پارێزگاریکردنی تایبەتێتی خۆت. بەشدار بە لە فایەرفۆکس.\nlearnMore = زیاتر بزانە\n"
  },
  {
    "path": "public/locales/cs/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Probíhá import…\nencryptingFile = Probíhá šifrování…\ndecryptingFile = Probíhá dešifrování…\ndownloadCount =\n    { $num ->\n        [one] jednom stažení\n        [few] { $num } staženích\n       *[other] { $num } staženích\n    }\ntimespanHours =\n    { $num ->\n        [one] hodinu\n        [few] { $num } hodiny\n       *[other] { $num } hodin\n    }\ncopiedUrl = Zkopírováno!\nunlockInputPlaceholder = Heslo\nunlockButtonLabel = Odemknout\ndownloadButtonLabel = Stáhnout\ndownloadFinish = Stahování dokončeno\nfileSizeProgress = ({ $partialSize } z { $totalSize })\nsendYourFilesLink = Vyzkoušet Send\nerrorPageHeader = Nastala chyba!\nfileTooBig = Tento soubor je příliš veliký. Velikost nahrávaných souborů by neměla překročit { $size }.\nlinkExpiredAlt = Platnost odkazu vypršela\nnotSupportedHeader = Váš prohlížeč není podporován.\nnotSupportedLink = Proč není můj prohlížeč podporovaný?\nnotSupportedOutdatedDetail = Tato verze Firefoxu bohužel nepodporuje webovou technologii, která pohání Send. Musíte aktualizovat svůj prohlížeč.\nupdateFirefox = Aktualizovat Firefox\ndeletePopupCancel = Zrušit\ndeleteButtonHover = Smazat\nfooterLinkLegal = Právní informace\nfooterLinkPrivacy = Soukromí\nfooterLinkCookies = Cookies\npasswordTryAgain = Špatné heslo. Zkuste to znovu.\njavascriptRequired = Send vyžaduje povolený JavaScript\nwhyJavascript = Proč Send vyžaduje povolený JavaScript?\nenableJavascript = Povolte JavaScript a zkuste to znovu.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } h { $minutes } m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maximální délka hesla: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Toto heslo nemohlo být nastaveno\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand =\n    { $case ->\n       *[nom] Send\n        [gen] Firefoxu Send\n        [dat] Firefoxu Send\n        [acc] Send\n        [voc] Firefoxe Send\n        [loc] Firefoxu Send\n        [ins] Firefoxem Send\n    }\n-send-short-brand =\n    { $case ->\n       *[nom] Send\n        [gen] Sendu\n        [dat] Sendu\n        [acc] Send\n        [voc] Sende\n        [loc] Sendu\n        [ins] Sendem\n    }\n-firefox =\n    { $case ->\n       *[nom] Firefox\n        [gen] Firefoxu\n        [dat] Firefoxu\n        [acc] Firefox\n        [voc] Firefoxe\n        [loc] Firefoxu\n        [ins] Firefoxem\n    }\n-mozilla =\n    { $case ->\n       *[nom] Mozilla\n        [gen] Mozilly\n        [dat] Mozille\n        [acc] Mozillu\n        [voc] Mozillo\n        [loc] Mozille\n        [ins] Mozillou\n    }\nintroTitle = Jednoduché a soukromé sdílení souborů\nintroDescription = S { -send-brand(case: \"ins\") } jsou sdílené soubory šifrované end-to-end, takže ani my nevíme, co sdílíte. Platnost odkazů je navíc omezená. Soubory tak můžete sdílet soukromě a s jistotou, že se nezůstanou na internetu válet navždy.\nnotifyUploadEncryptDone = Váš soubor je zašifrovaný a připraven k odeslání\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Platnost vyprší po { $downloadCount } nebo za { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] jednu minutu\n        [few] { $num } minuty\n       *[other] { $num } minut\n    }\ntimespanDays =\n    { $num ->\n        [one] jeden den\n        [few] { $num } dny\n       *[other] { $num } dní\n    }\ntimespanWeeks =\n    { $num ->\n        [one] týden\n        [few] { $num } týdny\n       *[other] { $num } týdnů\n    }\nfileCount =\n    { $num ->\n        [one] jeden soubor\n        [few] { $num } soubory\n       *[other] { $num } souborů\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Celková velikost: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Soubor můžete sdílet tímto odkazem:\ncopyLinkButton = Zkopírovat odkaz\ndownloadTitle = Stáhnout soubory\ndownloadDescription = Tento soubor byl sdílen přes { -send-brand(case: \"acc\") } s end-to-end šifrováním a odkazem s omezenou platností.\ntrySendDescription = Vyzkoušejte jednoduché a bezpečné sdílení souborů s { -send-brand(case: \"ins\") }\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Najednou lze nahrávat jen jeden soubor.\n        [few] Najednou lze nahrávat jen { $count } soubory.\n       *[other] Najednou lze nahrávat jen { $count } souborů.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Povolen je nejvýše jeden archiv.\n        [few] Povoleny jsou nejvýše { $count } archivy.\n       *[other] Povoleno je nejvýše { $count } archivů.\n    }\nexpiredTitle = Platnost tohoto odkazu vypršela.\nnotSupportedDescription = { -send-brand } nebude v tomto prohlížeči fungovat. Nejlépe { -send-short-brand } funguje v nejnovějším { -firefox(case: \"gen\") } nebo aktuálních verzích nejpoužívanějších prohlížečů.\ndownloadFirefox = Stáhnout { -firefox(case: \"acc\") }\nlegalTitle = Zásady { -send-short-brand(case: \"acc\") } pro ochranu osobních údajů\nlegalDateStamp = Verze 1.0, 12. března 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Vyberte soubory k nahrání\ntrustWarningMessage = Ujistěte se, že adresátovi důvěřujete pro sdílení vašich důvěrných dat.\nuploadButton = Nahrát\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Přetažením myší nebo kliknutím sem\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = můžete poslat až { $size }\naddPassword = Ochránit heslem\nemailPlaceholder = Zadejte svoji e-mailovou adresu\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Pro odesílání souborů o velikosti až { $size } se prosím přihlaste\nsignInOnlyButton = Přihlásit se\naccountBenefitTitle = Vytvořte si účet { -firefox(case: \"gen\") } nebo se přihlaste\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Sdílejte soubory o velikosti až { $size }\naccountBenefitDownloadCount = Sdílejte soubory s více lidmi\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Odkazy platné až jeden den\n        [few] Odkazy platné až { $count } dny\n       *[other] Odkazy platné až { $count } dní\n    }\naccountBenefitSync = Správa sdílených souborů z jakéhokoliv zařízení\naccountBenefitMoz = Více informací o dalších službách od { -mozilla(case: \"gen\") }\nsignOut = Odhlásit se\nokButton = OK\ndownloadingTitle = Stahování\nnoStreamsWarning = Dešifrování tak velikého souboru se v tomto prohlížeči nemusí podařit.\nnoStreamsOptionCopy = Zkopírujte odkaz pro otevření v jiném prohlížeči\nnoStreamsOptionFirefox = Vyzkoušejte náš oblíbený prohlížeč\nnoStreamsOptionDownload = Pokračovat v tomto prohlížeči\ndownloadFirefoxPromo = { -send-short-brand } od aplikace { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Sdílet odkaz na soubor:\nshareLinkButton = Sdílet odkaz\n# $name is the name of the file\nshareMessage = Stáhněte si soubor „{ $name }“ s { -send-brand(case: \"ins\") } - jednoduché a bezpečné sdílení souborů\ntrailheadPromo = Existuje způsob, jak ochránit své soukromí. Používejte Firefox.\nlearnMore = Zjistit více.\ndownloadFlagged = Tento odkaz byl pro porušení podmínek používání služby deaktivován.\ndownloadConfirmTitle = Ještě jedna věc\ndownloadConfirmDescription = Ujistěte se, že opravdu důvěřujete odesílateli tohoto souboru, protože nemůžeme potvrdit bezpečnost jeho otevření na vašem zařízení.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Odesílateli tohoto souboru důvěřuji\n        [few] Odesílateli těchto souborů důvěřuji\n       *[other] Odesílateli těchto souborů důvěřuji\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Nahlásit tento soubor jako podezřelý\n        [few] Nahlásit tyto soubory jako podezřelé\n       *[other] Nahlásit tyto soubory jako podezřelé\n    }\nreportDescription = Pomozte nám. Co si myslíte, že je s těmito soubory špatně?\nreportUnknownDescription = Otevřete odkaz, který chcete nahlásit, a klepněte na „{ reportFile }“.\nreportButton = Nahlásit\nreportReasonMalware = Tyto soubory obsahují malware nebo jsou součástí phishingového útoku.\nreportReasonPii = Tyto soubory obsahují mé osobní údaje.\nreportReasonAbuse = Tyto soubory obsahují nelegální nebo urážlivý obsah.\nreportReasonCopyright = Chcete-li nahlásit porušení autorských práv nebo ochranných známek, použijte postup popsaný na <a>této stránce</a>.\nreportedTitle = Soubory byly nahlášeny\nreportedDescription = Děkujeme vám za zaslané hlášení ohledně těchto souborů.\n"
  },
  {
    "path": "public/locales/cy/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Mewnforio…\nencryptingFile = Wrthi'n amgryptio…\ndecryptingFile = Wrthi'n dadgryptio…\ndownloadCount =\n    { $num ->\n        [zero] Dim llwythi i lawr\n        [one] 1 llwyth i lawr\n        [two] { $num } llwyth i lawr\n        [few] { $num } llwyth i lawr\n        [many] { $num } llwyth i lawr\n       *[other] { $num } llwyth i lawr\n    }\ntimespanHours =\n    { $num ->\n        [zero] awr\n        [one] 1 awr\n        [two] { $num } awr\n        [few] { $num } awr\n        [many] { $num } awr\n       *[other] { $num } awr\n    }\ncopiedUrl = Wedi eu copïo!\nunlockInputPlaceholder = Cyfrinair\nunlockButtonLabel = Datgloi\ndownloadButtonLabel = Llwytho i Lawr\ndownloadFinish = Llwytho wedi Gorffen\nfileSizeProgress = ({ $partialSize } o { $totalSize })\nsendYourFilesLink = Rhowch gynnig ar Send\nerrorPageHeader = Aeth rhywbeth o'i le!\nfileTooBig = Mae'r ffeil yn rhy fawr i'w llwytho. Dylai fod yn llai na { $size }.\nlinkExpiredAlt = Mae'r ddolen wedi dod i ben\nnotSupportedHeader = Nid yw eich porwr yn cael ei gynnal.\nnotSupportedLink = Pam nad yw fy mhorwr yn cael ei gynnal?\nnotSupportedOutdatedDetail = Yn anffodus, nid yw'r fersiwn yma o Firefox yn cynnal y technoleg gwe sy'n gyrru Send. Bydd angen i chi ddiweddaru eich porwr.\nupdateFirefox = Diweddaru Firefox\ndeletePopupCancel = Diddymu\ndeleteButtonHover = Dileu\nfooterLinkLegal = Cyfreithiol\nfooterLinkPrivacy = Preifatrwydd\nfooterLinkCookies = Cwcis\npasswordTryAgain = Cyfrinair anghywir. Ceisiwch eto.\njavascriptRequired = Mae Send angen JavaScript\nwhyJavascript = Pam fod Send angen JavaScript?\nenableJavascript = Galluogwch JavaScript a cheisio eto.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }a { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Hyd mwyaf cyfrinair: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Nid oedd modd gosod y cyfrinair hwn\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Anfon\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Rhannu ffeiliau syml a phreifat\nintroDescription = Mae { -send-brand } yn gadael i chi rannu ffeiliau gydag amgryptio o'r dechrau i'r diwedd a dolen sy'n dod i ben yn awtomatig. Felly gallwch chi gadw'r hyn rydych chi'n ei rannu'n breifat a sicrhau nad yw'ch pethau'n aros ar-lein am byth.\nnotifyUploadEncryptDone = Mae eich ffeil wedi'i hamgryptio ac yn barod i'w hanfon\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Yn dod i ben ar ôl { $downloadCount } neu { $timespan }\ntimespanMinutes =\n    { $num ->\n        [zero] 0 munud\n        [one] 1 munud\n        [two] { $num } munud\n        [few] { $num } munud\n        [many] { $num } munud\n       *[other] { $num } munud\n    }\ntimespanDays =\n    { $num ->\n        [zero] 0 diwrnod\n        [one] 1 diwrnod\n        [two] { $num } diwrnod\n        [few] { $num } diwrnod\n        [many] { $num } diwrnod\n       *[other] { $num } diwrnod\n    }\ntimespanWeeks =\n    { $num ->\n        [zero] 0 wythnos\n        [one] 1 wythnos\n        [two] { $num } wythnos\n        [few] { $num } wythnos\n        [many] { $num } wythnos\n       *[other] { $num } wythnos\n    }\nfileCount =\n    { $num ->\n        [zero] 0 ffeil\n        [one] 1 ffeil\n        [two] { $num } ffeil\n        [few] { $num } ffeil\n        [many] { $num } ffeil\n       *[other] { $num } ffeil\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Cyfanswm maint: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copïwch y ddolen i rannu eich ffeil:\ncopyLinkButton = Copïo'r ddolen\ndownloadTitle = Llwytho ffeiliau i lawr\ndownloadDescription = Rhannwyd y ffeil hon trwy { -send-brand } gydag amgryptiad o'r dechrau i'r diwedd a dolen sy'n dod i ben yn awtomatig.\ntrySendDescription = Rhowch gynnig ar { -send-brand } ar gyfer rhannu ffeiliau syml a diogel.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [zero] Nid oes modd llwytho ffeiliau i fyny.\n        [one] Dim ond 1 ffeil y mae modd ei llwytho i fyny ar y tro.\n        [two] Dim ond ffeiliau { $count } y mae modd eu llwytho i fyny ar y tro.\n        [few] Dim ond ffeiliau { $count } y mae modd eu llwytho i fyny ar y tro.\n        [many] Dim ond ffeiliau { $count } y mae modd eu llwytho i fyny ar y tro.\n       *[other] Dim ond ffeiliau { $count } y mae modd eu llwytho i fyny ar y tro.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [zero] Dim caniatâd i archifau.\n        [one] Dim ond 1 archif y'n cael ei ganiatáu.\n        [two] Dim ond { $count } archif sy'n cael eu caniatáu.\n        [few] Dim ond { $count } archif sy'n cael eu caniatáu.\n        [many] Dim ond { $count } archif sy'n cael eu caniatáu.\n       *[other] Dim ond { $count } archif sy'n cael eu caniatáu.\n    }\nexpiredTitle = Mae'r ddolen hon wedi dod i ben.\nnotSupportedDescription = Ni fydd { -send-brand } yn gweithio gyda'r porwr hwn. Mae { -send-short-brand } yn gweithio orau gyda'r fersiwn ddiweddaraf o { -firefox }, a bydd yn gweithio gyda'r fersiwn gyfredol o'r rhan fwyaf o borwyr.\ndownloadFirefox = Llwytho { -firefox } i Lawr\nlegalTitle = Hysbysiad Preifatrwydd { -send-short-brand }\nlegalDateStamp = Fersiwn 1.0, dyddiedig Mawrth 12, 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } d { $hours } a { $minutes } m\naddFilesButton = Dewis ffeiliau i'w llwytho i fyny\ntrustWarningMessage = Gwnewch yn siŵr eich bod yn ymddiried yn eich derbynnydd pan yn rhannu data sensitif.\nuploadButton = Llwytho i fyny\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Llusgo a gollwng ffeiliau\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = neu glicio i anfon hyd at { $size }\naddPassword = Diogelu gyda chyfrinair\nemailPlaceholder = Rhowch eich e-bost\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Mewngofnodi i anfon hyd at { $size }\nsignInOnlyButton = Mewngofnodi\naccountBenefitTitle = Creu Cyfrif { -firefox } neu fewngofnodi\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Rhannu ffeiliau hyd at { $size }\naccountBenefitDownloadCount = Rhannu ffeiliau gyda mwy o bobl\naccountBenefitTimeLimit =\n    { $count ->\n        [zero] Cadw dolenni'n weithredol am hyd at 0 diwrnod\n        [one] Cadw dolenni'n weithredol am hyd at 1 diwrnod\n        [two] Cadw dolenni'n weithredol am hyd at { $count } diwrnod\n        [few] Cadw dolenni'n weithredol am hyd at { $count } diwrnod\n        [many] Cadw dolenni'n weithredol am hyd at { $count } diwrnod\n       *[other] Cadw dolenni'n weithredol am hyd at { $count } diwrnod\n    }\naccountBenefitSync = Rheoli ffeiliau sy'n cael eu rhannu o unrhyw ddyfais\naccountBenefitMoz = Dysgu am wasanaethau eraill { -mozilla }\nsignOut = Allgofnodi\nokButton = Iawn\ndownloadingTitle = Llwytho i Lawr\nnoStreamsWarning = Efallai na fydd y porwr hwn yn gallu dadgryptio ffeil mor fawr a hon.\nnoStreamsOptionCopy = Copïwch y ddolen i'w agor mewn porwr arall\nnoStreamsOptionFirefox = Rhowch gynnig ar ein hoff porwr\nnoStreamsOptionDownload = Parhau gyda'r porwr hwn\ndownloadFirefoxPromo = Mae { -send-short-brand } yn cael ei gynnig i ci gan y { -firefox } newydd.\n# the next line after the colon contains a file name\nshareLinkDescription = Rhannu'r ddolen i'ch ffeil:\nshareLinkButton = Rhannu'r ddolen\n# $name is the name of the file\nshareMessage = Llwytho i lawr “{ $name }” gyda { -send-brand }: rhannu ffeiliau syml a diogel\ntrailheadPromo = Mae ffordd o ddiogelu eich preifatrwydd. Ymunwch â Firefox.\nlearnMore = Dysgu rhagor.\ndownloadFlagged = Mae'r ddolen wedi'i analluogi am fynd yn groes i'r telerau gwasanaeth.\ndownloadConfirmTitle = Un peth arall\ndownloadConfirmDescription = Gwnewch yn siŵr eich bod yn ymddiried yn y person a anfonodd y ffeil hon atoch oherwydd nid ydym yn gallu gwirio na fydd yn niweidio'ch dyfais.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [zero] Rwy'n ymddiried yn y person anfonodd yr { $count } ffeil yma\n        [one] Rwy'n ymddiried yn y person anfonodd yr { $count } ffeil yma\n        [two] Rwy'n ymddiried yn y person anfonodd yr { $count } ffeil yma\n        [few] Rwy'n ymddiried yn y person anfonodd yr { $count } ffeil yma\n        [many] Rwy'n ymddiried yn y person anfonodd yr { $count } ffeil yma\n       *[other] Rwy'n ymddiried yn y person anfonodd yr { $count } ffeil yma\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [zero] Adrodd y { $count } ffeil yma fel rhai amheus\n        [one] Adrodd y { $count } ffeil yma fel un amheus\n        [two] Adrodd y { $count } ffeil yma fel rhai amheus\n        [few] Adrodd y { $count } ffeil yma fel rhai amheus\n        [many] Adrodd y { $count } ffeil yma fel rhai amheus\n       *[other] Adrodd y { $count } ffeil yma fel rhai amheus\n    }\nreportDescription = Helpwch ni i ddeall beth sy'n digwydd. Beth ydych chi'n meddwl sydd o'i le gyda'r ffeiliau hyn?\nreportUnknownDescription = Ewch i url y ddolen rydych am adrodd amdani a chlicio “{ reportFile }”.\nreportButton = Adrodd\nreportReasonMalware = Mae'r ffeiliau hyn yn cynnwys meddalwedd maleisus neu'n rhan o ymosodiad gwe-rwydo.\nreportReasonPii = Mae'r ffeiliau hyn yn cynnwys gwybodaeth bersonol adnabyddadwy amdanaf i.\nreportReasonAbuse = Mae'r ffeiliau hyn yn cynnwys deunydd anghyfreithlon neu ymosodol.\nreportReasonCopyright = I adrodd ar dorri hawlfraint neu nod masnach, defnyddiwch y broses sy'n cael ei ddisgrifio yn y <a>dudalen hon</a>.\nreportedTitle = Ffeiliau Adroddwyd Amdanynt\nreportedDescription = Diolch. Rydym wedi derbyn eich adroddiad ar y ffeiliau hyn.\n"
  },
  {
    "path": "public/locales/da/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importerer…\nencryptingFile = Krypterer…\ndecryptingFile = Dekrypterer…\ndownloadCount =\n    { $num ->\n        [one] 1 hentning\n       *[other] { $num } hentninger\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 time\n       *[other] { $num } timer\n    }\ncopiedUrl = Kopieret!\nunlockInputPlaceholder = Adgangskode\nunlockButtonLabel = Lås op\ndownloadButtonLabel = Hent\ndownloadFinish = Hentning fuldført\nfileSizeProgress = ({ $partialSize } af { $totalSize })\nsendYourFilesLink = Prøv Send\nerrorPageHeader = Der gik noget galt!\nfileTooBig = Den fil er for stor at uploade. Den skal være mindre end { $size }.\nlinkExpiredAlt = Link er udløbet\nnotSupportedHeader = Din browser understøttes ikke.\nnotSupportedLink = Hvorfor understøttes min browser ikke?\nnotSupportedOutdatedDetail = Desværre understøtter denne version af Firefox ikke den webteknologi, som driver Send. Du skal opdatere din browser.\nupdateFirefox = Opdater Firefox\ndeletePopupCancel = Annuller\ndeleteButtonHover = Slet\nfooterLinkLegal = Juridisk\nfooterLinkPrivacy = Privatliv\nfooterLinkCookies = Cookies\npasswordTryAgain = Forkert adgangskode. Prøv igen.\njavascriptRequired = Send kræver JavaScript\nwhyJavascript = Hvorfor kræver Send JavaScript?\nenableJavascript = Aktiver JavaScript og prøv igen.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } t { $minutes } m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maksimum længde af adgangskode: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Adgangskoden kunne ikke sættes\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Enkel, privat fildeling\nintroDescription = { -send-brand } gør det muligt at dele filer via et tidsbegrænset link og med end to end-kryptering. På den måde kan du dele filer privat og samtidig være sikker på, at det delte ikke forbliver online for evigt.\nnotifyUploadEncryptDone = Din fil er krypteret og klar til at blive sendt\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Udløber efter { $downloadCount } eller { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minut\n       *[other] { $num } minutter\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 dag\n       *[other] { $num } dage\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 uge\n       *[other] { $num } uger\n    }\nfileCount =\n    { $num ->\n        [one] 1 fil\n       *[other] { $num } filer\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Samlet størrelse: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopier linket for at dele din fil:\ncopyLinkButton = Kopier link\ndownloadTitle = Hent filer\ndownloadDescription = Denne fil blev delt via { -send-brand } med end to end-kryptering og et link, der automatisk udløber.\ntrySendDescription = Prøv { -send-brand } for enkel og sikker fildeling.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Du kan kun uploade 1 fil ad gangen.\n       *[other] Du kan kun uploade { $count } filer ad gangen.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Kun 1 arkiv er tilladt.\n       *[other] Kun { $count } arkiver er tilladt.\n    }\nexpiredTitle = Dette link er udløbet.\nnotSupportedDescription = { -send-brand } virker ikke med denne browser. { -send-short-brand } virker bedst med den nyeste version af { -firefox } og med de fleste andre nye browsere.\ndownloadFirefox = Hent { -firefox }\nlegalTitle = { -send-short-brand }, om privatlivspolitik\nlegalDateStamp = Version 1.0, udsendt d. 12. marts 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } d. { $hours } t. { $minutes } m.\naddFilesButton = Vælg filer, der skal uploades\ntrustWarningMessage = Vær sikker på, at du stoler på modtageren, når du deler følsomme data.\nuploadButton = Upload\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Træk og slip filer\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = eller klik for at sende filer på op til { $size }\naddPassword = Beskyt med adgangskode\nemailPlaceholder = Indtast din mailadresse\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Log ind for at sende filer på op til { $size }\nsignInOnlyButton = Log ind\naccountBenefitTitle = Opret en { -firefox }-konto eller log ind\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Del filer på op til { $size }\naccountBenefitDownloadCount = Del filer med flere personer\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Bevar links aktive i op til 1 dag\n       *[other] Bevar links aktive i op til { $count } dage\n    }\naccountBenefitSync = Håndter delte filer på enhver enhed\naccountBenefitMoz = Læs om andre tjenester fra { -mozilla }\nsignOut = Log ud\nokButton = OK\ndownloadingTitle = Henter\nnoStreamsWarning = Denne browser kan muligvis ikke dekryptere en fil, der er så stor.\nnoStreamsOptionCopy = Kopier linket for at åbne det i en anden browser\nnoStreamsOptionFirefox = Prøv vores favorit-browser\nnoStreamsOptionDownload = Fortsæt med denne browser\ndownloadFirefoxPromo = { -send-short-brand } præsenteres af den nye { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Del linket til din fil:\nshareLinkButton = Del link\n# $name is the name of the file\nshareMessage = Hent { $name } med { -send-brand } - simpel og sikker fildeling\ntrailheadPromo = Beskyt dine digitale rettigheder. Slut dig til Firefox.\nlearnMore = Læs mere.\ndownloadFlagged = Dette link er blevet deaktiveret for overtrædelse af tjenestevilkårene.\ndownloadConfirmTitle = En ting til\ndownloadConfirmDescription = Vær sikker på, at du stoler på afsenderen af ​​denne fil, da vi ikke kan garantere, at den ikke vil skade din enhed.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Jeg stoler på personen, som sendte denne fil\n       *[other] Jeg stoler på personen, som sendte disse filer\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Rapportér denne fil som mistænkelig\n       *[other] Rapportér disse filer som mistænkelige\n    }\nreportDescription = Hjælp os med at forstå, hvad der foregår. Hvad er der i vejen med disse filer?\nreportUnknownDescription = Gå til adressen på det link, du vil rapportere, og klik på “{ reportFile }”.\nreportButton = Rapportér\nreportReasonMalware = Disse filer indeholder malware eller er en del af et phishing-angreb.\nreportReasonPii = Disse filer indeholder oplysninger om mig, der er personligt identificerbare.\nreportReasonAbuse = Disse filer indeholder ulovligt eller voldeligt indhold.\nreportReasonCopyright = Hvis du vil rapportere overtrædelse af ophavsrettigheder eller varemærker, skal du bruge processen, som er beskrevet på <a>denne side</a>.\nreportedTitle = Rapporterede filer\nreportedDescription = Tak. Vi har modtaget din rapport om disse filer.\n"
  },
  {
    "path": "public/locales/de/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Wird importiert…\nencryptingFile = Wird verschlüsselt…\ndecryptingFile = Wird entschlüsselt…\ndownloadCount =\n    { $num ->\n        [one] einem Download\n       *[other] { $num } Downloads\n    }\ntimespanHours =\n    { $num ->\n        [one] einer Stunde\n       *[other] { $num } Stunden\n    }\ncopiedUrl = Kopiert!\nunlockInputPlaceholder = Passwort\nunlockButtonLabel = Entsperren\ndownloadButtonLabel = Herunterladen\ndownloadFinish = Download abgeschlossen\nfileSizeProgress = ({ $partialSize } von { $totalSize })\nsendYourFilesLink = Send ausprobieren\nerrorPageHeader = Ein Fehler ist aufgetreten!\nfileTooBig = Die Datei ist zu groß zum Hochladen. Sie sollte maximal { $size } groß sein.\nlinkExpiredAlt = Link abgelaufen\nnotSupportedHeader = Dein Browser wird nicht unterstützt.\nnotSupportedLink = Warum wird mein Browser nicht unterstützt?\nnotSupportedOutdatedDetail = Leider unterstützt diese Firefox-Version die Web-Technologie nicht, auf der Send basiert. Du musst deinen Browser aktualisieren.\nupdateFirefox = Firefox aktualisieren\ndeletePopupCancel = Abbrechen\ndeleteButtonHover = Löschen\nfooterLinkLegal = Rechtliches\nfooterLinkPrivacy = Datenschutz\nfooterLinkCookies = Cookies\npasswordTryAgain = Falsches Passwort. Versuche es nochmal.\njavascriptRequired = Send benötigt JavaScript\nwhyJavascript = Warum benötigt Send JavaScript?\nenableJavascript = Bitte aktiviere JavaScript und versuche es erneut.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maximale Passwortlänge: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Dieses Passwort konnte nicht eingerichtet werden\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Einfach und privat Dateien versenden\nintroDescription = Mit { -send-brand } kannst du Dateien sicher mit anderen teilen – mit End-to-End-Verschlüsselung und einem Freigabe-Link, der automatisch abläuft. So bleiben deine geteilten Inhalte privat und du kannst sicherstellen, dass deine Daten nicht für immer im Web herumschwirren.\nnotifyUploadEncryptDone = Deine Datei ist verschlüsselt und zum Senden bereit\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Läuft ab nach { $downloadCount } oder { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 Minute\n       *[other] { $num } Minuten\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 Tag\n       *[other] { $num } Tage\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 Woche\n       *[other] { $num } Wochen\n    }\nfileCount =\n    { $num ->\n        [one] 1 Datei\n       *[other] { $num } Dateien\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Gesamtgröße: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopiere den Link, um deine Datei zu teilen:\ncopyLinkButton = Link kopieren\ndownloadTitle = Dateien herunterladen\ndownloadDescription = Diese Datei wurde über { -send-brand } mit End-to-End-Verschlüsselung und einem automatisch ablaufenden Link geteilt.\ntrySendDescription = Probiere { -send-brand } aus, um einfach und sicher Dateien zu versenden.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Es kann maximal eine Datei auf einmal hochgeladen werden.\n       *[other] Es können maximal { $count } Dateien auf einmal hochgeladen werden.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Es ist nur ein  Archiv erlaubt.\n       *[other] Es sind nur { $count } Archive erlaubt.\n    }\nexpiredTitle = Dieser Link ist abgelaufen.\nnotSupportedDescription = { -send-brand } funktioniert nicht mit diesem Browser. { -send-short-brand } funktioniert am besten mit der neuesten Version von { -firefox } und funktioniert mit der aktuellen Version der meisten Browser.\ndownloadFirefox = { -firefox } herunterladen\nlegalTitle = Datenschutzerklärung zu { -send-short-brand }\nlegalDateStamp = Version 1.0, Stand 12. März 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Dateien zum Hochladen auswählen\ntrustWarningMessage = Sie sollten dem Empfänger vertrauen, wenn Sie vertrauliche Daten weitergeben.\nuploadButton = Hochladen\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Dateien per Drag & Drop einfügen\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = oder klicken, um bis zu { $size } zu senden\naddPassword = Mit Passwort schützen\nemailPlaceholder = E-Mail-Adresse eingeben\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Melde dich an, um Dateien bis { $size } zu senden\nsignInOnlyButton = Anmelden\naccountBenefitTitle = Erstelle ein { -firefox }-Konto oder melde dich an\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Dateien bis zu { $size } teilen\naccountBenefitDownloadCount = Teile Dateien mit weiteren Leuten\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Link bis zu einen Tag lang aktiv halten\n       *[other] Link bis zu { $count } Tage lang aktiv halten\n    }\naccountBenefitSync = Geteilte Dateien von anderen Geräten aus verwalten\naccountBenefitMoz = Erfahre mehr über andere { -mozilla }-Dienste\nsignOut = Abmelden\nokButton = OK\ndownloadingTitle = Wird heruntergeladen…\nnoStreamsWarning = Dieser Browser kann eine so große Datei möglicherweise nicht entschlüsseln.\nnoStreamsOptionCopy = Kopiere den Link, um ihn in einem anderen Browser zu öffnen\nnoStreamsOptionFirefox = Probiere unseren Lieblingsbrowser aus\nnoStreamsOptionDownload = Mit diesem Browser weitermachen\ndownloadFirefoxPromo = { -send-short-brand } wird Ihnen präsentiert vom brandneuen { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Teilen Sie den Link zu Ihrer Datei:\nshareLinkButton = Link teilen\n# $name is the name of the file\nshareMessage = Laden Sie „{ $name }“ mit { -send-brand } herunter: einfaches, sicheres Teilen von Dateien\ntrailheadPromo = Es gibt einen Weg, deine Privatsphäre zu schützen. Komm zu Firefox.\nlearnMore = Mehr erfahren.\ndownloadFlagged = Dieser Link wurde wegen Verstoßes gegen die Nutzungsbedingungen deaktiviert.\ndownloadConfirmTitle = Eine Sache noch\ndownloadConfirmDescription = Sie sollten dem Absender dieser Datei vertrauen, da wir nicht überprüfen können, ob Ihr Gerät dadurch beschädigt wird.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Ich vertraue der Person, die diese Datei gesendet hat\n       *[other] Ich vertraue der Person, die diese Dateien gesendet hat\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Diese Datei als verdächtig melden\n       *[other] Diese Dateien als verdächtig melden\n    }\nreportDescription = Helfen Sie uns mit weiteren Informationen. Wo liegt das Problem bei diesen Dateien?\nreportUnknownDescription = Bitte besuchen Sie die Adresse des Links, den Sie melden möchten, und klicken Sie auf „{ reportFile }“.\nreportButton = Melden\nreportReasonMalware = Diese Dateien enthalten Malware oder sind Teil eines Phishing-Angriffs.\nreportReasonPii = Diese Dateien enthalten personenbezogene Daten über mich.\nreportReasonAbuse = Diese Dateien enthalten illegale oder missbräuchliche Inhalte.\nreportReasonCopyright = Um Urheber- oder Markenrechtsverletzungen zu melden, nutzen Sie bitte das auf <a>dieser Seite</a> beschriebene Verfahren.\nreportedTitle = Dateien gemeldet\nreportedDescription = Vielen Dank. Wir haben Ihren Bericht über diese Dateien erhalten.\n"
  },
  {
    "path": "public/locales/dsb/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importěrujo se...\nencryptingFile = Koděrujo se...\ndecryptingFile = Dešifrěrujo se...\ndownloadCount =\n    { $num ->\n        [one] 1 ześěgnjenje\n        [two] { $num } ześěgnjeni\n        [few] { $num } ześěgnjenja\n       *[other] { $num } ześěgnjenjow\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 góźina\n        [two] { $num } góźinje\n        [few] { $num } góźiny\n       *[other] { $num } góźin\n    }\ncopiedUrl = Kopěrowany!\nunlockInputPlaceholder = Gronidło\nunlockButtonLabel = Wótwóriś\ndownloadButtonLabel = Ześěgnuś\ndownloadFinish = Ześěgnjenje dokóńcone\nfileSizeProgress = ({ $partialSize } z { $totalSize })\nsendYourFilesLink = Send wopytaś\nerrorPageHeader = Něco njejo se raźiło!\nfileTooBig = Toś ta dataja jo pśewjelika za nagraśe. Měła mjeńša ako { $size } byś.\nlinkExpiredAlt = Wótkaz spadnjony\nnotSupportedHeader = Waš wobglědowak se njepódpěra.\nnotSupportedLink = Cogodla se mój wobglědowak njepódpěra?\nnotSupportedOutdatedDetail = Bóžko toś ta wersija Firefox webtechnologiju njepódpěra, na kótarejž Send bazěrujo. Musyśo swój wobglědowak aktualizěrowaś.\nupdateFirefox = Firefox aktualizěrowaś\ndeletePopupCancel = Pśetergnuś\ndeleteButtonHover = Wulašowaś\nfooterLinkLegal = Pšawniske\nfooterLinkPrivacy = Priwatnosć\nfooterLinkCookies = Cookieje\npasswordTryAgain = Wopacne gronidło. Wopytajśo hyšći raz.\njavascriptRequired = Send JavaScript trjeba\nwhyJavascript = Cogodla Send JavaScript trjeba?\nenableJavascript = Pšosym zmóžniśo JavaScript a wopytajśo hyšći raz.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } góź. { $minutes } min.\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } min.\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maksimalna dłujkosć gronidła: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Toś to gronidło njedajo se nastajiś\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Jadnore, priwatne datajowe źělenje\nintroDescription = { -send-brand } wam zmóžnja, dataje z koděrowanim kóńc do kóńca a wótkazom źěliś, kótaryž awtomatiski spadnjo. Tak móžośo źělone wopśimjeśe priwatne źaržaś a zawěsćiś, až waše daty online na pśecej njewóstanu.\nnotifyUploadEncryptDone = Waša dataja jo skoděrowana za słanje\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Spadnjo pó { $downloadCount } abo { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] { $num } minuta\n        [two] { $num } minuśe\n        [few] { $num } minuty\n       *[other] { $num } minutow\n    }\ntimespanDays =\n    { $num ->\n        [one] { $num } źeń\n        [two] { $num } dnja\n        [few] { $num } dny\n       *[other] { $num } dnjow\n    }\ntimespanWeeks =\n    { $num ->\n        [one] { $num } tyźeń\n        [two] { $num } tyźenja\n        [few] { $num } tyźenje\n       *[other] { $num } tyźenjow\n    }\nfileCount =\n    { $num ->\n        [one] { $num } dataja\n        [two] { $num } dataji\n        [few] { $num } dataje\n       *[other] { $num } datajow\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Cełkowna wjelikosć: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopěrujśo wótkaz, aby swóju dataju źělił:\ncopyLinkButton = Wótkaz kopěrowaś\ndownloadTitle = Dataje ześěgnuś\ndownloadDescription = Toś ta dataja jo se pśez { -send-brand } z koděrowanim kóńc do kóńca a wótkazom źěliła, kótaryž awtomatiski spadnjo.\ntrySendDescription = Wopytajśo { -send-brand } za jadnore, wěste datajowe źělenje.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Jano { $count } dataja dajo se naraz nagraś.\n        [two] Jano { $count } dataji dajotej se naraz nagraś.\n        [few] Jano { $count } dataje daju se naraz nagraś.\n       *[other] Jano { $count } datajow dajo se naraz nagraś.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Jano { $count } archiw jo dowólony.\n        [two] Jano { $count } archiwa stej dowólonej.\n        [few] Jano { $count } archiwy su dowólone.\n       *[other] Jano { $count } archiwow jo dowólone.\n    }\nexpiredTitle = Toś ten wótkaz jo spadnjony.\nnotSupportedDescription = { -send-brand } z toś tym wobglědowakom njefunkcioněrujo. { -send-short-brand } nejlěpjej z nejnowšeju wersiju { -firefox } funkcioněrujo, a funkcioněrujo z aktualneju wersiju nejwěcej wobglědowakow.\ndownloadFirefox = { -firefox } ześěgnuś\nlegalTitle = Powěźeńka priwatnosći { -send-short-brand }\nlegalDateStamp = Wersija 1.0 wót 12. měrca 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }ź { $hours }g { $minutes }m\naddFilesButton = Dataje za nagrawanje wubraś\ntrustWarningMessage = Wy měł dostawarjeju dowěriś, gaž sensibelne daty źěliśo.\nuploadButton = Nagraś\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Śěgniśo a wótpołožćo dataje\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = abo klikniśo, aby do { $size } pósłał\naddPassword = Z gronidłom šćitaś\nemailPlaceholder = Zapódajśo swóju e-mailowu adresu\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Pśizjawśo se, aby do { $size } pósłał\nsignInOnlyButton = Pśizjawiś\naccountBenefitTitle = Załožćo konto { -firefox } abo pśizjawśo se\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Dataje do { $size } źěliś\naccountBenefitDownloadCount = Dataje z wěcej luźimi źěliś\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Wótkaze do { $count } dnja aktiwne źaržaś\n        [two] Wótkaze do { $count } dnjowu aktiwne źaržaś\n        [few] Wótkaze do { $count } dnjow aktiwne źaržaś\n       *[other] Wótkaze do { $count } dnjow aktiwne źaržaś\n    }\naccountBenefitSync = Źělone dataje z někakego rěda zastojaś\naccountBenefitMoz = Zgóńśo wěcej wó drugich słužbach { -mozilla }\nsignOut = Wótzjawiś\nokButton = W pórěźe\ndownloadingTitle = Ześěgujo se\nnoStreamsWarning = Toś ten wobglědowak njamógał taku wjeliku dataju dešifrěrowaś.\nnoStreamsOptionCopy = Kopěrujśo wótkaz, aby jen w drugim wobglědowaku wócynił\nnoStreamsOptionFirefox = Wopytajśo naš nejlubšy wobglědowak\nnoStreamsOptionDownload = Z toś tym wobglědowakom pókšacowaś\ndownloadFirefoxPromo = { -send-short-brand } se wam pśez cele nowy { -firefox } pśinjaso.\n# the next line after the colon contains a file name\nshareLinkDescription = Źělśo wótkaz k swójej dataji:\nshareLinkButton = Wótkaz źěliś\n# $name is the name of the file\nshareMessage = Ześěgniśo „{ $name }“ z { -send-brand }: jadnore, wěste źělenje datajow\ntrailheadPromo = Jo móžnosć, wašu priwatnosć šćitaś. Pśiźćo k Firefox.\nlearnMore = Dalšne informacije.\ndownloadFlagged = Toś ten wótkaz jo se znjemóžnił pśestupjenja wužywańskich wuměnjenjow dla.\ndownloadConfirmTitle = Jadna wěc hyšći\ndownloadConfirmDescription = Wy měł wótpósłarjeju toś teje dataje dowěriś, dokulaž njamóžomy pśeglědaś, lěc to waš rěd kazy.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Dowěrim wósobje, kótaraž jo pósłała toś tu dataju\n        [two] Dowěrim wósobje, kótaraž jo pósłała toś tej dataji\n        [few] Dowěrim wósobje, kótaraž jo pósłała toś te dataje\n       *[other] Dowěrim wósobje, kótaraž jo pósłała toś te dataje\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Toś tu dataju ako suspektnu k wěsći daś\n        [two] Toś tej dataji ako suspektnej k wěsći daś\n        [few] Toś te dataje ako suspektne k wěsći daś\n       *[other] Toś te dataje ako suspektne k wěsći daś\n    }\nreportDescription = Pomagajśo nam rozumić, co se stawa. Co pó wašom měnjenju njejo w pórědku z toś tymi datajami?\nreportUnknownDescription = Źiśo pšosym k URL wótkaza, kótaryž cośo k wěsći daś a klikniśo na „{ reportFile }“.\nreportButton = K wěsći daś\nreportReasonMalware = Toś te dataje škódnu softwaru wopśimuju abo su źěl napada kšadnjenja datow.\nreportReasonPii = Toś te dataje wósobinske informacije wó mnje, kótarež mógu mě identificěrowaś.\nreportReasonAbuse = Toś te dataje njedowólone abo ranjece wopśimjeśe wopśimuju.\nreportReasonCopyright = Aby pśestupjenje awtorskego pšawa abo pšawa wikowwych markow k wěsći dał, wužywajśo póstupowanje, kótarež se na <a>toś tom boku</a> wopisujo.\nreportedTitle = Dataje k wěsći dane\nreportedDescription = Wjeliki źěk. Smy dostali wašu rozpšawu wó toś tych datajach.\n"
  },
  {
    "path": "public/locales/el/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Εισαγωγή…\nencryptingFile = Κρυπτογράφηση…\ndecryptingFile = Αποκρυπτογράφηση…\ndownloadCount =\n    { $num ->\n        [one] 1 λήψη\n       *[other] { $num } λήψεις\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 ώρα\n       *[other] { $num } ώρες\n    }\ncopiedUrl = Αντιγράφτηκε!\nunlockInputPlaceholder = Κωδικός πρόσβασης\nunlockButtonLabel = Ξεκλείδωμα\ndownloadButtonLabel = Λήψη\ndownloadFinish = Η λήψη ολοκληρώθηκε\nfileSizeProgress = ({ $partialSize } από { $totalSize })\nsendYourFilesLink = Δοκιμάστε το Send\nerrorPageHeader = Κάτι πήγε στραβά!\nfileTooBig = Αυτό το αρχείο είναι πολύ μεγάλο για μεταφόρτωση. Πρέπει να είναι μικρότερο από { $size }.\nlinkExpiredAlt = Ο σύνδεσμος έληξε\nnotSupportedHeader = Το πρόγραμμα περιήγησής σας δεν υποστηρίζεται.\nnotSupportedLink = Γιατί δεν υποστηρίζεται το πρόγραμμα περιήγησής μου;\nnotSupportedOutdatedDetail = Δυστυχώς, αυτή η έκδοση του Firefox δεν υποστηρίζει την τεχνολογία ιστού στην οποία βασίζεται το Send. Πρέπει να ενημερώσετε το πρόγραμμα περιήγησής σας.\nupdateFirefox = Ενημέρωση Firefox\ndeletePopupCancel = Ακύρωση\ndeleteButtonHover = Διαγραφή\nfooterLinkLegal = Νομικά\nfooterLinkPrivacy = Απόρρητο\nfooterLinkCookies = Cookies\npasswordTryAgain = Λάθος κωδικός πρόσβασης. Δοκιμάστε ξανά.\njavascriptRequired = Το Send απαιτεί JavaScript\nwhyJavascript = Γιατί το Send απαιτεί JavaScript;\nenableJavascript = Παρακαλώ ενεργοποιήστε το JavaScript και δοκιμάστε ξανά.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }ώ { $minutes }λ\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }λ\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Μέγιστο μήκος κωδικού: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Δεν ήταν δυνατός ο ορισμός αυτού του κωδικού\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Απλή, ιδιωτική κοινή χρήση αρχείων\nintroDescription = Το { -send-brand } σάς επιτρέπει να μοιράζεστε αρχεία με από άκρη σε άκρη κρυπτογράφηση και ένα σύνδεσμο που λήγει αυτόματα. Έτσι, ό,τι μοιράζεστε παραμένει ιδιωτικό και είστε βέβαιοι πως δεν παραμένει στο διαδίκτυο για πάντα.\nnotifyUploadEncryptDone = Το αρχείο σας έχει κρυπτογραφηθεί και είναι έτοιμο για αποστολή\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Λήγει μετά από { $downloadCount } ή { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 λεπτό\n       *[other] { $num } λεπτά\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 ημέρα\n       *[other] { $num } ημέρες\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 εβδομάδα\n       *[other] { $num } εβδομάδες\n    }\nfileCount =\n    { $num ->\n        [one] 1 αρχείο\n       *[other] { $num } αρχεία\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Συνολικό μέγεθος: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Αντιγράψτε το σύνδεσμο για να μοιραστείτε το αρχείο:\ncopyLinkButton = Αντιγραφή συνδέσμου\ndownloadTitle = Λήψη αρχείων\ndownloadDescription = Αυτό το αρχείο διαμοιράστηκε μέσω του { -send-brand } με κρυπτογράφηση από άκρο σε άκρο και με ένα σύνδεσμο που λήγει αυτόματα.\ntrySendDescription = Δοκιμάστε το { -send-brand } για απλό, ασφαλή διαμοιρασμό αρχείων.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Μόνο 1 αρχείο μπορεί να μεταφορτωθεί κάθε φορά.\n       *[other] Μόνο { $count } αρχεία μπορούν να μεταφορτωθούν κάθε φορά.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Μόνο 1 αρχείο επιτρέπεται.\n       *[other] Μόνο { $count } αρχεία επιτρέπονται.\n    }\nexpiredTitle = Αυτός ο σύνδεσμος έχει λήξει.\nnotSupportedDescription = Το { -send-brand } δεν θα λειτουργήσει με αυτό το πρόγραμμα περιήγησης. Το { -send-short-brand } λειτουργεί καλύτερα με την πιο πρόσφατη έκδοση του { -firefox }, καθώς και με την τρέχουσα έκδοση των περισσότερων προγραμμάτων περιήγησης.\ndownloadFirefox = Λήψη του { -firefox }\nlegalTitle = Σημείωση Απορρήτου { -send-short-brand }\nlegalDateStamp = Έκδοση 1.0, από 12 Μαρτίου 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }η { $hours }ώ { $minutes }λ\naddFilesButton = Επιλέξτε αρχεία για μεταφόρτωση\ntrustWarningMessage = Βεβαιωθείτε ότι ο παραλήπτης είναι έμπιστος πριν μοιραστείτε ευαίσθητα δεδομένα.\nuploadButton = Μεταφόρτωση\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Σύρετε και εναποθέστε αρχεία\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = ή κάντε κλικ για να στείλετε μέχρι { $size }\naddPassword = Προστασία με κωδικό πρόσβασης\nemailPlaceholder = Εισάγετε το email σας\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Συνδεθείτε για να στείλετε μέχρι { $size }\nsignInOnlyButton = Σύνδεση\naccountBenefitTitle = Δημιουργία λογαριασμού { -firefox } ή σύνδεση\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Μοιραστείτε αρχεία έως { $size }\naccountBenefitDownloadCount = Μοιραστείτε αρχεία με περισσότερα άτομα\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Να παραμείνουν οι σύνδεσμοι ενεργοί έως και 1 ημέρα\n       *[other] Να παραμείνουν οι σύνδεσμοι ενεργοί έως και { $count } ημέρες\n    }\naccountBenefitSync = Διαχειριστείτε τα διαμοιρασμένα αρχεία από οποιαδήποτε συσκευή\naccountBenefitMoz = Μάθετε για τις άλλες υπηρεσίες της { -mozilla }\nsignOut = Αποσύνδεση\nokButton = OK\ndownloadingTitle = Γίνεται λήψη\nnoStreamsWarning = Αυτό το πρόγραμμα περιήγησης ενδέχεται να μην μπορέσει να αποκρυπτογραφήσει αρχεία αυτού του μεγέθους.\nnoStreamsOptionCopy = Αντιγράψτε το σύνδεσμο για άνοιγμα σε άλλο πρόγραμμα περιήγησης\nnoStreamsOptionFirefox = Δοκιμάστε το αγαπημένο μας πρόγραμμα περιήγησης\nnoStreamsOptionDownload = Συνέχεια με αυτό το πρόγραμμα περιήγησης\ndownloadFirefoxPromo = Το { -send-short-brand } παρέχεται σε εσάς από το ολοκαίνουριο { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Μοιραστείτε το σύνδεσμο του αρχείου σας:\nshareLinkButton = Κοινή χρήση συνδέσμου\n# $name is the name of the file\nshareMessage = Λήψη του “{ $name }” με το { -send-brand }: απλός και ασφαλής διαμοιρασμός αρχείων\ntrailheadPromo = Υπάρχει τρόπος να προστατέψετε το απόρρητό σας. Γίνετε μέλος του Firefox.\nlearnMore = Μάθετε περισσότερα.\ndownloadFlagged = Αυτός ο σύνδεσμος έχει απενεργοποιηθεί λόγω παραβίασης των όρων υπηρεσίας.\ndownloadConfirmTitle = Κάτι ακόμα\ndownloadConfirmDescription = Βεβαιωθείτε ότι το αρχείο προέρχεται από έμπιστο άτομο, καθώς δεν μπορούμε να επαληθεύσουμε ότι δεν θα βλάψει τη συσκευή σας.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Εμπιστεύομαι το άτομο που έστειλε το αρχείο\n       *[other] Εμπιστεύομαι το άτομο που έστειλε τα αρχεία\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Αναφορά ύποπτου αρχείου\n       *[other] Αναφορά ύποπτων αρχείων\n    }\nreportDescription = Βοηθήστε μας να καταλάβουμε τι συμβαίνει. Τι νομίζετε ότι δεν πάει καλά με αυτά τα αρχεία;\nreportUnknownDescription = Παρακαλούμε μεταβείτε στο URL του συνδέσμου που θέλετε να αναφέρετε και κάντε κλικ στο \"{ reportFile }\".\nreportButton = Αναφορά\nreportReasonMalware = Αυτά τα αρχεία περιέχουν κακόβουλο λογισμικό ή αποτελούν μέρος μιας επίθεσης ηλεκτρονικού ψαρέματος.\nreportReasonPii = Αυτά τα αρχεία περιέχουν προσωπικές μου πληροφορίες ταυτοποίησης.\nreportReasonAbuse = Αυτά τα αρχεία περιέχουν παράνομο ή καταχρηστικό περιεχόμενο.\nreportReasonCopyright = Για να αναφέρετε παραβίαση πνευματικών δικαιωμάτων ή εμπορικών σημάτων, χρησιμοποιήστε τη διαδικασία που περιγράφεται σε <a>αυτή τη σελίδα</a>.\nreportedTitle = Έγινε αναφορά των αρχείων\nreportedDescription = Σας ευχαριστούμε. Λάβαμε την αναφορά σας για τα αρχεία.\n"
  },
  {
    "path": "public/locales/en-CA/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importing…\nencryptingFile = Encrypting…\ndecryptingFile = Decrypting…\ndownloadCount =\n    { $num ->\n        [one] 1 download\n       *[other] { $num } downloads\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hour\n       *[other] { $num } hours\n    }\ncopiedUrl = Copied!\nunlockInputPlaceholder = Password\nunlockButtonLabel = Unlock\ndownloadButtonLabel = Download\ndownloadFinish = Download Complete\nfileSizeProgress = ({ $partialSize } of { $totalSize })\nsendYourFilesLink = Try Send\nerrorPageHeader = Something went wrong!\nfileTooBig = That file is too big to upload. It should be less than { $size }.\nlinkExpiredAlt = Link expired\nnotSupportedHeader = Your browser is not supported.\nnotSupportedLink = Why is my browser not supported?\nnotSupportedOutdatedDetail = Unfortunately this version of Firefox does not support the web technology that powers Send. You’ll need to update your browser.\nupdateFirefox = Update Firefox\ndeletePopupCancel = Cancel\ndeleteButtonHover = Delete\nfooterLinkLegal = Legal\nfooterLinkPrivacy = Privacy\nfooterLinkCookies = Cookies\npasswordTryAgain = Incorrect password. Try again.\njavascriptRequired = Send requires JavaScript\nwhyJavascript = Why does Send require JavaScript?\nenableJavascript = Please enable JavaScript and try again.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maximum password length: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = This password could not be set\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Simple, private file sharing\nintroDescription = { -send-brand } lets you share files with end-to-end encryption and a link that automatically expires. So you can keep what you share private and make sure your stuff doesn’t stay online forever.\nnotifyUploadEncryptDone = Your file is encrypted and ready to send\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Expires after { $downloadCount } or { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minute\n       *[other] { $num } minutes\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 day\n       *[other] { $num } days\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 week\n       *[other] { $num } weeks\n    }\nfileCount =\n    { $num ->\n        [one] 1 file\n       *[other] { $num } files\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Total size: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copy the link to share your file:\ncopyLinkButton = Copy link\ndownloadTitle = Download files\ndownloadDescription = This file was shared via { -send-brand } with end-to-end encryption and a link that automatically expires.\ntrySendDescription = Try { -send-brand } for simple, safe file sharing.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Only 1 file can be uploaded at a time.\n       *[other] Only { $count } files can be uploaded at a time.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Only 1 archive is allowed.\n       *[other] Only { $count } archives are allowed.\n    }\nexpiredTitle = This link has expired.\nnotSupportedDescription = { -send-brand } will not work with this browser. { -send-short-brand } works best with the latest version of { -firefox }, and will work with the current version of most browsers.\ndownloadFirefox = Download { -firefox }\nlegalTitle = { -send-short-brand } Privacy Notice\nlegalDateStamp = Version 1.0, dated March 12, 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Select files to upload\ntrustWarningMessage = Make sure you trust your recipient when sharing sensitive data.\nuploadButton = Upload\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Drag and drop files\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = or click to send up to { $size }\naddPassword = Protect with password\nemailPlaceholder = Enter your email\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Sign in to send up to { $size }\nsignInOnlyButton = Sign in\naccountBenefitTitle = Create a { -firefox } Account or sign in\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Share files up to { $size }\naccountBenefitDownloadCount = Share files with more people\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Keep links active for up to 1 day\n       *[other] Keep links active for up to { $count } days\n    }\naccountBenefitSync = Manage shared files from any device\naccountBenefitMoz = Learn about other { -mozilla } services\nsignOut = Sign out\nokButton = OK\ndownloadingTitle = Downloading\nnoStreamsWarning = This browser might not be able to decrypt a file this big.\nnoStreamsOptionCopy = Copy the link to open in another browser\nnoStreamsOptionFirefox = Try our favourite browser\nnoStreamsOptionDownload = Continue with this browser\ndownloadFirefoxPromo = { -send-short-brand } is brought to you by the all-new { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Share the link to your file:\nshareLinkButton = Share link\n# $name is the name of the file\nshareMessage = Download “{ $name }” with { -send-brand }: simple, safe file sharing\ntrailheadPromo = There is a way to protect your privacy. Join Firefox.\nlearnMore = Learn more.\ndownloadFlagged = This link has been disabled for violating the terms of service.\ndownloadConfirmTitle = One more thing\ndownloadConfirmDescription = Make sure you trust the person who sent you this file because we can’t verify that it will not harm your device.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] I trust the person who sent this file\n       *[other] I trust the person who sent these files\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Report this file as suspicious\n       *[other] Report these files as suspicious\n    }\nreportDescription = Help us understand what’s going on. What do you think is wrong with these files?\nreportUnknownDescription = Please go to the URL of the link you wish to report and click “{ reportFile }”.\nreportButton = Report\nreportReasonMalware = These files contain malware or are part of a phishing attack.\nreportReasonPii = These files contain personally identifiable information about me.\nreportReasonAbuse = These files contain illegal or abusive content.\nreportReasonCopyright = To report copyright or trademark infringement, use the process described at <a>this page</a>.\nreportedTitle = Files Reported\nreportedDescription = Thank you. We have received your report on these files.\n"
  },
  {
    "path": "public/locales/en-GB/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importing…\nencryptingFile = Encrypting…\ndecryptingFile = Decrypting…\ndownloadCount =\n    { $num ->\n        [one] 1 download\n       *[other] { $num } downloads\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hour\n       *[other] { $num } hours\n    }\ncopiedUrl = Copied!\nunlockInputPlaceholder = Password\nunlockButtonLabel = Unlock\ndownloadButtonLabel = Download\ndownloadFinish = Download Complete\nfileSizeProgress = ({ $partialSize } of { $totalSize })\nsendYourFilesLink = Try Send\nerrorPageHeader = Something went wrong!\nfileTooBig = That file is too big to upload. It should be less than { $size }.\nlinkExpiredAlt = Link expired\nnotSupportedHeader = Your browser is not supported.\nnotSupportedLink = Why is my browser not supported?\nnotSupportedOutdatedDetail = Unfortunately this version of Firefox does not support the web technology that powers Send. You’ll need to update your browser.\nupdateFirefox = Update Firefox\ndeletePopupCancel = Cancel\ndeleteButtonHover = Delete\nfooterLinkLegal = Legal\nfooterLinkPrivacy = Privacy\nfooterLinkCookies = Cookies\npasswordTryAgain = Incorrect password. Try again.\njavascriptRequired = Send requires JavaScript\nwhyJavascript = Why does Send require JavaScript?\nenableJavascript = Please enable JavaScript and try again.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maximum password length: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = This password could not be set\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Simple, private file sharing\nintroDescription = { -send-brand } lets you share files with end-to-end encryption and a link that automatically expires. So you can keep what you share private and make sure your stuff doesn’t stay online forever.\nnotifyUploadEncryptDone = Your file is encrypted and ready to send\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Expires after { $downloadCount } or { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minute\n       *[other] { $num } minutes\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 day\n       *[other] { $num } days\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 week\n       *[other] { $num } weeks\n    }\nfileCount =\n    { $num ->\n        [one] 1 file\n       *[other] { $num } files\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = kB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Total size: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copy the link to share your file:\ncopyLinkButton = Copy link\ndownloadTitle = Download files\ndownloadDescription = This file was shared via { -send-brand } with end-to-end encryption and a link that automatically expires.\ntrySendDescription = Try { -send-brand } for simple, safe file sharing.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Only 1 file can be uploaded at a time.\n       *[other] Only { $count } files can be uploaded at a time.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Only 1 archive is allowed.\n       *[other] Only { $count } archives are allowed.\n    }\nexpiredTitle = This link has expired.\nnotSupportedDescription = { -send-brand } will not work with this browser. { -send-short-brand } works best with the latest version of { -firefox }, and will work with the current version of most browsers.\ndownloadFirefox = Download { -firefox }\nlegalTitle = { -send-short-brand } Privacy Notice\nlegalDateStamp = Version 1.0, dated March 12, 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Select files to upload\ntrustWarningMessage = Make sure you trust your recipient when sharing sensitive data.\nuploadButton = Upload\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Drag and drop files\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = or click to send up to { $size }\naddPassword = Protect with password\nemailPlaceholder = Enter your email\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Sign in to send up to { $size }\nsignInOnlyButton = Sign in\naccountBenefitTitle = Create a { -firefox } Account or sign in\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Share files up to { $size }\naccountBenefitDownloadCount = Share files with more people\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Keep links active for up to 1 day\n       *[other] Keep links active for up to { $count } days\n    }\naccountBenefitSync = Manage shared files from any device\naccountBenefitMoz = Learn about other { -mozilla } services\nsignOut = Sign out\nokButton = OK\ndownloadingTitle = Downloading\nnoStreamsWarning = This browser might not be able to decrypt a file this big.\nnoStreamsOptionCopy = Copy the link to open in another browser\nnoStreamsOptionFirefox = Try our favourite browser\nnoStreamsOptionDownload = Continue with this browser\ndownloadFirefoxPromo = { -send-short-brand } is brought to you by the all-new { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Share the link to your file:\nshareLinkButton = Share link\n# $name is the name of the file\nshareMessage = Download “{ $name }” with { -send-brand }: simple, safe file sharing\ntrailheadPromo = There is a way to protect your privacy. Join Firefox.\nlearnMore = Learn more.\ndownloadFlagged = This link has been disabled for violating the terms of service.\ndownloadConfirmTitle = One more thing\ndownloadConfirmDescription = Make sure you trust the person who sent you this file because we can’t verify that it will not harm your device.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] I trust the person who sent this file\n       *[other] I trust the person who sent these files\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Report this file as suspicious\n       *[other] Report these files as suspicious\n    }\nreportDescription = Help us understand what’s going on. What do you think is wrong with these files?\nreportUnknownDescription = Please go to the url of the link you wish to report and click “{ reportFile }”.\nreportButton = Report\nreportReasonMalware = These files contain malware or are part of a phishing attack.\nreportReasonPii = These files contain personally identifiable information about me.\nreportReasonAbuse = These files contain illegal or abusive content.\nreportReasonCopyright = To report copyright or trademark infringement, use the process described at <a>this page</a>.\nreportedTitle = Files Reported\nreportedDescription = Thank you. We have received your report on these files.\n"
  },
  {
    "path": "public/locales/en-US/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importing…\nencryptingFile = Encrypting…\ndecryptingFile = Decrypting…\ndownloadCount = { $num ->\n        [one] 1 download\n       *[other] { $num } downloads\n    }\ntimespanHours = { $num ->\n        [one] 1 hour\n       *[other] { $num } hours\n    }\ncopiedUrl = Copied!\nunlockInputPlaceholder = Password\nunlockButtonLabel = Unlock\ndownloadButtonLabel = Download\ndownloadFinish = Download complete\nfileSizeProgress = ({ $partialSize } of { $totalSize })\nsendYourFilesLink = Try Send\nerrorPageHeader = Something went wrong!\nfileTooBig = That file is too big to upload. It should be less than { $size }\nlinkExpiredAlt = Link expired\nnotSupportedHeader = Your browser is not supported.\nnotSupportedLink = Why is my browser not supported?\nnotSupportedOutdatedDetail = Unfortunately this version of Firefox does not support the web technology that powers Send. You’ll need to update your browser.\nupdateFirefox = Update Firefox\ndeletePopupCancel = Cancel\ndeleteButtonHover = Delete\nfooterLinkLegal = Legal\nfooterLinkPrivacy = Privacy\nfooterLinkCookies = Cookies\npasswordTryAgain = Incorrect password. Try again.\njavascriptRequired = Send requires JavaScript\nwhyJavascript = Why does Send require JavaScript?\nenableJavascript = Please enable JavaScript and try again.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maximum password length: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = This password could not be set\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\n\nintroTitle = Simple, private file sharing\nintroDescription = { -send-brand } lets you share files with end-to-end encryption and a link that automatically expires. So you can keep what you share private and make sure your stuff doesn’t stay online forever.\nnotifyUploadEncryptDone = Your file is encrypted and ready to send\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Expires after { $downloadCount } or { $timespan }\ntimespanMinutes = { $num ->\n        [one] 1 minute\n       *[other] { $num } minutes\n    }\ntimespanDays = { $num ->\n        [one] 1 day\n       *[other] { $num } days\n    }\ntimespanWeeks = { $num ->\n        [one] 1 week\n       *[other] { $num } weeks\n    }\nfileCount = { $num ->\n    [one] 1 file\n   *[other] { $num } files\n}\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Total size: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copy the link to share your file:\ncopyLinkButton = Copy link\ndownloadTitle = Download files\ndownloadDescription = This file was shared via { -send-brand } with end-to-end encryption and a link that automatically expires.\ntrySendDescription = Try { -send-brand } for simple, safe file sharing.\n# count will always be > 10\ntooManyFiles = { $count ->\n     [one] Only 1 file can be uploaded at a time.\n    *[other] Only { $count } files can be uploaded at a time.\n}\n# count will always be > 10\ntooManyArchives = { $count ->\n     [one] Only 1 archive is allowed.\n    *[other] Only { $count } archives are allowed.\n}\nexpiredTitle = This link has expired.\nnotSupportedDescription = { -send-brand } will not work with this browser. { -send-short-brand } works best with the latest version of { -firefox }, and will work with the current version of most browsers.\ndownloadFirefox = Download { -firefox }\nlegalTitle = { -send-short-brand } Privacy Notice\nlegalDateStamp = Version 1.0, dated March 12, 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Select files to upload\ntrustWarningMessage = Make sure you trust your recipient when sharing sensitive data.\nuploadButton = Upload\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Drag and drop files\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = or click to send up to { $size }\naddPassword = Protect with password\nemailPlaceholder = Enter your email\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Sign in to send up to { $size }\nsignInOnlyButton = Sign in\naccountBenefitTitle = Create a { -firefox } Account or sign in\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Share files up to { $size }\naccountBenefitDownloadCount = Share files with more people\naccountBenefitTimeLimit = { $count ->\n     [one] Keep links active for up to 1 day\n    *[other] Keep links active for up to { $count } days\n}\naccountBenefitSync = Manage shared files from any device\naccountBenefitMoz = Learn about other { -mozilla } services\nsignOut = Sign out\nokButton = OK\ndownloadingTitle = Downloading\nnoStreamsWarning = This browser might not be able to decrypt a file this big.\nnoStreamsOptionCopy = Copy the link to open in another browser\nnoStreamsOptionFirefox = Try our favorite browser\nnoStreamsOptionDownload = Continue with this browser\ndownloadFirefoxPromo = { -send-short-brand } is brought to you by the all-new { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Share the link to your file:\nshareLinkButton = Share link\n# $name is the name of the file\nshareMessage = Download “{ $name }” with { -send-brand }: simple, safe file sharing\ntrailheadPromo = There is a way to protect your privacy. Join Firefox.\nlearnMore = Learn more.\ndownloadFlagged = This link has been disabled for violating the terms of service.\ndownloadConfirmTitle = One more thing\ndownloadConfirmDescription = Make sure you trust the person who sent you this file because we can’t verify that it will not harm your device.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] I trust the person who sent this file\n       *[other] I trust the person who sent these files\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Report this file as suspicious\n       *[other] Report these files as suspicious\n    }\nreportDescription = Help us understand what’s going on. What do you think is wrong with these files?\nreportUnknownDescription = Please go to the url of the link you wish to report and click “{ reportFile }”.\nreportButton = Report\nreportReasonMalware = These files contain malware or are part of a phishing attack.\nreportReasonPii = These files contain personally identifiable information about me.\nreportReasonAbuse = These files contain illegal or abusive content.\nreportReasonCopyright = To report copyright or trademark infringement, use the process described at <a>this page</a>.\nreportedTitle = Files Reported\nreportedDescription = Thank you. We have received your report on these files.\n"
  },
  {
    "path": "public/locales/es-AR/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importando…\nencryptingFile = Cifrando…\ndecryptingFile = Descifrando…\ndownloadCount =\n    { $num ->\n        [one] 1 descarga\n       *[other] { $num } descargas\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hora\n       *[other] { $num } horas\n    }\ncopiedUrl = ¡Copiado!\nunlockInputPlaceholder = Contraseña\nunlockButtonLabel = Desbloquear\ndownloadButtonLabel = Descargar\ndownloadFinish = Descarga completa\nfileSizeProgress = ({ $partialSize } de { $totalSize })\nsendYourFilesLink = Probá Send\nerrorPageHeader = ¡Algo falló!\nfileTooBig = El archivo es demasiado grande para subir. Debería tener menos de { $size }.\nlinkExpiredAlt = Enlace explirado\nnotSupportedHeader = El navegador no está soportado.\nnotSupportedLink = ¿Por qué mi navegador no está soportado?\nnotSupportedOutdatedDetail = Desafortunadamente esta versión de Firefox no soporta la tecnología web que necesita Send. Necesitás actualizar el navegador.\nupdateFirefox = Actualizar Firefox\ndeletePopupCancel = Cancelar\ndeleteButtonHover = Borrar\nfooterLinkLegal = Legales\nfooterLinkPrivacy = Privacidad\nfooterLinkCookies = Cookies\npasswordTryAgain = Contraseña incorrecta. Intentá nuevamente.\njavascriptRequired = Send requiere JavaScript\nwhyJavascript = ¿Por qué Send requiere Java Script?\nenableJavascript = Por favor habilite JavaScript y pruebe de nuevo.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = h { $hours } m { $minutes }\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = m { $minutes }\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Longitud máxima de la contraseña: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = No se pudo establecer la contraseña\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Intercambio de archivos sencillo y privado\nintroDescription = { -send-brand } le permite compartir archivos con cifrado de extremo a extremo y un enlace que caduca automáticamente. Así puede mantener privado lo que comparte y asegurarse de que sus cosas no permanezcan en línea para siempre.\nnotifyUploadEncryptDone = Su archivo está cifrado y listo para enviar\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Vence después de { $downloadCount } o { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuto\n       *[other] { $num } minutos\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 día\n       *[other] { $num } días\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 semana\n       *[other] { $num } semanas\n    }\nfileCount =\n    { $num ->\n        [one] 1 file\n       *[other] { $num } archivos\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Tamaño total: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copiar el enlace para compartir su archivo:\ncopyLinkButton = Copiar enlace\ndownloadTitle = Descargar archivos\ndownloadDescription = Este archivo se compartió a través de { -send-brand } con cifrado de extremo a extremo y un enlace que caduca automáticamente.\ntrySendDescription = Pruebe { -send-brand } para compartir archivos de forma sencilla y segura.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Solo se puede subir 1 archivo a la vez.\n       *[other] Solo se pueden subir archivos { $count } a la vez.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Solo se permite 1 archivo.\n       *[other] Solo se permiten { $count } archivos.\n    }\nexpiredTitle = Este enlace caducó.\nnotSupportedDescription = { -send-brand } no funcionará con este navegador. { -send-short-brand } funciona mejor con la última versión de { -firefox }, y funcionará con la versión actual de la mayoría de los navegadores.\ndownloadFirefox = Descargue { -firefox }\nlegalTitle = Aviso de privacidad de { -send-short-brand }\nlegalDateStamp = Versión 1.0, con fecha 12 de marzo de 2019.\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Seleccionar archivos para subir\ntrustWarningMessage = Asegurate de que confiás en tu destinatario cuando compartís datos confidenciales.\nuploadButton = Subir\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Arrastrar y soltar archivos\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = o haga clic para enviar hasta { $size }\naddPassword = Proteger con contraseña\nemailPlaceholder = Ingrese su correo electrónico\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Inicie sesión para enviar hasta { $size }\nsignInOnlyButton = Iniciar sesión\naccountBenefitTitle = Cree una cuenta de { -firefox } o inicie la sesión\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Compartir archivos hasta { $size }\naccountBenefitDownloadCount = Compartir archivos con más personas\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Mantenga los enlaces activos hasta por 1 día\n       *[other] Mantenga los enlaces activos hasta por { $count } días\n    }\naccountBenefitSync = Administre archivos compartidos desde cualquier dispositivo.\naccountBenefitMoz = Conocer sobre otros servicios de { -mozilla }\nsignOut = Salir\nokButton = Aceptar\ndownloadingTitle = Descargando\nnoStreamsWarning = Es posible que este navegador no pueda descifrar un archivo tan grande.\nnoStreamsOptionCopy = Copiar el enlace para abrir en otro navegador.\nnoStreamsOptionFirefox = Pruebe nuestro navegador favorito\nnoStreamsOptionDownload = Continuar con este navegador\ndownloadFirefoxPromo = El nuevo { -firefox } te ofrece { -send-short-brand }.\n# the next line after the colon contains a file name\nshareLinkDescription = Compartir el enlace con tu dispositivo:\nshareLinkButton = Compartir el enlace\n# $name is the name of the file\nshareMessage = Descargar \"{ $name }\" con { -send-brand }: compartir archivos de forma simple y segura\ntrailheadPromo = Hay una forma de proteger tu privacidad. Unite a Firefox.\nlearnMore = Conocer más.\ndownloadFlagged = Este enlace fue deshabilitado por violar los términos del servicio.\ndownloadConfirmTitle = Una cosa más\ndownloadConfirmDescription = Asegurate de confiar en la persona que te envió este archivo porque no podemos verificar que no va a dañar tu dispositivo.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Confío en la persona que envió este archivo\n       *[other] Confío en la persona que envió estos archivos\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Denunciar este archivo como sospechoso\n       *[other] Denunciar estos archivos como sospechosos\n    }\nreportDescription = Ayudanos a entender lo que está pasando. ¿Qué creés que está mal con estos archivos?\nreportUnknownDescription = Navegá a la url del enlace que querés denunciar y hacé clic en \"{ reportFile }\".\nreportButton = Denunciar\nreportReasonMalware = Estos archivos contienen programas dañinos o son parte de un fraude electrónico.\nreportReasonPii = Estos archivos contienen información personal que me puede identificar.\nreportReasonAbuse = Estos archivos contienen contenido ilegal o abusivo.\nreportReasonCopyright = Para denunciar una infracción de derechos de autor o de marca registrada, seguí el proceso descrito en <a>esta página</a>.\nreportedTitle = Archivos denunciados\nreportedDescription = Gracias. Recibimos tu denuncia sobre estos archivos.\n"
  },
  {
    "path": "public/locales/es-CL/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importando…\nencryptingFile = Cifrando…\ndecryptingFile = Descifrando…\ndownloadCount =\n    { $num ->\n        [one] 1 descarga\n       *[other] { $num } descargas\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hora\n       *[other] { $num } horas\n    }\ncopiedUrl = ¡Copiado!\nunlockInputPlaceholder = Contraseña\nunlockButtonLabel = Desbloquear\ndownloadButtonLabel = Descargar\ndownloadFinish = Descarga completa\nfileSizeProgress = ({ $partialSize } de { $totalSize })\nsendYourFilesLink = Probar Send\nerrorPageHeader = ¡Algo se fue a las pailas!\nfileTooBig = Ese archivo es muy grande para ser subido. Debiera tener un tamaño menor a { $size }.\nlinkExpiredAlt = Enlace expirado\nnotSupportedHeader = Tu navegador no está soportado.\nnotSupportedLink = ¿Por qué mi navegador no es soportado?\nnotSupportedOutdatedDetail = Lamentablemente esta versión de Firefox no soporta la tecnología web que potencia a Send. Deberás actualizar tu navegador.\nupdateFirefox = Actualizar Firefox\ndeletePopupCancel = Cancelar\ndeleteButtonHover = Eliminar\nfooterLinkLegal = Legal\nfooterLinkPrivacy = Privacidad\nfooterLinkCookies = Cookies\npasswordTryAgain = Contraseña incorrecta. Vuelve a intentarlo.\njavascriptRequired = Send requiere JavaScript.\nwhyJavascript = ¿Por qué Send requiere JavaScript?\nenableJavascript = Por favor, activa JavaScript y vuelve a intentarlo.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Longitud máxima de la contraseña: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Esta contraseña no pudo ser establecida\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Intercambio de archivos simple y privado\nintroDescription = { -send-brand } te permite compartir archivos con cifrado de extremo a extremo y un enlace que expira automáticamente. Así puedes mantener lo que compartes en privado y asegurarte de que tus cosas no permanezcan en línea para siempre.\nnotifyUploadEncryptDone = Tu archivo está cifrado y listo para enviar\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Expira después de { $downloadCount } o { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuto\n       *[other] { $num } minutos\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 día\n       *[other] { $num } días\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 semana\n       *[other] { $num } semanas\n    }\nfileCount =\n    { $num ->\n        [one] 1 archivo\n       *[other] { $num } archivos\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Tamaño total: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copiar el enlace para compartir el archivo:\ncopyLinkButton = Copiar enlace\ndownloadTitle = Bajando archivos\ndownloadDescription = Este archivo fue compartido a través de { -send-brand } con cifrado de punto a punto y un enlace que expira automáticamente.\ntrySendDescription = Prueba { -send-brand } para compartir archivos de forma simple y segura.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Solo 1 archivo puede ser subido a la vez.\n       *[other] Solo { $count } archivos pueden ser subidos a la vez.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Solo 1 archivo está permitido.\n       *[other] Solo { $count } archivos están permitidos.\n    }\nexpiredTitle = Este enlace ha expirado.\nnotSupportedDescription = { -send-brand } no funcionará con este navegador. { -send-short-brand } funciona mejor con la última versión de { -firefox } y con la versión actual de la mayoría de los navegadores.\ndownloadFirefox = Bajar { -firefox }\nlegalTitle = Aviso de privacidad de { -send-short-brand }\nlegalDateStamp = Versión 1.0 del 12 de marzo de 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Selecciona los archivos a subir\ntrustWarningMessage = Asegúrate de que confías en tu destinatario cuando compartas datos sensibles.\nuploadButton = Subir\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Arrastra y suelta archivos\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = o haz clic para enviar hasta { $size }\naddPassword = Protegido con contraseña\nemailPlaceholder = Ingresa tu correo\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Conéctate para enviar hasta { $size }\nsignInOnlyButton = Conectarse\naccountBenefitTitle = Crea una cuenta de { -firefox } o conéctate\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Comparte archivos de hasta { $size }\naccountBenefitDownloadCount = Comparte archivos con más personas\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Mantener enlaces activos durante 1 día\n       *[other] Mantener enlaces activos durante { $count } días\n    }\naccountBenefitSync = Administrar los archivos compartidos desde cualquier dispositivo\naccountBenefitMoz = Aprender más acerca de otros servicios de { -mozilla }\nsignOut = Salir\nokButton = Aceptar\ndownloadingTitle = Bajando\nnoStreamsWarning = Es posible que este navegador no pueda descifrar un archivo tan grande.\nnoStreamsOptionCopy = Copiar el enlace para abrirlo en otro navegador\nnoStreamsOptionFirefox = Prueba nuestro navegador favorito\nnoStreamsOptionDownload = Continuar con este navegador\ndownloadFirefoxPromo = { -send-short-brand } es traído a ti por el renovado { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Comparte el enlace a tu dispositivo:\nshareLinkButton = Compartir enlace\n# $name is the name of the file\nshareMessage = Baja \"{ $name }\" con { -send-brand }: compartir archivos de forma simple y segura\ntrailheadPromo = Hay una forma de proteger tu privacidad. Únete a Firefox.\nlearnMore = Aprender más.\ndownloadFlagged = Este enlace ha sido deshabilitado por violar los términos del servicio.\ndownloadConfirmTitle = Una cosa más\ndownloadConfirmDescription = Asegúrate de confiar en la persona que te envió este archivo porque no podemos verificar que no dañará tu dispositivo.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Confío en la persona que envió es archivo\n       *[other] Confío en la persona que envió estos archivos\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Reportar este archivo como sospechoso\n       *[other] Reportar estos archivos como sospechosos\n    }\nreportDescription = Ayúdanos a entender lo que está pasando. ¿Qué crees que está mal con estos archivos?\nreportUnknownDescription = Por favor, ve a la url del enlace que quieres reportar y haz clic en \"{ reportFile }\".\nreportButton = Reportar\nreportReasonMalware = Estos archivos contienen malware o son parte de un ataque de phishing.\nreportReasonPii = Estos archivos contienen información personal identificable sobre mí.\nreportReasonAbuse = Estos archivos contienen contenido ilegal o abusivo.\nreportReasonCopyright = Para denunciar una infracción de derechos de autor o de marca registrada, sigue el proceso descrito en <a>esta página</a>.\nreportedTitle = Archivos reportados\nreportedDescription = Gracias. Hemos recibido tu reporte sobre estos archivos.\n"
  },
  {
    "path": "public/locales/es-ES/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importando...\nencryptingFile = Cifrando...\ndecryptingFile = Descifrando...\ndownloadCount =\n    { $num ->\n        [one] 1 descarga\n       *[other] { $num } descargas\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hora\n       *[other] { $num } horas\n    }\ncopiedUrl = ¡Copiado!\nunlockInputPlaceholder = Contraseña\nunlockButtonLabel = Desbloquear\ndownloadButtonLabel = Descargar\ndownloadFinish = Descarga completa\nfileSizeProgress = ({ $partialSize } de { $totalSize })\nsendYourFilesLink = Prueba Send\nerrorPageHeader = ¡Se ha producido un error!\nfileTooBig = Ese archivo es muy grande. Debería ocupar menos de { $size }.\nlinkExpiredAlt = Enlace caducado\nnotSupportedHeader = Tu navegador no es compatible.\nnotSupportedLink = ¿Por qué mi navegador no es compatible?\nnotSupportedOutdatedDetail = Lamentablemente, esta versión de Firefox no admite la tecnología web que impulsa Send. Tendrás que actualizar tu navegador.\nupdateFirefox = Actualizar Firefox\ndeletePopupCancel = Cancelar\ndeleteButtonHover = Eliminar\nfooterLinkLegal = Legal\nfooterLinkPrivacy = Privacidad\nfooterLinkCookies = Cookies\npasswordTryAgain = Contraseña incorrecta. Inténtalo de nuevo.\njavascriptRequired = Send requiere JavaScript\nwhyJavascript = ¿Por qué Send requiere JavaScript?\nenableJavascript = Por favor, activa JavaScript y vuelve a intentarlo.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Longitud máxima de la contraseña: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = No se ha podido establecer la contraseña\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Enviar\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Compartir archivos de forma sencilla y privada\nintroDescription = { -send-brand } te permite compartir archivos con cifrado de extremo a extremo y un enlace que caduca automáticamente. Así que puedes mantener lo que compartes en privado y asegurarte de que tus cosas no permanezcan en línea para siempre.\nnotifyUploadEncryptDone = El archivo está cifrado y listo para enviar\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Caduca tras { $downloadCount } o { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuto\n       *[other] { $num } minutos\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 día\n       *[other] { $num } días\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 semana\n       *[other] { $num } semanas\n    }\nfileCount =\n    { $num ->\n        [one] 1 archivo\n       *[other] { $num } archivos\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Tamaño total: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copiar el enlace para compartir el archivo:\ncopyLinkButton = Copiar enlace\ndownloadTitle = Descargar archivos\ndownloadDescription = Este archivo se compartió a través de { -send-brand } con cifrado de extremo a extremo y un enlace que caduca automáticamente.\ntrySendDescription = Prueba { -send-brand } para compartir archivos de forma sencilla y segura.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Solo se puede subir 1 archivo a la vez.\n       *[other] Solo se pueden subir { $count } archivos a la vez.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Solo se permite 1 archivo.\n       *[other] Solo se permiten { $count } archivos.\n    }\nexpiredTitle = Este enlace ha expirado.\nnotSupportedDescription = { -send-brand } no funciona con este navegador. { -send-short-brand } funciona mejor con la última versión de { -firefox }, y funciona con la última versión de la mayoría de los navegadores.\ndownloadFirefox = Descargar { -firefox }\nlegalTitle = Aviso de privacidad de { -send-short-brand }\nlegalDateStamp = Versión 1.0 del 12 de marzo de 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Seleccionar archivos para subir\ntrustWarningMessage = Asegúrate de que confías en tu destinatario cuando compartas datos sensibles.\nuploadButton = Subir\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Arrastrar y soltar archivos\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = o hacer clic para enviar hasta { $size }\naddPassword = Proteger con contraseña\nemailPlaceholder = Introducir dirección de correo\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Iniciar sesión para enviar hasta { $size }\nsignInOnlyButton = Iniciar sesión\naccountBenefitTitle = Crear una cuenta { -firefox } o iniciar sesión\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Compartir archivos de hasta { $size }\naccountBenefitDownloadCount = Compartir archivos con más gente\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Mantener enlaces activos durante 1 día\n       *[other] Mantener enlaces activos durante { $count } días\n    }\naccountBenefitSync = Administrar los archivos compartidos desde cualquier dispositivo\naccountBenefitMoz = Saber más sobre otros servicios de { -mozilla }\nsignOut = Cerrar sesión\nokButton = Vale\ndownloadingTitle = Descargando\nnoStreamsWarning = Puede que este navegador no pueda descifrar un archivo tan grande.\nnoStreamsOptionCopy = Copiar el enlace para abrirlo en otro navegador\nnoStreamsOptionFirefox = Probar nuestro navegador favorito\nnoStreamsOptionDownload = Continuar en este navegador\ndownloadFirefoxPromo = El nuevo { -firefox } te ofrece { -send-short-brand }.\n# the next line after the colon contains a file name\nshareLinkDescription = Compartir el enlace a tu archivo:\nshareLinkButton = Compartir enlace\n# $name is the name of the file\nshareMessage = Descargar “{ $name }” con { -send-brand }: comparte archivos de forma segura y sencilla\ntrailheadPromo = Existe la forma de proteger tu privacidad. Únete a Firefox.\nlearnMore = Saber más.\ndownloadFlagged = Este enlace ha sido desactivado por violar los términos del servicio.\ndownloadConfirmTitle = Una cosa más\ndownloadConfirmDescription = Asegúrate de confiar en la persona que te envió este archivo porque no podemos verificar que no va a dañar tu dispositivo.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Confío en la persona que envió este archivo\n       *[other] Confío en la persona que envió estos archivos\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Denunciar este archivo como sospechoso\n       *[other] Denunciar estos archivos como sospechosos\n    }\nreportDescription = Ayúdanos a entender lo que está pasando. ¿Qué crees que está mal con estos archivos?\nreportUnknownDescription = Por favor, ve a la url del enlace que quieres denunciar y haz clic en “{ reportFile }”.\nreportButton = Denunciar\nreportReasonMalware = Estos archivos contienen malware o son parte de un ataque de phishing.\nreportReasonPii = Estos archivos contienen información personal identificable sobre mí.\nreportReasonAbuse = Estos archivos tienen contenido ilegal o abusivo.\nreportReasonCopyright = Para denunciar una infracción de derechos de autor o marca registrada, sigue el proceso descrito en <a>esta página</a>.\nreportedTitle = Archivos denunciados\nreportedDescription = Gracias. Hemos recibido tu denuncia sobre estos archivos.\n"
  },
  {
    "path": "public/locales/es-MX/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Comentario\nimportingFile = Importando...\nencryptingFile = Encriptando…\ndecryptingFile = Desencriptando…\ndownloadCount =\n    { $num ->\n        [one] 1 descarga\n       *[other] { $num } descargas\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hora\n       *[other] { $num } horas\n    }\ncopiedUrl = ¡Copiado!\nunlockInputPlaceholder = Contraseña\nunlockButtonLabel = Desbloquear\ndownloadButtonLabel = Descargar\ndownloadFinish = Descarga completa\nfileSizeProgress = ({ $partialSize } de { $totalSize })\nsendYourFilesLink = Prueba Send\nerrorPageHeader = ¡Algo salió mal!\nfileTooBig = Ese archivo es muy grande. Debería ocupar menos de { $size }.\nlinkExpiredAlt = Enlace caducado\nnotSupportedHeader = Tu navegador no está soportado.\nnotSupportedLink = ¿Por qué mi navegador no tiene soporte?\nnotSupportedOutdatedDetail = Lamentablemente esta versión de Firefox no soporta la tecnología web que potencia a Send. Deberás actualizar tu navegador.\nupdateFirefox = Actualizar Firefox\ndeletePopupCancel = Cancelar\ndeleteButtonHover = Eliminar\nfooterLinkLegal = Legal\nfooterLinkPrivacy = Privacidad\nfooterLinkCookies = Cookies\npasswordTryAgain = Contraseña incorrecta. Intenta de nuevo.\njavascriptRequired = Send requiere JavaScript\nwhyJavascript = ¿Por qué Send requiere JavaScript?\nenableJavascript = Por favor, habilita JavaScript e intenta de nuevo.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Longitud máxima de la contraseña: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = No se ha podido establecer la contraseña\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Enviar\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Compartir archivos fácil y privado\nintroDescription = { -send-brand } te permite compartir archivos con cifrado de extremo a extremo y un enlace que caduca automáticamente. Así puedes mantener en privado lo que compartes y asegurarte de que tus cosas no permanezcan en línea para siempre.\nnotifyUploadEncryptDone = Tu archivo está cifrado y listo para enviar\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Expira después de { $downloadCount } o { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuto\n       *[other] { $num } minutos\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 día\n       *[other] { $num } días\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 semana\n       *[other] { $num } semanas\n    }\nfileCount =\n    { $num ->\n        [one] 1 archivo\n       *[other] { $num } archivos\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Tamaño total: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copiar el enlace para compartir el archivo:\ncopyLinkButton = Copiar enlace\ndownloadTitle = Descargar archivos\ndownloadDescription = Este archivo fue compartido vía { -send-brand } con un cifrado de punto a punto y un enlace que expira automáticamente.\ntrySendDescription = Intenta con { -send-brand } para compartir fácil y seguro.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Solo 1 archivo puede ser cargado a la vez.\n       *[other] Solo { $count } archivos pueden ser cargados a la vez.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Solo 1 archivo está permitido.\n       *[other] Solo { $count } archivos están permitidos.\n    }\nexpiredTitle = Este enlace ha expirado.\nnotSupportedDescription = { -send-brand } no funcionará con este navegador. { -send-short-brand } trabaja mejor que la última versión de { -firefox }, y trabajará con la versión actual de la mayoría de la navegadores.\ndownloadFirefox = Descargar { -firefox }\nlegalTitle = Aviso de privacidad de { -send-short-brand }\nlegalDateStamp = Versión 1.0 del 12 de marzo de 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Seleccionar archivos para subir\nuploadButton = Subir\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Arrastrar y soltar archivos\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = o hacer clic para enviar hasta { $size }\naddPassword = Protegido con contraseña\nemailPlaceholder = Ingresa tu correo electrónico\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Iniciar sesión para enviar hasta { $size }\nsignInOnlyButton = Iniciar sesión\naccountBenefitTitle = Crear una cuenta de { -firefox } o iniciar sesión\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Compartir archivos de hasta { $size }\naccountBenefitDownloadCount = Compartir archivos con más personas\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Mantener enlaces activos por 1 día\n       *[other] Mantener enlaces activos hasta { $count } días\n    }\naccountBenefitSync = Administrar archivos compartidos desde cualquier dispositivo\naccountBenefitMoz = Saber más sobre otros servicios de { -mozilla }\nsignOut = Cerrar sesión\nokButton = Aceptar\ndownloadingTitle = Descargando\nnoStreamsWarning = Puede que este navegador no pueda descifrar un archivo tan grande.\nnoStreamsOptionCopy = Copiar el enlace para abrir en otro navegador\nnoStreamsOptionFirefox = Prueba nuestro navegador favorito\nnoStreamsOptionDownload = Continuar con este navegador\ndownloadFirefoxPromo = { -send-short-brand } te lo ofrece el nuevo { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Comparte el enlace a tu archivo:\nshareLinkButton = Enlace para compartir\n# $name is the name of the file\nshareMessage = Descarga «{ $name }» con { -send-brand }: es sencillo y seguro\ntrailheadPromo = Existe una forma de proteger tu privacidad. Únete a Firefox.\nlearnMore = Saber más.\n"
  },
  {
    "path": "public/locales/et/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Tagasiside\nimportingFile = Importimine...\nencryptingFile = Krüptimine…\ndecryptingFile = Dekrüptimine...\ndownloadCount =\n    { $num ->\n        [one] üht allalaadimist\n       *[other] { $num } allalaadimist\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 tunni\n       *[other] { $num } tunni\n    }\ncopiedUrl = Kopeeritud!\nunlockInputPlaceholder = Parool\nunlockButtonLabel = Ava\ndownloadButtonLabel = Laadi alla\ndownloadFinish = Allalaadimine lõpetati\nfileSizeProgress = ({ $partialSize }/{ $totalSize })\nsendYourFilesLink = Proovi Send'i\nerrorPageHeader = Midagi läks valesti!\nfileTooBig = Fail on üleslaadimiseks liiga suur. See peaks olema väiksem kui { $size }.\nlinkExpiredAlt = Link on aegunud\nnotSupportedHeader = Sinu brauser pole toetatud.\nnotSupportedLink = Miks mu brauser toetatud pole?\nnotSupportedOutdatedDetail = Kahjuks ei toeta see Firefoxi versioon veebitehnoloogiaid, mis teevad Sendi toimimise võimalikuks. Sa pead oma brauserit uuendama.\nupdateFirefox = Uuenda Firefox\ndeletePopupCancel = Loobu\ndeleteButtonHover = Kustuta\nfooterLinkLegal = Õiguslik teave\nfooterLinkPrivacy = Privaatsusest\nfooterLinkCookies = Küpsistest\npasswordTryAgain = Vale parool. Palun proovi uuesti.\njavascriptRequired = Send'i kasutamiseks tuleb JavaScript lubada\nwhyJavascript = Miks Send JavaScripti vajab?\nenableJavascript = Palun luba JavaScript ja proovi uuesti.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }t { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maksimaalne parooli pikkus: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Parooli muutmine ebaõnnestus\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Lihtne ja privaatne failijagamine\nintroDescription = { -send-brand } võimaldab sul faile jagada otspunktkrüpteerimise ning automaatselt aeguva lingiga. Nii saad jagatava privaatsena hoida ja kindlustada, et su asjad igavesti internetti vedelema ei jää.\nnotifyUploadEncryptDone = Sinu fail on krüptitud ja saatmiseks valmis\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Aegub peale { $downloadCount } või { $timespan } järel\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuti\n       *[other] { $num } minuti\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 päeva\n       *[other] { $num } päeva\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 nädala\n       *[other] { $num } nädala\n    }\nfileCount =\n    { $num ->\n        [one] 1 fail\n       *[other] { $num } faili\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = kB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Kogusuurus: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Faili jagamiseks kopeeri link:\ncopyLinkButton = Kopeeri link\ndownloadTitle = Failide allalaadimine\ndownloadDescription = See fail jagati teenuse { -send-brand } kaudu otspunktkrüpteeritult ja automaatselt aeguva lingiga.\ntrySendDescription = Proovi lihtsaks ja turvaliseks failijagamiseks { -send-brand } teenust.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Korraga saab üles laadida vaid 1 faili.\n       *[other] Korraga saab üles laadida vaid { $count } faili.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Vaid 1 arhiveerimine on lubatud.\n       *[other] Vaid { $count } arhiveerimist on lubatud.\n    }\nexpiredTitle = Link on aegunud.\nnotSupportedDescription = { -send-brand } ei tööta selle veebilehitsejaga. Kõige paremini töötab { -send-short-brand } uusima { -firefox }iga ja töötab ka enamikes teistes uuendatud brauserites.\ndownloadFirefox = Laadi { -firefox } alla\nlegalTitle = { -send-short-brand } privaatsusteade\nlegalDateStamp = Versioon 1.0, alates 12. märts 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }p { $hours }t { $minutes }m\naddFilesButton = Vali failid üleslaadimiseks\nuploadButton = Laadi üles\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Lohista failid siia\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = või klõpsa kuni { $size } suuruste failide saatmiseks\naddPassword = Kaitse parooliga\nemailPlaceholder = Sisesta e-posti aadress\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Logi sisse ning saad saata kuni { $size } suuruseid faile\nsignInOnlyButton = Logi sisse\naccountBenefitTitle = Loo { -firefox }i konto või logi sisse\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Jaga kuni { $size } suuruseid faile\naccountBenefitDownloadCount = Jaga faile enamate inimestega\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Hoia linke aktiivsena 1 päev\n       *[other] Hoia linke aktiivsena kuni { $count } päeva\n    }\naccountBenefitSync = Jagatud faile saad hallata mis tahes seadmes\naccountBenefitMoz = Rohkem teavet teistest { -mozilla } teenustest\nsignOut = Logi välja\nokButton = Olgu\ndownloadingTitle = Allalaadimine\nnoStreamsWarning = Sinu veebilehitseja ei pruugi suuta nii suurt faili dekrüptida.\nnoStreamsOptionCopy = Kopeeri link teises brauseris avamiseks\nnoStreamsOptionFirefox = Proovi meie lemmikbrauserit\nnoStreamsOptionDownload = Jätka selle brauseriga\ndownloadFirefoxPromo = { -send-short-brand } toob sinuni uhiuus { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Jaga linki failile:\nshareLinkButton = Jaga linki\n# $name is the name of the file\nshareMessage = Laadi “{ $name }” alla teenusega { -send-brand }, mis pakub lihtsat ja turvalist failijagamist\ntrailheadPromo = Oma privaatsust on võimalik kaitsta. Liitu Firefoxiga.\nlearnMore = Rohkem teavet.\n"
  },
  {
    "path": "public/locales/eu/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Iritzia\nimportingFile = Inportatzen…\nencryptingFile = Zifratzen...\ndecryptingFile = Deszifratzen...\ndownloadCount =\n    { $num ->\n        [one] Deskarga bat\n       *[other] { $num } deskarga\n    }\ntimespanHours =\n    { $num ->\n        [one] Ordubete\n       *[other] { $num } ordu\n    }\ncopiedUrl = Kopiatuta!\nunlockInputPlaceholder = Pasahitza\nunlockButtonLabel = Desblokeatu\ndownloadButtonLabel = Deskargatu\ndownloadFinish = Deskarga burututa\nfileSizeProgress = ({ $totalSize } / { $partialSize })\nsendYourFilesLink = Probatu Send\nerrorPageHeader = Zerbait gaizki joan da!\nfileTooBig = Fitxategia handiegia da kargatzeko. { $size } baino txikiagoa izan behar du.\nlinkExpiredAlt = Lotura iraungi da\nnotSupportedHeader = Zure nabigatzailea ez da onartzen.\nnotSupportedLink = Zergatik ez da nire nabigatzailea onartzen?\nnotSupportedOutdatedDetail = Zoritxarrez Firefox bertsio honek ez du Send-ek behar duen web teknologia onartzen. Zure nabigatzailea eguneratu behar duzu.\nupdateFirefox = Eguneratu Firefox\ndeletePopupCancel = Utzi\ndeleteButtonHover = Ezabatu\nfooterLinkLegal = Lege-oharra\nfooterLinkPrivacy = Pribatutasuna\nfooterLinkCookies = Cookieak\npasswordTryAgain = Pasahitz okerra. Saiatu berriro.\njavascriptRequired = JavaScript beharrezkoa da Send erabiltzeko.\nwhyJavascript = Zergatik behar du Send-ek JavasScript?\nenableJavascript = Gaitu JavaScript eta saiatu berriro.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Pasahitzaren gehienezko luzera: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Pasahitz hau ezin da ezarri\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Partekatu fitxategiak modu sinple eta pribatuan\nintroDescription = { -send-brand } tresna fitxategiak partekatzeko da, muturretik muturrera zifratuta eta automatikoki iraungitzen diren loturekin. Hortaz, partekatzen duzuna pribatua izango da eta ziur egon zaitezke zure fitxategiak ez direla online egongo betirako.\nnotifyUploadEncryptDone = Zure fitxategia zifratuta eta bidaltzeko prest dago\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = { $downloadCount } edo { $timespan } ondoren iraungiko da\ntimespanMinutes =\n    { $num ->\n        [one] minutu 1\n       *[other] { $num } minutu\n    }\ntimespanDays =\n    { $num ->\n        [one] egun 1\n       *[other] { $num } egun\n    }\ntimespanWeeks =\n    { $num ->\n        [one] aste 1\n       *[other] { $num } aste\n    }\nfileCount =\n    { $num ->\n        [one] fitxategi 1\n       *[other] { $num } fitxategi\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Tamaina guztira: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopiatu fitxategia partekatzeko lotura:\ncopyLinkButton = Kopiatu lotura\ndownloadTitle = Deskargatu fitxategiak\ndownloadDescription = { -send-brand } bidez partekatu da fitxategia muturretik muturrera zifratuta eta automatikoki iraungitzen den lotura batekin.\ntrySendDescription = Probatu { -send-brand } fitxategiak partekatzeko modu sinple eta segururako.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Soilik fitxategi bakarra igo daiteke aldi berean.\n       *[other] Soilik { $count } fitxategi igo daitezke aldi berean.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Soilik artxibo bakarra onartzen da.\n       *[other] Soilik { $count } artxibo onartzen dira.\n    }\nexpiredTitle = Lotura hau iraungi da.\nnotSupportedDescription = { -send-brand } ez da nabigatzaile honetan ibiliko. { -send-short-brand } hobeto dabil { -firefox }(r)en azken bertsioarekin; halaber, nabigatzaile gehienen azken bertsioarekin ibiliko da.\ndownloadFirefox = Deskargatu { -firefox }\nlegalTitle = { -send-short-brand } pribatutasun-oharra\nlegalDateStamp = 1.0 bertsioa, 2019ko martxoaren 12koa.\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }e { $hours }h { $minutes }m\naddFilesButton = Hautatu igotzeko fitxategiak\nuploadButton = Igo\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Arrastatu eta jaregin fitxategiak\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = edo egin klik { $size } arte igotzeko\naddPassword = Babestu pasahitzarekin\nemailPlaceholder = Idatzi zure helbide elektronikoa\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Hasi saioa { $size } arte bidaltzeko\nsignInOnlyButton = Hasi saioa\naccountBenefitTitle = Sortu { -firefox } kontu bat edo hasi saioa\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Partekatu { $size } arteko fitxategiak\naccountBenefitDownloadCount = Partekatu fitxategiak jende gehiagorekin\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Utzi loturak erabilgarri egun batez\n       *[other] Utzi loturak erabilgarri { $count } egunez\n    }\naccountBenefitSync = Kudeatu partekatutako fitxategiak edozein gailutatik\naccountBenefitMoz = { -mozilla }ren beste zerbitzuei buruzko argibide gehiago\nsignOut = Amaitu saioa\nokButton = Ados\ndownloadingTitle = Deskargatzen\nnoStreamsWarning = Baliteke nabigatzailea gai ez izatea horrelako tamaina handiko fitxategiak deszifratzeko.\nnoStreamsOptionCopy = Kopiatu lotura beste nabigatzaile batean irekitzeko\nnoStreamsOptionFirefox = Probatu gure nabigatzaile gogokoena\nnoStreamsOptionDownload = Jarraitu nabigatzaile honekin\ndownloadFirefoxPromo = Erabat berritutako { -firefox }(e)k eskaintzen dizu { -send-short-brand }\n# the next line after the colon contains a file name\nshareLinkDescription = Partekatu zure fitxategirako lotura:\nshareLinkButton = Partekatu lotura\n# $name is the name of the file\nshareMessage = Deskargatu \"{ $name }\" { -send-brand } erabiliz: fitxategi-partekatze sinple eta segurua\ntrailheadPromo = Badago zure pribatutasuna babesteko modua. Egizu bat Firefoxekin.\nlearnMore = Argibide gehiago.\n"
  },
  {
    "path": "public/locales/fa/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = بازخورد\nimportingFile = در حال وارد کردن…\nencryptingFile = در حال رمزنگاری…\ndecryptingFile = در حال رمزگشایی…\ndownloadCount =\n    { $num ->\n        [one] ۱ بارگیری\n       *[other] { $num } بارگیری\n    }\ntimespanHours =\n    { $num ->\n        [one] ۱ ساعت\n       *[other] { $num } ساعت\n    }\ncopiedUrl = رونوشت شد!\nunlockInputPlaceholder = گذرواژه\nunlockButtonLabel = باز کردن\ndownloadButtonLabel = بارگیری\ndownloadFinish = بارگیری کامل شد\nfileSizeProgress = ({ $partialSize } از { $totalSize })\nsendYourFilesLink = Send را امتحان کنید\nerrorPageHeader = خطایی رخ داد!\nfileTooBig = این پرونده بسیار حجیم است. حجم آن می‌بایستی کم تر { $size } باشد.\nlinkExpiredAlt = پیوند منقضی شده است\nnotSupportedHeader = مرورگر شما پشتیبانی نمی‌شود.\nnotSupportedLink = چرا از مرورگر من پشتیبانی نمی‌شود؟\nnotSupportedOutdatedDetail = متاسفانه این نسخه از فایرفاکس این تکنولوژی وب که به Send قدرت می‌بخشد را پشتیبانی نمی‌کند. شما نیاز دارید تا مرورگر خود را بروز کنید.\nupdateFirefox = بروزرسانی فایرفاکس\ndeletePopupCancel = انصراف\ndeleteButtonHover = حذف\nfooterLinkLegal = ملاحظات حقوقی\nfooterLinkPrivacy = حریم‌خصوصی\nfooterLinkCookies = کوکی‌ها\npasswordTryAgain = کلمه عبور اشتباه است. مجدد تلاش کنید.\njavascriptRequired = Send نیازمند جاوااسکریپت است\nwhyJavascript = چرا Send جاوااسکریپت لازم داد؟\nenableJavascript = لطفا جاوااسکریپت را فعال کنید و مجددا تلاش کنید.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }ساعت { $minutes }دقیقه\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } دقیقه\n# A short status message shown when the user enters a long password\nmaxPasswordLength = حداکثر اندازهٔ گذرواژه: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = امکان ثبت این گذواژه نیست\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = ارسال\n-firefox = فایرفاکس\n-mozilla = موزیلا\nintroTitle = اشتراک‌گذاری ساده و خصوصیِ پرونده‌ها\nintroDescription = { -send-brand } به شما امکان اشتراک‌گذاری فایل‌ها با رمزگذاری سرتاسری و لینکی که به طور خودکار منقضی می شود را می‌دهد. در نتیجه می‌توانید اشتراک گذاری‌های خود را خصوصی نگه دارید و اطمینان حاصل کنید که فایل‌های شما تا همیشه آنلاین دردسترس نخواهند ماند.\nnotifyUploadEncryptDone = پرونده شما رمزگذاری شده و آماده ارسال است\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = پس از { $downloadCount } یا { $timespan } منقضی می‌شود\ntimespanMinutes =\n    { $num ->\n        [one] 1 دقیقه\n       *[other] { $num } دقیقه\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 روز\n       *[other] { $num } روز\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 هفته\n       *[other] { $num } هفته\n    }\nfileCount =\n    { $num ->\n        [one] 1 پرونده\n       *[other] { $num } پرونده\n    }\n# byte abbreviation\nbytes = بایت\n# kibibyte abbreviation\nkb = کیلوبایت\n# mebibyte abbreviation\nmb = مگابایت\n# gibibyte abbreviation\ngb = گیگابایت\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = حجم کل: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = برای به اشتراک گذاشتن فایل خود، لینک را کپی کنید:\ncopyLinkButton = رونوشت از پیوند\ndownloadTitle = دریافت پرونده‌ها\ndownloadDescription = این پرونده از طریق { -send-brand } با رمزگذاری سرتاسری و پیوندی که به طور خودکار منقضی می شود، به اشتراک گذاشته شد.\ntrySendDescription = { -send-brand } را برای اشتراک گذاری ساده و ایمن پرونده امتحان کنید.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] تنها 1 پرونده می‌تواند در لحظه بارگزاری شود.\n       *[other] تنها { $count } پرونده می‌تواند در لحظه بارگزاری شود.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] تنها 1 بایگانی مجاز است.\n       *[other] تنها { $count } بایگانی مجاز است.\n    }\nexpiredTitle = این پیوند منقضی شده است.\nnotSupportedDescription = { -send-brand } با این مرورگر کار نخواهد کرد. { -send-short-brand } بهترین عملکرد را با آخرین نسخه { -firefox } خواهد داشت، و با آخرین نسخه اکثر مرورگر‌های کنونی کار می‌کند.\ndownloadFirefox = دریافت { -firefox }\nlegalTitle = { -send-short-brand } نکات حفظ حریم خصوصی\nlegalDateStamp = نسخه ۱.۰، مورخ ۱۲، ۲۰۱۹\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } روز { $hours } ساعت { $minutes } دقیقه\naddFilesButton = پرونده‌ها را برای بارگذاری انتخاب کنید\nuploadButton = بارگذاری\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = فایل‌ها را بکشید و اینجا رها کنید\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = یا برای ارسال تا { $size } کلیک کنید\naddPassword = با گذرواژه محافظت کنید\nemailPlaceholder = ایمیل خود را وارد کنید\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = برای ارسال تا { $size } وارد شوید\nsignInOnlyButton = ورود\naccountBenefitTitle = یک حساب { -firefox } ایجاد کنید یا وارد شوید\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = پرونده‌هایی تا { $size } را اشتراک‌گذاری کنید\naccountBenefitDownloadCount = پرونده‌ها را با افراد بیشتری به اشتراک بگذارید\naccountBenefitTimeLimit =\n    { $count ->\n        [one] پیوند‌ها را تا 1 روز فعال نگه دارید\n       *[other] پیوند‌ها را تا { $count } روز فعال نگه دارید\n    }\naccountBenefitSync = فایل‌های اشتراکی را از هر دستگاه مدیریت کنید\naccountBenefitMoz = در مورد سایر خدمات { -mozilla } اطلاعات کسب کنید\nsignOut = خروج\nokButton = تأیید\ndownloadingTitle = در حال بارگیری\nnoStreamsWarning = ممکن است این مرورگر نتواند یک پرونده به این بزرگی را رمزگشایی کند.\nnoStreamsOptionCopy = لینک را کپی کنید تا در مرورگر دیگری باز شود\nnoStreamsOptionFirefox = مرورگر مورد علاقه ما را امتحان کنید\nnoStreamsOptionDownload = با این مرورگر ادامه دهید\ndownloadFirefoxPromo = { -send-short-brand } با جدیدترین { -firefox } برای شما آماده شده است.\n# the next line after the colon contains a file name\nshareLinkDescription = پیوند مربوط به پرونده خود را به اشتراک بگذارید:\nshareLinkButton = اشتراک‌گذاری پیوند\n# $name is the name of the file\nshareMessage = “{ $name }” را با { -send-brand } دانلود کنید: اشتراک‌گذاری ساده و امن فایل\ntrailheadPromo = راهی برای محافظت از حریم خصوصی شما وجود دارد. به Firefox بپیوندید.\nlearnMore = بیشتر بدانید.\n"
  },
  {
    "path": "public/locales/fi/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Tuodaan…\nencryptingFile = Salataan...\ndecryptingFile = Puretaan salausta...\ndownloadCount =\n    { $num ->\n        [one] yhden latauksen\n       *[other] { $num } latauksen\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 tunnin\n       *[other] { $num } tunnin\n    }\ncopiedUrl = Kopioitu!\nunlockInputPlaceholder = Salasana\nunlockButtonLabel = Avaa\ndownloadButtonLabel = Lataa\ndownloadFinish = Lataus valmis\nfileSizeProgress = { $partialSize } / { $totalSize }\nsendYourFilesLink = Kokeile Send -palvelua\nerrorPageHeader = Jokin meni pieleen!\nfileTooBig = Tämä tiedosto on liian suuri ladattavaksi. Sen pitäisi olla pienempi kuin { $size }.\nlinkExpiredAlt = Linkki on vanhentunut\nnotSupportedHeader = Selaintasi ei tueta.\nnotSupportedLink = Miksi selaintani ei tueta?\nnotSupportedOutdatedDetail = Valitettavasti tämä Firefoxin versio ei tue Sendiä käyttävää web-tekniikkaa. Sinun on päivitettävä selaimesi.\nupdateFirefox = Päivitä Firefox\ndeletePopupCancel = Peruuta\ndeleteButtonHover = Poista\nfooterLinkLegal = Juridiset asiat\nfooterLinkPrivacy = Tietosuoja\nfooterLinkCookies = Evästeet\npasswordTryAgain = Väärä salasana. Yritä uudelleen.\njavascriptRequired = Firefox-Send vaatii JavaScriptin\nwhyJavascript = Miksi Send vaatii JavaScriptin?\nenableJavascript = Ota JavaScript käyttöön ja yritä uudelleen.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } t { $minutes } min\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } min\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Salasanan enimmäispituus: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Tätä salasanaa ei voitu asettaa\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Helppoa ja yksityistä tiedostonjakoa\nintroDescription = { -send-brand } mahdollistaa tiedostojen jakamisen automaattisesti vanhenevalla linkillä. Tiedostojen jakaminen tapahtuu päästä päähän -salattuna. Näin jakamasi tiedostot pysyvät yksityisinä ja voit olla varma, etteivät lähettämäsi tiedostot pysy verkossa ikuisesti.\nnotifyUploadEncryptDone = Tiedosto on salattu ja valmis lähetettäväksi\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Vanhenee { $downloadCount } tai { $timespan } jälkeen\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuutin\n       *[other] { $num } minuutin\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 päivän\n       *[other] { $num } päivän\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 viikon\n       *[other] { $num } viikon\n    }\nfileCount =\n    { $num ->\n        [one] 1 tiedosto\n       *[other] { $num } tiedostoa\n    }\n# byte abbreviation\nbytes = t\n# kibibyte abbreviation\nkb = kt\n# mebibyte abbreviation\nmb = Mt\n# gibibyte abbreviation\ngb = Gt\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Koko yhteensä: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopioi linkki jakaaksesi tiedoston:\ncopyLinkButton = Kopioi linkki\ndownloadTitle = Lataa tiedostot\ndownloadDescription = Tämä tiedosto jaettiin { -send-brand } -palvelun kautta päästä päähän -salattuna ja automaattisesti vanhenevalla linkillä.\ntrySendDescription = Kokeile { -send-brand } -palvelua jakaaksesi tiedostoja helposti ja turvallisesti.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Vain 1 tiedosto on mahdollistaa lähettää kerralla.\n       *[other] Vain { $count } tiedostoa on mahdollista lähettää kerralla.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Vain 1 arkisto on sallittu.\n       *[other] Vain { $count } arkistoa on sallittu.\n    }\nexpiredTitle = Tämä linkki on vanhentunut.\nnotSupportedDescription = { -send-brand } ei toimi tällä selaimella. { -send-short-brand } toimii parhaiten { -firefox }in uusimmalla versiolla, ja toimii useimpien selainten uusimmilla versioilla.\ndownloadFirefox = Lataa { -firefox }\nlegalTitle = { -send-short-brand }-yksityisyyskäytäntö\nlegalDateStamp = Versio 1.0, päivätty 13. maaliskuuta 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } pv { $hours } t { $minutes } min\naddFilesButton = Valitse lähetettävät tiedostot\ntrustWarningMessage = Varmista, että luotat vastaanottajaan jakaessasi arkaluontoisia tietoja.\nuploadButton = Lähetä\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Vedä ja pudota tiedostot\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = tai napsauta lähettääksesi tiedostoja, joiden koko voi olla enintään { $size }\naddPassword = Suojaa salasanalla\nemailPlaceholder = Kirjoita sähköpostiosoitteesi\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Kirjautumalla voit lähettää jopa { $size } kokoisia tiedostoja\nsignInOnlyButton = Kirjaudu sisään\naccountBenefitTitle = Luo { -firefox }-tili tai kirjaudu sisään\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Jaa jopa { $size } kokoisia tiedostoja\naccountBenefitDownloadCount = Jaa tiedostoja useamman ihmisen kesken\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Säilytä linkit aktiivisina 1 päivän ajan\n       *[other] Säilytä linkit aktiivisina { $count } päivän ajan\n    }\naccountBenefitSync = Hallitse jaettuja tiedostoja miltä tahansa laitteelta\naccountBenefitMoz = Lue lisää muista { -mozilla }-palveluista\nsignOut = Kirjaudu ulos\nokButton = OK\ndownloadingTitle = Ladataan\nnoStreamsWarning = Tämä selain ei välttämättä osaa purkaa salausta näin suurikokoisista tiedostoista.\nnoStreamsOptionCopy = Kopioi linkki avataksesi sen toisessa selaimessa\nnoStreamsOptionFirefox = Kokeile suosikkiselaintamme\nnoStreamsOptionDownload = Jatka tällä selaimella\ndownloadFirefoxPromo = { -send-short-brand } on olemassa kiitos uuden { -firefox }in.\n# the next line after the colon contains a file name\nshareLinkDescription = Jaa linkki tiedostoosi:\nshareLinkButton = Jaa linkki\n# $name is the name of the file\nshareMessage = Lataa tiedosto ”{ $name }” { -send-brand } -palvelusta: yksinkertaista ja turvallista tiedostonjakoa\ntrailheadPromo = On tapa suojata yksityisyyttään. Liity Firefoxiin.\nlearnMore = Lue lisää.\ndownloadFlagged = Tämä linkki on poistettu käytöstä palvelun käyttöehtojen rikkomisen vuoksi.\ndownloadConfirmTitle = Vielä yksi asia\ndownloadConfirmDescription = Varmista, että luotat sinulle tämän tiedoston lähettäneeseen henkilöön, koska emme voi vahvistaa, ettei kyseinen tiedosto vahingoita laitettasi.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Luotan henkilöön, joka lähetti tämän tiedoston\n       *[other] Luotan henkilöön, joka lähetti nämä tiedostot\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Ilmoita tämä tiedosto epäilyttävänä\n       *[other] Ilmoita nämä tiedostot epäilyttävinä\n    }\nreportDescription = Auta meitä ymmärtämään mitä tapahtuu. Mikä on mielestäsi vialla näissä tiedostoissa?\nreportUnknownDescription = Siirry sen linkin osoitteeseen, josta haluat tehdä ilmoituksen, ja napsauta “{ reportFile }”.\nreportButton = Ilmoita\nreportReasonMalware = Nämä tiedostot sisältävät haittaohjelmia tai ovat osa tietojenkalasteluhyökkäystä.\nreportReasonPii = Nämä tiedostot sisältävät henkilökohtaisia tietoja minusta.\nreportReasonAbuse = Nämä tiedostot sisältävät laitonta tai loukkaavaa sisältöä.\nreportReasonCopyright = Ilmoita tekijänoikeuksien tai tavaramerkkien loukkauksista <a>tällä sivulla</a> kuvatun prosessin mukaisesti.\nreportedTitle = Tiedostot ilmoitettu\nreportedDescription = Kiitos. Olemme vastaanottaneet raporttisi näistä tiedostoista.\n"
  },
  {
    "path": "public/locales/fr/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importation…\nencryptingFile = Chiffrement…\ndecryptingFile = Déchiffrement…\ndownloadCount =\n    { $num ->\n        [one] 1 téléchargement\n       *[other] { $num } téléchargements\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 heure\n       *[other] { $num } heures\n    }\ncopiedUrl = Lien copié !\nunlockInputPlaceholder = Mot de passe\nunlockButtonLabel = Déverrouiller\ndownloadButtonLabel = Télécharger\ndownloadFinish = Téléchargement terminé\nfileSizeProgress = ({ $partialSize } sur { $totalSize })\nsendYourFilesLink = Essayer Send\nerrorPageHeader = Une erreur s’est produite.\nfileTooBig = Ce fichier est trop volumineux pour être envoyé. Sa taille doit être inférieure à { $size }.\nlinkExpiredAlt = Le lien a expiré\nnotSupportedHeader = Votre navigateur n’est pas pris en charge.\nnotSupportedLink = Pourquoi mon navigateur n’est-il pas pris en charge ?\nnotSupportedOutdatedDetail = Malheureusement, cette version de Firefox ne prend pas en charge les technologies web utilisées par Send. Vous devez mettre à jour votre navigateur.\nupdateFirefox = Mettre à jour Firefox\ndeletePopupCancel = Annuler\ndeleteButtonHover = Supprimer\nfooterLinkLegal = Mentions légales\nfooterLinkPrivacy = Confidentialité\nfooterLinkCookies = Cookies\npasswordTryAgain = Mot de passe incorrect. Veuillez réessayer.\njavascriptRequired = Send nécessite JavaScript\nwhyJavascript = Pourquoi Send nécessite-t-il JavaScript ?\nenableJavascript = Veuillez activer JavaScript puis réessayer.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } h { $minutes } min\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } min\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Longueur maximale du mot de passe : { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Ce mot de passe n’a pas pu être défini\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Partage de fichiers simple et privé\nintroDescription = { -send-brand } vous permet de partager des fichiers chiffrés de bout en bout ainsi qu’un lien qui expire automatiquement. Ainsi, vous pouvez garder ce que vous partagez en privé et vous assurer que vos contenus ne restent pas en ligne pour toujours.\nnotifyUploadEncryptDone = Votre fichier est chiffré et prêt à l’envoi\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Expire après { $downloadCount } ou { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minute\n       *[other] { $num } minutes\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 jour\n       *[other] { $num } jours\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 semaine\n       *[other] { $num } semaines\n    }\nfileCount =\n    { $num ->\n        [one] 1 fichier\n       *[other] { $num } fichiers\n    }\n# byte abbreviation\nbytes = o\n# kibibyte abbreviation\nkb = Ko\n# mebibyte abbreviation\nmb = Mo\n# gibibyte abbreviation\ngb = Go\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Taille totale : { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copiez le lien pour partager votre fichier :\ncopyLinkButton = Copier le lien\ndownloadTitle = Télécharger les fichiers\ndownloadDescription = Ce fichier a été partagé via { -send-brand } avec un chiffrement de bout en bout et un lien qui expire automatiquement.\ntrySendDescription = Essayez { -send-brand } pour un partage de fichiers simple et sécurisé.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Un seul fichier peut être envoyé à la fois.\n       *[other] Seuls { $count } fichiers peuvent être envoyés à la fois.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Une seule archive est autorisée.\n       *[other] Seules { $count } archives sont autorisées.\n    }\nexpiredTitle = Ce lien a expiré.\nnotSupportedDescription = { -send-brand } ne fonctionnera pas avec ce navigateur. { -send-short-brand } fonctionne mieux avec la dernière version de { -firefox } et fonctionnera avec la dernière version de la plupart des navigateurs.\ndownloadFirefox = Télécharger { -firefox }\nlegalTitle = Politique de confidentialité de { -send-short-brand }\nlegalDateStamp = Version 1.0 du 12 mars 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } j { $hours } h { $minutes } min\naddFilesButton = Sélectionnez des fichiers à envoyer\ntrustWarningMessage = Assurez-vous de faire confiance au destinataire lorsque vous partagez des données sensibles.\nuploadButton = Envoyer\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Glissez-déposez des fichiers\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = ou cliquez pour envoyer jusqu’à { $size }\naddPassword = Protéger par mot de passe\nemailPlaceholder = Votre adresse électronique\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Connectez-vous pour envoyer jusqu’à { $size }\nsignInOnlyButton = Connexion\naccountBenefitTitle = Créez un compte { -firefox } ou connectez-vous\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Partagez des fichiers jusqu’à { $size }\naccountBenefitDownloadCount = Partagez des fichiers avec davantage de personnes\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Maintenez les liens actifs jusqu’à 1 journée\n       *[other] Maintenez les liens actifs jusqu’à { $count } jours\n    }\naccountBenefitSync = Gérez les fichiers partagés à partir de n’importe quel appareil\naccountBenefitMoz = Apprenez-en davantage sur les autres services { -mozilla }\nsignOut = Se déconnecter\nokButton = OK\ndownloadingTitle = Téléchargement en cours\nnoStreamsWarning = Ce navigateur pourrait ne pas être en mesure de déchiffrer un fichier aussi volumineux.\nnoStreamsOptionCopy = Copiez le lien pour l’ouvrir dans un autre navigateur\nnoStreamsOptionFirefox = Essayez notre navigateur préféré\nnoStreamsOptionDownload = Continuer avec ce navigateur\ndownloadFirefoxPromo = { -send-short-brand } vous est proposé par le tout nouveau { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Partagez le lien vers votre fichier :\nshareLinkButton = Partager le lien\n# $name is the name of the file\nshareMessage = Télécharger « { $name } » avec { -send-brand } : un moyen simple et sûr de partager des fichiers\ntrailheadPromo = Il existe un moyen de protéger votre vie privée. Rejoignez Firefox.\nlearnMore = En savoir plus.\ndownloadFlagged = Ce lien a été désactivé en raison d’une violation des conditions d’utilisation.\ndownloadConfirmTitle = Une dernière chose\ndownloadConfirmDescription = Assurez-vous de faire confiance à la personne qui vous a envoyé ce fichier, car nous ne pouvons pas vérifier qu’il n’endommagera pas votre appareil.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Je fais confiance à la personne qui a envoyé ce fichier\n       *[other] Je fais confiance à la personne qui a envoyé ces fichiers\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Signaler ce fichier comme suspect\n       *[other] Signaler ces fichiers comme suspects\n    }\nreportDescription = Aidez-nous à comprendre ce qui se passe. Selon vous, quel est le problème avec ces fichiers ?\nreportUnknownDescription = Accédez à l’adresse du lien que vous souhaitez signaler et cliquez sur « { reportFile } ».\nreportButton = Signaler\nreportReasonMalware = Ces fichiers contiennent des logiciels malveillants ou contribuent à une attaque de hameçonnage.\nreportReasonPii = Ces fichiers contiennent des informations personnelles qui me concernent.\nreportReasonAbuse = Ces fichiers contiennent du contenu illégal ou abusif.\nreportReasonCopyright = Pour signaler une violation de droit d’auteur ou de marque, suivez la procédure décrite sur <a>cette page</a>.\nreportedTitle = Fichiers signalés\nreportedDescription = Merci, nous avons reçu votre signalement relatif à ces fichiers.\n"
  },
  {
    "path": "public/locales/fy-NL/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Ymportearje…\nencryptingFile = Fersiferje…\ndecryptingFile = Untsiferje…\ndownloadCount =\n    { $num ->\n        [one] 1 download\n       *[other] { $num } downloads\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 oer\n       *[other] { $num } oer\n    }\ncopiedUrl = Kopiearre!\nunlockInputPlaceholder = Wachtwurd\nunlockButtonLabel = Deblokkearje\ndownloadButtonLabel = Downloade\ndownloadFinish = Download foltôge\nfileSizeProgress = ({ $partialSize } fan { $totalSize })\nsendYourFilesLink = Send probearje\nerrorPageHeader = Der is wat misgien!\nfileTooBig = It bestân is te grut om op te laden. It moat lytser wêze as { $size }.\nlinkExpiredAlt = Keppeling ferrûn\nnotSupportedHeader = Jo browser wurdt net stipe.\nnotSupportedLink = Wêrom wurdt myn browser net stipe?\nnotSupportedOutdatedDetail = Spitigernôch stipet dizze ferzje fan Firefox de webtechnology dy't Send mooflik makket net. Jo moatte jo browser fernije.\nupdateFirefox = Firefox fernije\ndeletePopupCancel = Annulearje\ndeleteButtonHover = Fuortsmite\nfooterLinkLegal = Juridysk\nfooterLinkPrivacy = Privacy\nfooterLinkCookies = Cookies\npasswordTryAgain = Net krekt wachtwurd. Probearje it opnij.\njavascriptRequired = Send fereasket JavaScript.\nwhyJavascript = Werom hat Send JavaScript nedich?\nenableJavascript = Skeakelje JavaScript yn en probearje nochris.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }o { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maksimale wachtwurdlingte: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Dit wachtwurd koe net ynsteld wurde\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Ienfâldich, privee bestannen diele\nintroDescription = Mei { -send-brand } kinne jo bestannen mei ein-ta-ein-fersifering en in automatysk ferrinnende keppeling diele. Sa kinne jo de dielde ynhâld privee hâlde, sadat jo gegevens net foar altyd online bliuwt.\nnotifyUploadEncryptDone = Jo bestân is fersifere en ree om te ferstjoeren\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Ferrint nei { $downloadCount } of { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minute\n       *[other] { $num } minuten\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 dei\n       *[other] { $num } dagen\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 wike\n       *[other] { $num } wiken\n    }\nfileCount =\n    { $num ->\n        [one] 1 bestân\n       *[other] { $num } bestannen\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Totale grutte: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopiearje de keppeling, om jo bestannen te dielen:\ncopyLinkButton = Keppeling kopierje\ndownloadTitle = Bestannen downloade\ndownloadDescription = Dit bestân is mei ein-ta-ein-fersifering en in keppeling dy't automatysk ferrint dield fia { -send-brand }.\ntrySendDescription = Probearje { -send-brand }, om ienfâldich en privee bestannen te dielen.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Der kin maksimaal ien bestân opladen wurde.\n       *[other] Der kinne maksimaal { $count } bestannen opladen wurde.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Der is mar ien argyf tastien.\n       *[other] Der binne mar { $count } argiven tastien.\n    }\nexpiredTitle = Dizze keppeling is ferrûn.\nnotSupportedDescription = { -send-brand } funksjonearret net mei dizze browser. { -send-short-brand } funksjonearret it bêste mei de nijste ferzje fan { -firefox } en funksjonearret mei de aktuele ferzje fan de measte browsers.\ndownloadFirefox = { -firefox } downloade\nlegalTitle = { -send-short-brand }-privacyferklearring\nlegalDateStamp = Ferzje 1.0, datearre 12 maart 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }o { $minutes }m\naddFilesButton = Bestannen selektearje om op te laden\ntrustWarningMessage = Soargje derfoar dat jo jo ûntfanger fertrouwe wannear't jo gefoelige gegevens diele.\nuploadButton = Oplade\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Sleep en pleats bestannen\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = of stjoer oant { $size } troch te klikken\naddPassword = Mei wachtwurd beskermje\nemailPlaceholder = Fier jo e-mailadres yn\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Meld jo oan, om bestannen oant { $size } te stjoeren\nsignInOnlyButton = Oanmelde\naccountBenefitTitle = Meitsje in { -firefox }-account of meld jo oan\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Diel bestannen oant { $size }\naccountBenefitDownloadCount = Diel bestannen mei mear minsken\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Keppeling oant ien dei lang aktyf hâlde\n       *[other] Keppeling oant { $count } dagen lang aktyf hâlde\n    }\naccountBenefitSync = Behear dielde bestannen fan elk apparaat ôf\naccountBenefitMoz = Lês mear oer oare { -mozilla }-tsjinsten\nsignOut = Ofmelde\nokButton = OK\ndownloadingTitle = Downloade\nnoStreamsWarning = Dizze browser kin in sa'n grut bestân mooglik net fersiferje.\nnoStreamsOptionCopy = Kopiearje de koppeling om yn in oare browser te iepenjen\nnoStreamsOptionFirefox = Probearje ús favorite browser\nnoStreamsOptionDownload = Trochgean mei dizze browser\ndownloadFirefoxPromo = { -send-short-brand } wurdt jo oanbean troch it folslein fernijde { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Diel de keppeling nei jo bestân:\nshareLinkButton = Keppeling diele\n# $name is the name of the file\nshareMessage = Download ‘{ $name }’ mei { -send-brand }: ienfâldich, feilich bestannen diele\ntrailheadPromo = Der is in manier om jo privacy te beskermjen. Doch mei mei Firefox.\nlearnMore = Mear ynfo.\ndownloadFlagged = Dizze keppeling is útskeakele fanwegen skeining fan de servicebetingsten.\ndownloadConfirmTitle = Noch ien ding\ndownloadConfirmDescription = Soargje derfoar dat jo de persoan fertrouwe dy't jo dit bestân stjoerd hat, omdat wy net ferifiearje kinne dat it jo apparaat net skansearje sil.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Ik fertrou de persoan dy't dit bestân stjoerd hat\n       *[other] Ik fertrou de persoan dy't dizze bestannen stjoerd hat\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Dit bestân as fertocht rapportearje\n       *[other] Dizze bestannen as fertocht rapportearje\n    }\nreportDescription = Help ús te begripen wat der oan de hân is. Wat is der neffens jo mis mei dizze bestannen?\nreportUnknownDescription = Gean nei de URL fan de keppeling dy't jo melde wolle en klik op ‘{ reportFile }’.\nreportButton = Rapportearje\nreportReasonMalware = Dizze bestannen befetsje malware of binne part fan in phishingoanfal.\nreportReasonPii = Dizze bestannen befetsje persoanlik identifisearjende ynformaasje oer my.\nreportReasonAbuse = Dizze bestannen befetsje yllegale of beledigjende ynhâld.\nreportReasonCopyright = Brûk de proseduere op <a>dizze side</a> om ynbreuk op auteursrjochten of hannelsmerken te melden.\nreportedTitle = Bestannen rapportearre\nreportedDescription = Tank. Wy hawwe jo rapport oer dizze bestannen ûntfongen.\n"
  },
  {
    "path": "public/locales/gn/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Ojegueruhína…\nencryptingFile = Mo’ãmby…\ndecryptingFile = Ñemo’ã’o…\ndownloadCount =\n    { $num ->\n        [one] 1 mboguejy\n       *[other] { $num } mboguejy\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 aravo\n       *[other] { $num } aravo\n    }\ncopiedUrl = Monguatiapyre!\nunlockInputPlaceholder = Ñe’ẽñemi\nunlockButtonLabel = Mbojera\ndownloadButtonLabel = Mboguejy\ndownloadFinish = Oguejypáma\nfileSizeProgress = ({ $partialSize } rehe { $totalSize })\nsendYourFilesLink = Eipuru Send\nerrorPageHeader = ¡Oiko jejavy!\nfileTooBig = Marandurenda tuichaiterei ehupi hag̃ua. Michĩveva’erã { $size } gui.\nlinkExpiredAlt = Juajuha ndoikóiva\nnotSupportedHeader = Ne kundaha ndorekói pytyvõ.\nnotSupportedLink = ¿Mba’ére che kundahára ndorekói ñepytyvõ?\nnotSupportedOutdatedDetail = Ko Firefox rembiapo ndaipu’akái ñanduti rembipurupyahu oikotevẽva Send. Embohekopyahúke ne kundahára.\nupdateFirefox = Firefox mbohekopyahu\ndeletePopupCancel = Heja\ndeleteButtonHover = Mboguete\nfooterLinkLegal = Añetegua\nfooterLinkPrivacy = Ñemigua\nfooterLinkCookies = Kookie\npasswordTryAgain = Ñe’ẽñemi ndoikóiva. Eha’ãjey.\njavascriptRequired = Send oikotevẽ JavaScript\nwhyJavascript = ¿Mba’ére Send oikotevẽ JavaScript?\nenableJavascript = Ikatúpa embojuruja JavaScript ha eha’ãjey uperire.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } h { $minutes } m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Ñe’ẽñemi pukukue: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Ndaikatúi oikóvo ko ñe’ẽñemi\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Marandurenda ñemoambue hasy’ỹ ha ñemiguáva\nintroDescription = { -send-brand } omoherakuãkuaa marandurenda papapýpe ñepyrũ guive opa peve ha juajuha opareíva ijehegui. Ikatu oreko ñemihápe emoherakuãva ha ehecháta mba’éicha ne mba’ekuéra noĩri ñandutípe opa ára.\nnotifyUploadEncryptDone = Ne marandurenda oñemo’ã ha ikatúma emondo\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Opáta { $downloadCount } rire térã { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 aravo’i\n       *[other] { $num } aravo’i\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 ára\n       *[other] { $num } ára\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 arapokõindy\n       *[other] { $num } arapokõindy\n    }\nfileCount =\n    { $num ->\n        [one] 1 marandurenda\n       *[other] { $num } marandurenda\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Tuichakue: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Emonguatia juajuha ha emoherakuã ne marandurenda:\ncopyLinkButton = Emonguatia juajuha\ndownloadTitle = Emboguejy marandurenda\ndownloadDescription = Ko marandurenda omoherakuã { -send-brand } rupive papapýpe ñepyrũ guive opa peve ha juajuha opáva ijehegui reheve.\ntrySendDescription = Eipuru { -send-brand } emoherakuã hag̃ua marandurenda tasy’ỹ ha tekorosãme.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Ikatu ehupi 1 marandurenda oñondive\n       *[other] Ikatu ehupi { $count } marandurenda oñondive\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Oñemoneĩ 1 marandurenda añoite\n       *[other] Oñemoneĩ { $count } marandurenda añoite\n    }\nexpiredTitle = Ko juajuha ndoikovéima.\nnotSupportedDescription = { -send-brand } ndoikomo’ãi ko kundahára ndive. { -send-short-brand } oikoporãvéta { -firefox } rembiapokue ipyahuvéva ndive, ha oikóta opavavete kundahára ndive.\ndownloadFirefox = Emboguejy { -firefox }\nlegalTitle = { -send-short-brand } Marandu ñemigua\nlegalDateStamp = Mba’epyahu 1.0, 12 jasyapy 2019 peguare\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Eiporavo marandurenda ehupi hag̃ua\ntrustWarningMessage = Ejerovia añetépa emondotaháre emoherakuãvo mba’ekuaarã kañyguáva.\nuploadButton = Hupi\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Embosyryry ha epoi marandurenda\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = térã eikutu emondo hag̃ua { $size } peve\naddPassword = Ñe’ẽñemíme mo’ãmbyre\nemailPlaceholder = Emoinge ne ñanduti veve\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Eñepyrũ tembiapo emondo hag̃ua { $size } peve\nsignInOnlyButton = Eñepyrũ tembiapo\naccountBenefitTitle = Emoheñói { -firefox } mba’ete térã eñepyrũ tembiapo\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Emoherakuã marandurenda { $size } peve\naccountBenefitDownloadCount = Emoherakuã marandurenda hetave tapicha ndive\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Eguereko juajuha hendyhápe 1 ára\n       *[other] Eguereko juajuha hendyhápe { $count } ára\n    }\naccountBenefitSync = Eñangareko marandurenda moherakuãmbyrére oimeraẽ mba’e’oka guive.\naccountBenefitMoz = Eikuaa ambue { -mozilla } mba’epytyvõrã\nsignOut = Emboty tembiapo\nokButton = OK\ndownloadingTitle = Oñemboguejyhína\nnoStreamsWarning = Ikatu ko kundahára ndoikuaái marandurenda tuichaitereíva.\nnoStreamsOptionCopy = Embokuatia juajuha embojuruja hag̃ua ambue kundahárape.\nnoStreamsOptionFirefox = Eipuru ore kundahára rohayhuvéva\nnoStreamsOptionDownload = Eku’ejey ko kundahára ndive\ndownloadFirefoxPromo = Ipyahúva { -firefox } ome’ẽse ndéve { -send-short-brand }.\n# the next line after the colon contains a file name\nshareLinkDescription = Emoherakuã juajuha ne mba’e’oka ndive:\nshareLinkButton = Emoherakuã juajuha\n# $name is the name of the file\nshareMessage = Emboguejy “{ $name }” { -send-brand } ndive: emoherakuã marandurenda tasy’ỹ ha tekorosãme\ntrailheadPromo = Mba’éichapa emo’ãta ne ñemigua. Eipuru Firefox.\nlearnMore = Kuaave.\ndownloadFlagged = Ko juajuha ojepe’áma ombyai rupi mba’epytyvõrã ñemboguata.\ndownloadConfirmTitle = Peteĩ mba’eve\ndownloadConfirmDescription = Ejerovia añetépa pe tapicha oguerukáva ndéve ko marandurenda ndaikatúire rohechajey ne mba’e’oka.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Ajerovia tapicháre orukáva ko marandurenda\n       *[other] Ajerovia umi tapicha orukáva ko’ã marandurenda\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Ehechauka ko marandurenda imarãkuaávarõ\n       *[other] Ehechauka ko’ã marandurenda imarãkuaávarõ\n    }\nreportDescription = Orepytyvõ roikumbývo mba’épa oiko. ¿Mba’épa ere oĩvaiha ko’ã marandurenda ndive?\nreportUnknownDescription = Eikundaha pe url juajuha ekoroiseha ndive ha eikutu “{ reportFile }”.\nreportButton = Ekorói\nreportReasonMalware = Ko’ã marandurenda oreko tembiaporape imarãva térã oñembyaikuaáva.\nreportReasonPii = Ko’ã marandurenda oreko marandu nemba’etéva che kuaaukakuaáva.\nreportReasonAbuse = Ko’ã marandurenda oreko tetepy ivai térã imbaretéva.\nreportReasonCopyright = Ekoróitarõ derécho ñembyaíre térã marca registrada, ehecha jehaipyre <a>ko kuatiaroguépe</a>.\nreportedTitle = Marandurenda jekoroihague\nreportedDescription = Aguyje. Og̃uahẽ nde jekorói ko’ã marandurenda rehegua.\n"
  },
  {
    "path": "public/locales/gor/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Firefox Molawo\nsiteSubtitle = web yimontalo\nsiteFeedback = Potunu\nuploadPageLearnMore = Pobalajariya po'olo\nuploadPageBrowseButton = Tulawota berkas to delomo komputermu\nuploadPageBrowseButton1 = Tulawota berkas u detohulo\nuploadPageBrowseButtonTitle = Detohe berkas\nuploadingPageProgress = Hemodetohu { $filename } ({ $size })\nnotifyUploadDone = Diletohumu ma yilapato\nuploadingPageMessage = Bataliya modetohu\nuploadingPageCancel = Bataliya modetohu\nuploadCancelNotification = Diletohumu ma bilatali\nuploadingPageLargeFileMessage = Berkas botiya damango wawu paralu wakutu ngope'e mopodetohu. Potihulo'opo!\nuploadingFileNotification = Poleleya ola'u wonu ma yilapato lodetohu.\nuploadSuccessConfirmHeader = Siap Molawo\nuploadSvgAlt = Detohe\ntimespanHours =\n    { $num ->\n       *[other] { $num } jam\n    }\ncopiedUrl = Yilami\ndeleteFileButton = Luluta berkas\nsendAnotherFileLink = Lawola berkas uwewo\n# Alternative text used on the download link/button (indicates an action).\ndownloadAltText = Mopohuli\ndownloadsFileList = Mopohuli\n# Used as header in a column indicating the amount of time left before a\n# download link expires (e.g. \"10h 5m\")\ntimeFileList = Wakutu\n# Used as header in a column indicating the number of times a file has been\n# downloaded\ndownloadFileName = Mopohuli { $filename }\ndownloadFileSize = ({ $size })\nunlockInputLabel = Tuwota Password\nunlockInputPlaceholder = Password\nunlockButtonLabel = Hu'owa\ndownloadFileTitle = Mopohuli Enskripsi Berkas\n# Text and title used on the download link/button (indicates an action).\ndownloadButtonLabel = Mopohuli\ndownloadNotification = U pilopohulimu ma yilapato.\ndownloadFinish = Mopohuli Yilapato\n# This message is displayed when uploading or downloading a file, e.g. \"(1,3 MB of 10 MB)\".\nfileSizeProgress = ({ $partialSize } meyalo { $totalSize })\n# Send is a brand name and should not be localized.\nsendYourFilesLink = Yimontali Firefox Molawo\ndownloadingPageProgress = Modetohu { $filename } ({ $size })\ndownloadFirefoxButtonSub = Pereyi Mopohuli\nuploadedFile = Berkas\ncopyFileList = Kupe'iya URL\n# expiryFileList is used as a column header\nexpiryFileList = Mopulito To\ndeleteFileList = Luluta\nnevermindButton = Sambelo\ndeletePopupText = Luluta berkas botiya?\ndeletePopupYes = Joo\ndeletePopupCancel = Bataliya\ndeleteButtonHover = Luluta\ncopyUrlHover = Kupe'iya URL\nfooterLinkLegal = Legal\n# Test Pilot is a proper name and should not be localized.\nfooterLinkAbout = Tomimbihu Test Pilot\nchangePasswordButton = Boli'a\n"
  },
  {
    "path": "public/locales/he/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = מתבצע ייבוא…\nencryptingFile = מתבצעת הצפנה...\ndecryptingFile = מתבצע פענוח...\ndownloadCount =\n    { $num ->\n        [one] הורדה אחת\n       *[other] { $num } הורדות\n    }\ntimespanHours =\n    { $num ->\n        [one] שעה אחת\n        [two] שעתיים\n       *[other] { $num } שעות\n    }\ncopiedUrl = הועתק!\nunlockInputPlaceholder = ססמה\nunlockButtonLabel = שחרור נעילה\ndownloadButtonLabel = הורדה\ndownloadFinish = ההורדה הושלמה\nfileSizeProgress = ({ $partialSize } מתוך { $totalSize })\nsendYourFilesLink = נסו את Send\nerrorPageHeader = משהו השתבש!\nfileTooBig = הקובץ הזה גדול מידי להעלאה. עליו להיות קטן מ־{ $size }.\nlinkExpiredAlt = הקישור פג\nnotSupportedHeader = הדפדפן שלך לא נתמך.\nnotSupportedLink = למה אין תמיכה בדפדפן שלי?\nnotSupportedOutdatedDetail = לצערנו גרסת Firefox זו לא תומכת בטכנולוגית הרשת שמפעילה את Send. יש לעדכן את הגרסה של הדפדפן שלך.\nupdateFirefox = עדכון Firefox\ndeletePopupCancel = ביטול\ndeleteButtonHover = מחיקה\nfooterLinkLegal = מידע משפטי\nfooterLinkPrivacy = פרטיות\nfooterLinkCookies = קובצי עוגיות\npasswordTryAgain = סיסמה שגויה. נא לנסות שוב.\njavascriptRequired = ל־Send דרוש JavaScript\nwhyJavascript = למה ל־Send דרוש JavaScript?\nenableJavascript = נא להפעיל JavaScript ולנסות שוב.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } שע׳ { $minutes } דק׳\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } דק׳\n# A short status message shown when the user enters a long password\nmaxPasswordLength = אורך הססמה המרבי: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = לא ניתן להגדיר את הססמה הזאת\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = שיתוף קבצים פרטי ופשוט\nintroDescription = { -send-brand } מאפשר לך לשתף קבצים עם הצפנה מקצה לקצה וקישור עם תפוגה אוטומטית. בצורה זו תוכלו לשתף קבצים באופן פרטי ולהבטיח שהדברים שלכם לא נשארים ברשת לנצח.\nnotifyUploadEncryptDone = הקובץ שלך מוצפן ומוכן לשליחה\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = יפוג לאחר { $downloadCount } או { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] דקה אחת\n       *[other] { $num } דקות\n    }\ntimespanDays =\n    { $num ->\n        [one] יום אחד\n        [two] יומיים\n       *[other] { $num } ימים\n    }\ntimespanWeeks =\n    { $num ->\n        [one] שבוע אחד\n        [two] שבועיים\n       *[other] { $num } שבועות\n    }\nfileCount =\n    { $num ->\n        [one] קובץ אחד\n       *[other] { $num } קבצים\n    }\n# byte abbreviation\nbytes = בתים\n# kibibyte abbreviation\nkb = ק״ב\n# mebibyte abbreviation\nmb = מ״ב\n# gibibyte abbreviation\ngb = ג״ב\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = גודל כולל: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = יש להעתיק את הקישור כדי לשתף את הקובץ שלך:\ncopyLinkButton = העתקת קישור\ndownloadTitle = הורדת קבצים\ndownloadDescription = קובץ זה שותף באמצעות { -send-brand } עם הצפנה מקצה לקצה וקישור שפג באופן אוטומטי.\ntrySendDescription = כדאי לנסות את { -send-brand } לשיתוף קבצים פשוט ומאובטח.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] ניתן להעלות רק קובץ אחד בכל פעם.\n       *[other] ניתן להעלות רק { $count } קבצים בכל פעם.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] רק ארכיון אחד מורשה.\n       *[other] רק { $count } ארכיונים מורשים.\n    }\nexpiredTitle = פג תוקפו של קישור זה.\nnotSupportedDescription = ‏{ -send-brand } לא יפעל עם דפדפן זה. { -send-short-brand } פועל בצורה הטובה ביותר עם הגרסה העדכנית ביותר של { -firefox }, ויעבוד עם הגרסה הנוכחית של רוב הדפדפנים.\ndownloadFirefox = הורדת { -firefox }\nlegalTitle = הצהרת פרטיות של { -send-short-brand }\nlegalDateStamp = גרסה 1.0, בתאריך 12 במרץ 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } ימים { $hours } שעות { $minutes } דקות\naddFilesButton = בחירת קבצים להעלאה\ntrustWarningMessage = עליך לוודא שבעת שיתוף מידע רגיש הנמענים שלך הם מהימנים.\nuploadButton = העלאה\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = גרירה והשלכת קבצים\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = או ללחוץ כדי לשלוח קבצים עד לגודל של { $size }\naddPassword = הגנה באמצעות ססמה\nemailPlaceholder = נא להכניס כתובת דוא״ל\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = נא להירשם כדי לשלוח קבצים עד גודל של { $size }\nsignInOnlyButton = כניסה\naccountBenefitTitle = נא ליצור חשבון { -firefox } או להיכנס לחשבון\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = שיתוף קבצים עד גודל של { $size }\naccountBenefitDownloadCount = שיתוף קבצים עם יותר אנשים\naccountBenefitTimeLimit =\n    { $count ->\n        [one] שמירה על קישורים פעילים עד ליום אחד\n       *[other] שמירה על קישורים פעילים עד ל־{ $count } ימים\n    }\naccountBenefitSync = ניהול קבצים משותפים מכל מכשיר\naccountBenefitMoz = מידע נוסף על שירותי { -mozilla } אחרים\nsignOut = יציאה\nokButton = אישור\ndownloadingTitle = בהורדה\nnoStreamsWarning = ייתכן שדפדפן זה לא יוכל לפענח קובץ בגודל כזה.\nnoStreamsOptionCopy = העתקת הקישור לפתיחה בדפדפן אחר\nnoStreamsOptionFirefox = נסו את הדפדפן המועדף עלינו\nnoStreamsOptionDownload = המשך בדפדפן זה\ndownloadFirefoxPromo = { -send-short-brand } מובא אליך בחסות { -firefox }\n# the next line after the colon contains a file name\nshareLinkDescription = שיתוף הקישור לקובץ שלך:\nshareLinkButton = שיתוף קישור\n# $name is the name of the file\nshareMessage = הורדת ״{ $name }״ עם { -send-brand }: שיתוף קבצים פשוט ובטוח\ntrailheadPromo = ישנן דרכים נוספות להגן על הפרטיות שלכם. הצטרפו אל Firefox.\nlearnMore = מידע נוסף.\ndownloadFlagged = קישור זה הושבת מכיוון שהפר את תנאי השירות.\ndownloadConfirmTitle = דבר אחד אחרון\ndownloadConfirmDescription = נא לוודא שמי ששלח לך את הקובץ הזה מהימן כיוון שאין לנו אפשרות לוודא שהוא לא יפגע במכשיר שלך.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] שולח הקובץ הזה מהימן\n       *[other] שולח הקבצים האלו מהימן\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] דיווח על קובץ זה כחשוד\n       *[other] דיווח על קבצים אלו כחשודים\n    }\nreportUnknownDescription = נא לגשת אל כתובת הקישור עליו ברצונך לדווח וללחוץ על ״{ reportFile }״.\nreportButton = דיווח\nreportReasonMalware = קבצים אלה מכילים תוכנה זדונית או שהינם חלק מהתקפת דיוג.\nreportReasonAbuse = קבצים אלה מכילים תוכן בלתי חוקי או פוגע.\nreportReasonCopyright = כדי לדווח על הפרה של זכויות יוצרים או סימני מסחר, יש להשתמש בתהליך המתואר ב<a>דף זה</a>.\nreportedTitle = קבצים שדווחו\nreportedDescription = תודה. קיבלנו את הדיווח שלך על קבצים אלה.\n"
  },
  {
    "path": "public/locales/hr/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Uvoz…\nencryptingFile = Šifriranje …\ndecryptingFile = Dešifriranje …\ndownloadCount =\n    { $num ->\n        [one] { $num } preuzimanje\n        [few] { $num } preuzimanja\n       *[other] { $num } preuzimanja\n    }\ntimespanHours =\n    { $num ->\n        [one] { $num } sat\n        [few] { $num } sata\n       *[other] { $num } sati\n    }\ncopiedUrl = Kopirano!\nunlockInputPlaceholder = Lozinka\nunlockButtonLabel = Otključaj\ndownloadButtonLabel = Preuzmi\ndownloadFinish = Preuzimanje je završeno.\nfileSizeProgress = ({ $partialSize } od { $totalSize })\nsendYourFilesLink = Isprobaj Send\nerrorPageHeader = Dogodila se neka greška!\nfileTooBig = Datoteka je prevelika za prijenos. Mora biti manja od { $size }.\nlinkExpiredAlt = Poveznica je istekla\nnotSupportedHeader = Tvoj preglednik nije podržan.\nnotSupportedLink = Zašto moj preglednik nije podržan?\nnotSupportedOutdatedDetail = Nažalost, ovo izdanje Firefoxa ne podržava web tehnologiju koja omogućava Send. Morat ćeš ažurirati preglednik.\nupdateFirefox = Ažuriraj Firefox\ndeletePopupCancel = Odustani\ndeleteButtonHover = Obriši\nfooterLinkLegal = Pravni podaci\nfooterLinkPrivacy = Privatnost\nfooterLinkCookies = Kolačići\npasswordTryAgain = Netočna lozinka. Pokušaj ponovo.\njavascriptRequired = Za Send potreban je JavaScript\nwhyJavascript = Zašto je za Send potreban JavaScript?\nenableJavascript = Aktiviraj JavaScript i pokušaj ponovo.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }s { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }min\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maksimalna duljina lozinke: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Lozinku nije moguće postaviti\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Jednostavno i privatno dijeljenje datoteka\nintroDescription = { -send-brand } omogućava dijeljenje datoteka sa šifriranjem i poveznicom koja će automatski isteći. Ovim putem, stvari koje dijeliš ostaju privatne i osiguravaš se da ne ostaju zauvijek dostupne na internetu.\nnotifyUploadEncryptDone = Tvoja je datoteka šifrirana i spremna za slanje.\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Isteći će nakon { $downloadCount } ili { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] { $num } minuta\n        [few] { $num } minute\n       *[other] { $num } minuta\n    }\ntimespanDays =\n    { $num ->\n        [one] { $num } dan\n        [few] { $num } dana\n       *[other] { $num } dana\n    }\ntimespanWeeks =\n    { $num ->\n        [one] { $num } tjedan\n        [few] { $num } tjedna\n       *[other] { $num } tjedana\n    }\nfileCount =\n    { $num ->\n        [one] { $num } datoteka\n        [few] { $num } datoteke\n       *[other] { $num } datoteka\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Ukupna veličina: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopiraj poveznicu za dijeljenje svoje datoteke:\ncopyLinkButton = Kopiraj poveznicu\ndownloadTitle = Preuzmi datoteke\ndownloadDescription = Ova se datoteka dijelila putem usluge { -send-brand } sa šifriranjem i poveznicom koja će automatski isteći.\ntrySendDescription = Probaj { -send-brand } za jednostavno i sigurno dijeljenje datoteka.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Istovremeno se može prenijeti samo { $count } datoteka.\n        [few] Istovremeno se može prenijeti samo { $count } datoteke.\n       *[other] Istovremeno se može prenijeti samo { $count } datoteka.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Dozvoljena je samo { $count } arhiva.\n        [few] Dozvoljene su samo { $count } arhive.\n       *[other] Dozvoljeno je samo { $count } arhiva.\n    }\nexpiredTitle = Poveznica je istekla.\nnotSupportedDescription = { -send-brand } neće raditi s ovim preglednikom. { -send-short-brand } najbolje radi sa zadnjom { -firefox } verzijom i radit će s aktualnim verzijama većine preglednika.\ndownloadFirefox = Preuzmi { -firefox }\nlegalTitle = { -send-short-brand } politika privatnosti\nlegalDateStamp = Verzija 1.0, od 12. ožujka 2019. godine\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }s { $minutes }m\naddFilesButton = Odaberi datoteke za prijenos\ntrustWarningMessage = Budite sigurni da vjerujete primatelju prije dijeljenja osjetljivih podataka.\nuploadButton = Prijenos\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Povuci i ispusti datoteke\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = ili pritisni gumb, za slanje do { $size }\naddPassword = Zaštiti s lozinkom\nemailPlaceholder = Upiši svoju e-adresu\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Prijavi se, za slanje do { $size }\nsignInOnlyButton = Prijavi se\naccountBenefitTitle = Otvori { -firefox } račun ili se prijavi\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Dijeli datoteke do { $size }\naccountBenefitDownloadCount = Dijeli datoteke s više osoba\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Ostavi poveznice aktivnima { $count } dan\n        [few] Ostavi poveznice aktivnima { $count } dana\n       *[other] Ostavi poveznice aktivnima { $count } dana\n    }\naccountBenefitSync = Upravljaj dijeljenim datotekama s bilo kojeg uređaja\naccountBenefitMoz = Saznaj više o drugim { -mozilla } uslugama\nsignOut = Odjavi se\nokButton = U redu\ndownloadingTitle = Preuzimanje\nnoStreamsWarning = Ovaj preglednik možda neće moći dešifrirati datoteku ove veličine.\nnoStreamsOptionCopy = Za otvaranje u drugom pregledniku, kopiraj poveznicu\nnoStreamsOptionFirefox = Isprobaj naš omiljeni preglednik\nnoStreamsOptionDownload = Nastavi s ovim preglednikom\ndownloadFirefoxPromo = Potpuno novi { -firefox } donosi { -send-short-brand }.\n# the next line after the colon contains a file name\nshareLinkDescription = Dijeli poveznicu na tvoju datoteku:\nshareLinkButton = Dijeli poveznicu\n# $name is the name of the file\nshareMessage = Preuzmi „{ $name }” pomoću { -send-brand }: jednostavno i sigurno dijeljenje datoteka\ntrailheadPromo = Postoji način, kako zaštititi vlastitu privatnost. Pridruži se Firefoxu.\nlearnMore = Saznaj više.\ndownloadFlagged = Poveznica je onemogućena zbog kršenja uvjeta pružanja usluge.\ndownloadConfirmTitle = Još jedna stvar\ndownloadConfirmDescription = Budite sigurni da vjerujete osobi koja vam je poslala ovu datoteku, zato što mi ne možemo provjeriti da li će ova datoteka naštetiti vašem uređaju.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Vjerujem osobi koja je poslala ove datoteke\n        [few] Vjerujem osobi koja je poslala ove datoteke\n       *[other] Vjerujem osobi koja je poslala ove datoteke\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Prijavi ove datoteke kao sumnjive\n        [few] Prijavi ove datoteke kao sumnjive\n       *[other] Prijavi ove datoteke kao sumnjive\n    }\nreportDescription = Pomozite nam da shvatimo što se dešava. Zašto mislite da nešto nije u redu s ovim datotekama?\nreportUnknownDescription = Idite na poveznicu koju želite prijaviti i kliknite  “{ reportFile }”.\nreportButton = Prijavi datoteku\nreportReasonMalware = Ove datoteke sadrže zlonamjerni softver ili su dio napada za krađu identiteta.\nreportReasonPii = Ove datoteke sadrže moje osobne podatke.\nreportReasonAbuse = Ove datoteke sadrže ilegalni ili nasilni sadržaj.\nreportReasonCopyright = Kako biste prijavili kršenje autorskih prava, koristite proces opisan na <a>ovoj stranici</a>.\nreportedTitle = Datoteke prijavljene\nreportedDescription = Hvala vam. Primili smo vašu prijavu za ove datoteke.\n"
  },
  {
    "path": "public/locales/hsb/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importuje so...\nencryptingFile = Zaklučuje so...\ndecryptingFile = Dešifruje so...\ndownloadCount =\n    { $num ->\n        [one] 1 sćehnjenje\n        [two] { $num } sćehnjeni\n        [few] { $num } sćehnjenja\n       *[other] { $num } sćehnjenjow\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hodźina\n        [two] { $num } hodźinje\n        [few] { $num } hodźiny\n       *[other] { $num } hodźin\n    }\ncopiedUrl = Kopěrowany!\nunlockInputPlaceholder = Hesło\nunlockButtonLabel = Wotewrěć\ndownloadButtonLabel = Sćahnyć\ndownloadFinish = Sćehnjenje dokónčene\nfileSizeProgress = ({ $partialSize } z { $totalSize })\nsendYourFilesLink = Send wupruwować\nerrorPageHeader = Něšto je so nimokuliło!\nfileTooBig = Tuta dataja je přewulka za nahraće. Měła mjeńša hač { $size } być.\nlinkExpiredAlt = Wotkaz je spadnjeny\nnotSupportedHeader = Waš wobhladowak so njepodpěruje.\nnotSupportedLink = Čehodla so mój wobhladowak njepodpěruje?\nnotSupportedOutdatedDetail = Bohužel tuta wersija Firefox webtechnologiju njepodpěruje, na kotrejž Send bazuje. Dyrbiće swój wobhladowak aktualizować.\nupdateFirefox = Firefox aktualizować\ndeletePopupCancel = Přetorhnyć\ndeleteButtonHover = Zhašeć\nfooterLinkLegal = Prawniske\nfooterLinkPrivacy = Priwatnosć\nfooterLinkCookies = Placki\npasswordTryAgain = Wopačne hesło. Prošu spytajće hišće raz.\njavascriptRequired = Send JavaScript trjeba\nwhyJavascript = Čehodla Send JavaScript trjeba?\nenableJavascript = Prošu zmóžńće JavaScript a spytajće hišće raz.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } hodź. { $minutes } mjeń.\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } mjeń.\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maksimalna dołhosć hesła: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Tute hesło njeda so nastajić\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Jednore, priwatne datajowe dźělenje\nintroDescription = { -send-brand } wam zmóžnja, dataje ze zaklučowanjom kónc do kónca a wotkazom dźělić, kotryž awtomatisce spadnje. Tak móžeće dźěleny wobsah priwatny dźeržeć a zawěsćić, zo waše daty online na přeco njewóstanu.\nnotifyUploadEncryptDone = Waša dataja je zaklučowana a hotowa za słanje\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Spadnje po { $downloadCount } abo { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] { $num } mjeńšina\n        [two] { $num } mjeńšinje\n        [few] { $num } mjeńšiny\n       *[other] { $num } mjeńšin\n    }\ntimespanDays =\n    { $num ->\n        [one] { $num } dźeń\n        [two] { $num } dnjej\n        [few] { $num } dny\n       *[other] { $num } dnjow\n    }\ntimespanWeeks =\n    { $num ->\n        [one] { $num } tydźeń\n        [two] { $num } njedźeli\n        [few] { $num } njedźele\n       *[other] { $num } njedźel\n    }\nfileCount =\n    { $num ->\n        [one] { $num } dataja\n        [two] { $num } dataji\n        [few] { $num } dataje\n       *[other] { $num } datajow\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Cyłkowna wulkosć: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopěrujće wotkaz, zo byšće swoju dataju dźělił:\ncopyLinkButton = Wotkaz kopěrować\ndownloadTitle = Dataje sćahnyć\ndownloadDescription = Tuta dataja je so přez { -send-brand } ze zaklučowanjom kónc do kónca a wotkazom dźěliła, kotryž awtomatisce spadnje.\ntrySendDescription = Spytajće { -send-brand } za jednore, wěste datajowe dźělenje.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Jenož { $count } dataja da so na jedne dobo nahrać.\n        [two] Jenož { $count } dataji datej so na jedne dobo nahrać.\n        [few] Jenož { $count } dataje dadźa so na jedne dobo nahrać.\n       *[other] Jenož { $count } datajow da so na jedne dobo nahrać.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Jenož { $count } archiw je dowoleny.\n        [two] Jenož { $count } archiwaj stej dowolenej.\n        [few] Jenož { $count } archiwy su dowolene.\n       *[other] Jenož { $count } archiwow je dowolene.\n    }\nexpiredTitle = Tutón wotkaz je spadnjeny.\nnotSupportedDescription = { -send-brand } z tutym wobhladowakom njefunguje. { -send-short-brand } najlěpje z najnowšej wersiju { -firefox } funguje, a funguje z aktualnej wersiju najwjace wobhladowakow.\ndownloadFirefox = { -firefox } scáhnyć\nlegalTitle = Zdźělenka priwatnosće { -send-short-brand }\nlegalDateStamp = Wersija 1.0 wot 12. měrca 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Dataje za nahrawanje wubrać\ntrustWarningMessage = Wy měł přijimarjej dowěrić, hdyž sensibelne daty dźěliće.\nuploadButton = Nahrać\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Ćehńće a wotkładźće dataje\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = abo klikńće, zo byšće do { $size } pósłał\naddPassword = Z hesłom škitać\nemailPlaceholder = Zapodajće swoju e-mejlowu adresu\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Přizjewće so, zo byšće do { $size } pósłał\nsignInOnlyButton = Přizjewić\naccountBenefitTitle = Załožće konto { -firefox } abo přizjewće so\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Dataje do { $size } dźělić\naccountBenefitDownloadCount = Dataje z wjace ludźimi dźělić\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Wotkazy do { $count } dnja aktiwne dźeržeć\n        [two] Wotkazy do { $count } dnjow aktiwne dźeržeć\n        [few] Wotkazy do { $count } dnjow aktiwne dźeržeć\n       *[other] Wotkazy do { $count } dnjow aktiwne dźeržeć\n    }\naccountBenefitSync = Dźělene dataje z někajkeho grata rjadować\naccountBenefitMoz = ZHońće wjace wo druhich słužbach { -mozilla }\nsignOut = Wotzjewić\nokButton = W porjadku\ndownloadingTitle = Sćahuje so\nnoStreamsWarning = Tutón wobhladowak njemóhł tajku wulku dataju dešifrować.\nnoStreamsOptionCopy = Kopěrujće wotkaz, zo byšće jón w druhim wobhladowaku wočinił\nnoStreamsOptionFirefox = Wupruwujće naš najlubši wobhladowak\nnoStreamsOptionDownload = Z tutym wobhladowakom pokročować\ndownloadFirefoxPromo = { -send-short-brand } so wam přez cyle nowy { -firefox } přinjese.\n# the next line after the colon contains a file name\nshareLinkDescription = Dźělće wotkaz k swojej dataji:\nshareLinkButton = Wotkaz dźělić\n# $name is the name of the file\nshareMessage = Sćehńće „{ $name }“ z { -send-brand }: jednore, wěste dźělenje datajow\ntrailheadPromo = Je móžnosć, wašu priwatnosć škitać. Přińdźće k Firefox.\nlearnMore = Dalše informacije.\ndownloadFlagged = Tutón wotkaz je so přestupjenja wužiwanskich wuměnjenjow dla znjemóžnił.\ndownloadConfirmTitle = Jedna wěc hišće\ndownloadConfirmDescription = Wy měł wotpósłarjej tuteje dataje dowěrić, dokelž njemóžemy přepruwować, hač to wašemu gratej wadźi.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Dowěrju wosobje, kotraž je tutu dataju pósłała\n        [two] Dowěrju wosobje, kotraž je tutej dataji pósłała\n        [few] Dowěrju wosobje, kotraž je tute dataje pósłała\n       *[other] Dowěrju wosobje, kotraž je tute dataje pósłała\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Tutu dataju jako podhladnu zdźělić\n        [two] Tutej dataji jako podhladnej zdźělić\n        [few] Tute dataje jako podhladne zdźělić\n       *[other] Tute dataje jako podhladne zdźělić\n    }\nreportDescription = Pomhajće nam rozumić, što so stawa. Što po wašim zdaću z tutymi datajemi w porjadku njeje?\nreportUnknownDescription = Dźiće prošu k URL wotkaza, kotryž chceće zdźělić a klikńće na „{ reportFile }“.\nreportButton = Zdźělić\nreportReasonMalware = Tute dataje škódnu softwaru wobsahuja abo su dźěl nadpada kradnjenja datow.\nreportReasonPii = Tute dataje wosobinske informacije wo mni, kotrež móža mje identifikować.\nreportReasonAbuse = Tute dataje njedowoleny abo ranjacy wobsah wobsahuja.\nreportReasonCopyright = Zo byšće zranjenje awtorskeho prawa abo prawa wikowanskich znamjenjow zdźělił, wužiwajće postupowanje, kotrež so na <a>tutej stronje</a> wopisuje.\nreportedTitle = Dataje su zdźělene\nreportedDescription = Wulki dźak. Smy wašu rozprawu wo tutych datajach dóstali.\n"
  },
  {
    "path": "public/locales/hu/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importálás…\nencryptingFile = Titkosítás…\ndecryptingFile = Visszafejtés…\ndownloadCount =\n    { $num ->\n        [one] 1 letöltés\n       *[other] { $num } letöltés\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 óra\n       *[other] { $num }  óra\n    }\ncopiedUrl = Másolva!\nunlockInputPlaceholder = Jelszó\nunlockButtonLabel = Feloldás\ndownloadButtonLabel = Letöltés\ndownloadFinish = A letöltés befejeződött\nfileSizeProgress = ({ $partialSize } / { $totalSize })\nsendYourFilesLink = Próbálja ki a Sendet\nerrorPageHeader = Hiba történt!\nfileTooBig = Ez a fájl túl nagy a feltöltéshez. Kevesebb mint { $size } kell legyen.\nlinkExpiredAlt = A hivatkozás lejárt\nnotSupportedHeader = A böngésző nem támogatott.\nnotSupportedLink = Miért nem támogatott a böngészőm?\nnotSupportedOutdatedDetail = Sajnos a Firefox ezen verziója nem támogatja a Send alapját képező technológiát. Frissítenie kell a böngészőjét.\nupdateFirefox = Firefox frissítése\ndeletePopupCancel = Mégse\ndeleteButtonHover = Törlés\nfooterLinkLegal = Jogi információk\nfooterLinkPrivacy = Adatvédelem\nfooterLinkCookies = Sütik\npasswordTryAgain = Helytelen jelszó. Próbálja meg újra.\njavascriptRequired = A Sendhez JavaScript szükséges\nwhyJavascript = Miért van szükség JavaScriptre a Sendhez?\nenableJavascript = Kérjük engedélyezze a JavaScriptet, majd próbálkozzon újra.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }ó { $minutes }p\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }p\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maximális jelszóhossz: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Ez a jelszó nem állítható be\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Egyszerű, privát fájlmegosztás\nintroDescription = A { -send-brand }del végpontok közötti titkosítással oszthat meg fájlokat, a hivatkozások pedig automatikusan lejárnak. Így bizalmasan tarthatja azt, amit megoszt, és biztosíthatja, hogy a dolgok nem maradnak örökre online.\nnotifyUploadEncryptDone = A fájl titkosítva és készen áll a küldésre\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = { $downloadCount } vagy { $timespan } után elévül\ntimespanMinutes =\n    { $num ->\n        [one] 1 perc\n       *[other] { $num } perc\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 nap\n       *[other] { $num } nap\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 hét\n       *[other] { $num } hét\n    }\nfileCount =\n    { $num ->\n        [one] 1 fájl\n       *[other] { $num } fájl\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Teljes méret: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Másolja a hivatkozást a fájl megosztásához:\ncopyLinkButton = Hivatkozás másolása\ndownloadTitle = Fájlok letöltése\ndownloadDescription = Ez a fájl a { -send-brand } szolgáltatással lett megosztva, végpontok közötti titkosítással, és a hivatkozás automatikusan elévül.\ntrySendDescription = Próbálja ki a { -send-brand }et az egyszerű, biztonságos fájlmegosztásért.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Egyszerre csak 1 fájl tölthető fel.\n       *[other] Egyszerre csak { $count } fájl tölthető fel.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Csak 1 archívum engedélyezett.\n       *[other] Csak { $count } archívum engedélyezett.\n    }\nexpiredTitle = Ez a hivatkozás elévült.\nnotSupportedDescription = A { -send-brand } nem működik ebben a böngészőben. A { -send-short-brand } a { -firefox } legfrissebb verziójával működik a legjobban, de működik a legtöbb böngésző aktuális verziójával is.\ndownloadFirefox = A { -firefox } letöltése\nlegalTitle = { -send-short-brand } adatvédelmi nyilatkozat\nlegalDateStamp = 1.0-s verzió, kelt 2019. március 12-én\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }n { $hours }ó { $minutes }p\naddFilesButton = Válassza ki a feltöltendő fájlokat\ntrustWarningMessage = Érzékeny adatok megosztásakor győződjön meg róla, hogy megbízik-e a címzettben.\nuploadButton = Feltöltés\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Húzza ide a fájlokat\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = vagy jelentkezzen be, és küldjön legfeljebb { $size }-ot\naddPassword = Jelszavas védelem\nemailPlaceholder = Adja meg az e-mail címét\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Jelentkezzen be, és küldjön legfeljebb { $size }-ot\nsignInOnlyButton = Bejelentkezés\naccountBenefitTitle = Hozzon létre egy { -firefox } fiókot vagy jelentkezzen be\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Osszon meg fájlokat { $size }-ig\naccountBenefitDownloadCount = Osszon meg fájlokat több emberrel\naccountBenefitTimeLimit =\n    { $count ->\n        [one] A hivatkozások aktívan tartása legfeljebb 1 napig\n       *[other] A hivatkozások aktívan tartása legfeljebb { $count } napig\n    }\naccountBenefitSync = Kezelje a megosztott fájlokat bármely eszközről\naccountBenefitMoz = Ismerje meg a többi { -mozilla } szolgáltatást\nsignOut = Kijelentkezés\nokButton = OK\ndownloadingTitle = Letöltés\nnoStreamsWarning = Előfordulhat, hogy a böngésző nem fog tudni visszafejteni egy ekkora fájlt.\nnoStreamsOptionCopy = Másolja a hivatkozást, és nyissa meg egy másik böngészőben\nnoStreamsOptionFirefox = Próbálja ki a kedvenc böngészőnket\nnoStreamsOptionDownload = Folytatás ezzel a böngészővel\ndownloadFirefoxPromo = A { -send-short-brand }et a vadonatúj { -firefox } hozza el Önnek.\n# the next line after the colon contains a file name\nshareLinkDescription = Ossza meg a fájlja hivatkozását:\nshareLinkButton = Hivatkozás megosztása\n# $name is the name of the file\nshareMessage = „{ $name }” letöltése a { -send-brand } segítségével: egyszerű, biztonságos fájlmegosztás\ntrailheadPromo = Védje meg a magánszféráját. Csatlakozzon a Firefoxhoz.\nlearnMore = További tudnivalók.\ndownloadFlagged = Ezt a hivatkozást a szolgáltatási feltételek megsértése miatt letiltottuk.\ndownloadConfirmTitle = Még egy dolog\ndownloadConfirmDescription = Győződjön meg arról, hogy megbízik-e abban, aki küldte a fájlt, mert nem tudjuk ellenőrizni, hogy nem okoz-e kárt az eszközén.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Megbízom abban a személyben, aki elküldte ezt a fájlt\n       *[other] Megbízom abban a személyben, aki elküldte ezeket a fájlokat\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Fájl jelentése gyanúsként\n       *[other] Fájlok jelentése gyanúsként\n    }\nreportDescription = Segítsen megérteni, hogy mi a helyzet. Ön szerint mi a baj ezekkel a fájlokkal?\nreportUnknownDescription = Ugorjon a jelentendő hivatkozás URL-jéhez, és kattintson a „{ reportFile }” gombra.\nreportButton = Jelentés\nreportReasonMalware = Ezek a fájlok rosszindulatú programokat tartalmaznak, vagy adathalász támadás részét képezik.\nreportReasonPii = Ezek a fájlok személyesen azonosítható információkat tartalmaznak rólam.\nreportReasonAbuse = Ezek a fájlok illegális vagy visszaélésszerű tartalmúak.\nreportReasonCopyright = A szerzői jogok vagy védjegyek megsértésének jelentéséhez használja az <a>ezen az oldalon</a> írt folyamatot.\nreportedTitle = Fájlok jelentve\nreportedDescription = Köszönjük. Megkaptuk a jelentését ezekről a fájlokról.\n"
  },
  {
    "path": "public/locales/hus/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Ka olna' max jant'oj yab u t'ojnal alwa'\nimportingFile = k'wajat i chiyál...\nencryptingFile = K'wajat i tsinat dheyál...\ndecryptingFile = K'wajat i exal ki wila'...\ndownloadCount =\n    { $num ->\n       *[other] 1 pa'badh { $num } pa'badh\n    }\ntimespanHours =\n    { $num ->\n       *[other] 1 hora { $num } hora\n    }\ncopiedUrl = Letsbadh...\nunlockInputPlaceholder = Tsinat japixtal\nunlockButtonLabel = Ka japiy\ndownloadButtonLabel = Ka pa'ba'\ndownloadFinish = Tala' pa'iyits\nfileSizeProgress = { $partialSize } xi ti { $totalSize }\nsendYourFilesLink = Ka eyendha' Send\nerrorPageHeader = ¡Yab kalej alwa'!\nfileTooBig = Tekedh pulik axi a le' ka kadh'ba', kwa'al kin alemna' { $size }\nlinkExpiredAlt = Yabats u awil ki ela'\nnotSupportedHeader = Yab u awil ka japiyat k'al axi NAVEGADOR\nnotSupportedLink = ¿Jale' ti u NAVEGADOR yab in japiyal?\nnotSupportedOutdatedDetail = Yab u awil ka eyendha' Send kom an NAVEGADOR Firefox biyalits. Ka Pa'ba' axi it.\nupdateFirefox = Ka itmedha' Firefox\ndeletePopupCancel = Ka kuba'\ndeleteButtonHover = Ka pakuw\nfooterLinkLegal = Axi walkadh ka t'ajan\nfooterLinkPrivacy = Tsinataláb\nfooterLinkCookies = Cookies\npasswordTryAgain = Yab ja' an tsinat japixtaláb. Ka exa' junil.\njavascriptRequired = Send in yejenchal JavaScript\nwhyJavascript = ¿Jale' Send in yejenchal JavaScript?\nenableJavascript = Ka lek'wtsiy JavaScript ani ka exa' junil.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = In puwél an tsinat japixtaláb pel: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Axi tsinat japixtaláb yab u awil ka eyendha'\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Yab k'ibat, a tsinat t'ojlabil u awil ka buk'uw\nintroDescription = { -send-brand } in t'ajál abal ka buk'uw a t'ojlabil po axé' tsinat abal an atikláb axi tat yab a le' kin tsu'uw yab kin ejtow, aniyej an enlace abal ka pa'ba' an t'ojláb u talél kwetém. Antsan patal axi ka abna' u awil ka buk'uw tsinat ani antsan jayej axi ka buk'uw yab u jilk'onal ets'ey ti ébtsolom (internet).\nnotifyUploadEncryptDone = A t'ojlabil xo' tsinadhits ani u awilits ka abna'\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Ne'ets ka taliy ti { $downloadCount } o ti { $timespan }\ntimespanMinutes =\n    { $num ->\n       *[other] 1 minuto { $num }\n    }\ntimespanDays =\n    { $num ->\n       *[other] 1 k'icháj { $num } k'ichajchik\n    }\ntimespanWeeks =\n    { $num ->\n       *[other] 1 semana { $num } i semanachik\n    }\nfileCount =\n    { $num ->\n       *[other] 1 t'ojláb { $num } t'ojlabchik\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = In puwél an t'ojláb: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Ka k'ot'biy an enlace abal ka ejtow ka buk'uw a t'ojlabil:\ncopyLinkButton = ka k'ot'biy an enlace\ndownloadTitle = Ka pa'ba' an t'ojláb\ndownloadDescription = Axi t'ojláb aban k'al in tolmixtal an { -send-brand } ani tsinat, aniyej in tsap an enlace u talél kwetém.\ntrySendDescription = Ka eyendha' { -send-brand } abal ka abna' a t'ojlabil, yab k'ibat ani k'anidh.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n       *[other]\n            Expidh u awil ka k'adhba' 1 i t'ojláb \n            Expidh u awil ka k'adhba' { $count } i t'ojláb.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n       *[other]\n            Expidh u awil 1 i t'ojláb.\n            Expidh u awil { $count } i t'ojláb.\n    }\nexpiredTitle = An enlace talíts in tsap.\nnotSupportedDescription = { -send-brand } yab u t'ojnal al axi navegador. { -send-short-brand } u t'ojnal alwa' k'al an { -firefox } axi it, ani ne'ets ka t'ojon alwa' k'al an it navegadorchik.\ndownloadFirefox = Ka pa'ba' { -firefox }\nlegalTitle = Tin kwentaj an \"Tsinaxtaláb a k'al\" { -send-short-brand }\nlegalDateStamp = Versión 1.0 ani t'ajadh ti Marzo 12 ti tamub 2019.\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } k'icháj { $hours } hora { $minutes } minuto\naddFilesButton = Ka takuy an t'ojláb axi ne'ets ka k'adhba'\nuploadButton = Ka k'adhba'\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Ka kina' a t'ojlabil ani ka walka' te'\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = o ka t'aja' an clic abal ka abna' ma { $size }\naddPassword = Ka k'aniy k'al jún i tsinat japixtaláb\nemailPlaceholder = Ka punuw a abnax dhuchlab Correo Electrónico.\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Kit otsits abal ka ejtow ka abna' ma { $size }\nsignInOnlyButton = Kit otsits\naccountBenefitTitle = Ka ts'ejka' jún a it k'al (cuenta) { -firefox } o kit otsits max a kwa'alits jún.\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Ka buk'uw a t'ojlabil, ma { $size }\naccountBenefitDownloadCount = Ka buk'uw a t'ojlabil k'al pil i atiklabchik\naccountBenefitTimeLimit =\n    { $count ->\n       *[other]\n            Ka ko'oy an enlace ma 1 a k'icháj\n            Ka ko'oy an enlacechik ma { $count } a k'icháhchik\n    }\naccountBenefitSync = Ka ejtow tit t'ojnal k'al t'ojlabil al jawakitsk'ij tum eyendhabnél\naccountBenefitMoz = Ka exla' jant'oj ti pidhál { -mozilla }\nsignOut = Kit kalej\nokButton = Ka bats'uw\ndownloadingTitle = K'wajat ti pa'íl\nnoStreamsWarning = Walám axi navegador yab ne'ets kin ejtow kin japiy jún i t'ojláb tekedh pulik.\nnoStreamsOptionCopy = Ka k'ot'biy an enlace abal ka japiy al pil i navegador\nnoStreamsOptionFirefox = Ka eyendha' i navegador\nnoStreamsOptionDownload = yab kit kalej al axi navegador\ndownloadFirefoxPromo = An it { -firefox } ti pidhál { -send-short-brand }\n# the next line after the colon contains a file name\nshareLinkDescription = Ka abna' an enlace al an eyendhanél:\nshareLinkButton = Ka abna' an enlace\n# $name is the name of the file\nshareMessage = Ka pa'ba' “{ $name }” k'al { -send-brand }: ka abna' a t'ojlabil, yab k'ibat ani k'anidh\ntrailheadPromo = U awil ka k'aniy axi tat a k'al. Kit tamkun k'al Firefox.\nlearnMore = Ka ajiy más.\n"
  },
  {
    "path": "public/locales/hy-AM/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Արձագանք\nimportingFile = Ներմուծում...\nencryptingFile = Գաղտնագրում…\ndecryptingFile = Վերծանում…\ndownloadCount =\n    { $num ->\n        [one] 1 ներբեռնում\n       *[other] { $num } ներբեռնումներ\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 ժամ\n       *[other] { $num } ժամ\n    }\ncopiedUrl = Պատճենված\nunlockInputPlaceholder = Գաղտնաբառ\nunlockButtonLabel = Ապակողպել\ndownloadButtonLabel = Ներբեռնել\ndownloadFinish = Ներբեռնումն ավարտված է\nfileSizeProgress = ({ $partialSize }-ը { $totalSize })-ից\nsendYourFilesLink = Փորձել Send-ը\nerrorPageHeader = Ինչ-որ բան այն չէ\nfileTooBig = Այդ ֆայլը չափազանց մեծ է վերբեռնելու համար: Այն պետք է լինի ավելի քիչ, քան { $size }-ը\nlinkExpiredAlt = Հղումն ավարտված է\nnotSupportedHeader = Ձեր զննարկիչը չի աջակցվում:\nnotSupportedLink = Ինչու իմ զննարկիչը չի աջակցվում:\nnotSupportedOutdatedDetail = Դժբախտաբար, Firefox- ի այս տարբերակը չի աջակցում այն վեբ տեխնոլոգիան, որը պետք է Send-ի համար: Դուք պետք է թարմացնեք ձեր զննարկիչը:\nupdateFirefox = Թարմացնել Firefox-ը\ndeletePopupCancel = Չեղարկել\ndeleteButtonHover = Ջնջել\nfooterLinkLegal = Իրավական\nfooterLinkPrivacy = Գաղտնիություն\nfooterLinkCookies = Cookie-ներ\npasswordTryAgain = Սխալ գաղտնաբառ. Կրկին փորձեք:\njavascriptRequired = Send-ը պահանջում է JavaScript\nwhyJavascript = Ինչո՞ւ է Send-ը պահանջում JavaScript.\nenableJavascript = Խնդրում ենք միացնել JavaScript-ը և կրկին փորձել:\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }ժ { $minutes }ր\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }ր\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Գանղտնաբառի առավելագույն չափ. { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Այս գաղտնաբառը հնարավոր չէ սահմանել\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Ուղարկել\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Պարզ, մասնավոր ֆայլերի փոխանակում\nintroDescription = { -send-brand }-ը թույլ է տալիս փոխանակել ֆայլեր ծայրից ծայր գաղտնագրման միջոցով և այնպիսի հղում, որն ինքնաբերաբար ավարտվում է: Այսպիսով, դուք կարող եք վերահսկել այն, ինչով կիսվում եք և համոզված լինեք, որ ձեր նյութերը հավերժ չեն մնա առցանց:\nnotifyUploadEncryptDone = Ձեր ֆայլը գաղտնագրված է և պատրաստ է ուղարկել\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Ավարտվելու է { $downloadCount }-ից կամ { $timespan }-ից\ntimespanMinutes =\n    { $num ->\n        [one] 1 րոպե\n       *[other] { $num } րոպե\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 օր\n       *[other] { $num } օր\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 շաբաթ\n       *[other] { $num } շաբաթ\n    }\nfileCount =\n    { $num ->\n        [one] 1 ֆայլ\n       *[other] { $num } ֆայլեր\n    }\n# byte abbreviation\nbytes = Բ\n# kibibyte abbreviation\nkb = ԿԲ\n# mebibyte abbreviation\nmb = ՄԲ\n# gibibyte abbreviation\ngb = ԳԲ\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Ընդհանուր չափ՝ { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Պատճենեք հղումը՝ ֆայլը համօգտագործելու համար.\ncopyLinkButton = Պատճենել հղումը\ndownloadTitle = Ներբեռնել ֆայլերը\ndownloadDescription = Հայլը համօգտագործվել է { -send-brand }-ի միջոցով ՝ ծայրից ծայր գաղտնագրմամբ և ինքնաբերաբար ավարտվող հղմամբ:\ntrySendDescription = Փորձեք { -send-brand }-ը՝ ֆայլերի պարզ և անվտանգ փոխանակման համար:\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Միաժամանակ միայն 1 ֆայլ կարող է վերբեռնվել:\n       *[other] Միաժամանակ միայն { $count } ֆայլեր կարող են վերբեռնվել:\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Միայն 1 արխիվ է թույլատրված:\n       *[other] Միայն { $count } արխիվներ են թույլատրված:\n    }\nexpiredTitle = Այս հղումն ավարտված է:\nnotSupportedDescription = { -send-brand }-ը չի աշխատի այս զննարկչի հետ: { -send-short-brand }-ը լավագույն կերպով աշխատում է { -firefox }-ի վերջին տարբերակի հետ և կաշխատի զննարկիչների մեծամասնության վերջին տարբերակների հետ:\ndownloadFirefox = Ներբեռնել { -firefox }-ը\nlegalTitle = { -send-short-brand }-ի Գաղտնիության ծանուցում\nlegalDateStamp = Տարբերակ 1.0, թվագրված՝ 2019 թ. մարտի 12-ով\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }օր { $hours }ժ { $minutes }ր\naddFilesButton = Ընտրեք ֆայլեր՝ վերբեռնելու համար\nuploadButton = Վերբեռնել\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Քաշեք և գցեք ֆայլերը\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = կամ կտտացրեք`ուղարկելու համար մինչև { $size }\naddPassword = Պաշտպանեք գաղտնաբառով\nemailPlaceholder = Մուտքագրեք ձեր էլ. փոստը\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Մուտք գործեք՝ { $size } ուղարկելու համար\nsignInOnlyButton = Մուտք գործել\naccountBenefitTitle = Ստեղծեք { -firefox } հաշիվ կամ մուտք գործեք\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Կիսվեք մինչև { $size } ֆայլերով\naccountBenefitDownloadCount = Կիսվեք ֆայլերով ավելի շատ մարդկանց հետ\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Հղումներն ակտիվ պահել մինչև 1 օր\n       *[other] Հղումներն ակտիվ պահել մինչև { $count } օր\n    }\naccountBenefitSync = Կառավարեք համօգտագործվող ֆայլերը ցանկացած սարքից\naccountBenefitMoz = Իմացեք { -mozilla }-ի այլ ծառայությունների մասին\nsignOut = Դուրս գրվել\nokButton = Լավ\ndownloadingTitle = Ներբեռնվում է\nnoStreamsWarning = Այս զննարկիչը չի կարողանա վերծանել այսպիսի մեծ ֆայլը\nnoStreamsOptionCopy = Պատճենեք հղումը`այլ զննարկիչում բացելու համար\nnoStreamsOptionFirefox = Փորձեք մեր սիրած զննարկիչը\nnoStreamsOptionDownload = Շարունակեք այս զննարկիչով\ndownloadFirefoxPromo = { -send-short-brand }-ը ձեզ է առաջարկում ամբողջովին նոր { -firefox }:\n# the next line after the colon contains a file name\nshareLinkDescription = Կիսվեք ձեր ֆայլի հղումով.\nshareLinkButton = Համօգտագործել հղումը\n# $name is the name of the file\nshareMessage = Ներբեռնեք “{ $name }”-ը { -send-brand }-ով ՝ պարզ և ապահով՝ ֆայլերի համօգտագործում\ntrailheadPromo = Ձեր գաղտնիությունը պաշտպանելու միջոց կա: Միացեք Firefox- ին:\nlearnMore = Իմանալ ավելին\n"
  },
  {
    "path": "public/locales/ia/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importation…\nencryptingFile = Cryptation...\ndecryptingFile = Decryptation…\ndownloadCount =\n    { $num ->\n        [one] { $num } discargamento\n       *[other] { $num } discargamentos\n    }\ntimespanHours =\n    { $num ->\n        [one] { $num } hora\n       *[other] { $num } horas\n    }\ncopiedUrl = Copiate!\nunlockInputPlaceholder = Contrasigno\nunlockButtonLabel = Disblocar\ndownloadButtonLabel = Discargar\ndownloadFinish = Discargamento completate\nfileSizeProgress = ({ $partialSize } de { $totalSize })\nsendYourFilesLink = Proba Send\nerrorPageHeader = Un error occurreva!\nfileTooBig = Iste file es troppo grande pro incargar. Illo debe esser inferior a { $size }.\nlinkExpiredAlt = Ligamine expirate\nnotSupportedHeader = Tu navigator non es supportate\nnotSupportedLink = Proque non es mi navigator supportate?\nnotSupportedOutdatedDetail = Infelicemente iste version de Firefox non supporta le nove technologia web que actiona Send. Tu debe actualisar tu navigator.\nupdateFirefox = Actualisar Firefox\ndeletePopupCancel = Cancellar\ndeleteButtonHover = Deler\nfooterLinkLegal = Legal\nfooterLinkPrivacy = Confidentialitate\nfooterLinkCookies = Cookies\npasswordTryAgain = Contrasigno incorrecte. Retenta.\njavascriptRequired = Send require JavaScript\nwhyJavascript = Proque Send require JavaScript?\nenableJavascript = Por favor activa JavaScript e tenta novemente.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maxime longor del contrasigno: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Iste contrasigno non ha potite esser establite\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Comparti file in maniera confidential\nintroDescription = { -send-brand } te pone in grado de compartir files con cryptographia bilateral e un ligamine que automaticamente expira. Assi que tu pote mantener private lo que tu comparti e liberar te del anxietate que tu problema resta online per sempre.\nnotifyUploadEncryptDone = Tu file es cryptate e preste pro esser inviate\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Expira post { $downloadCount } o { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuta\n       *[other] { $num } minutas\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 die\n       *[other] { $num } dies\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 septimana\n       *[other] { $num } septimanas\n    }\nfileCount =\n    { $num ->\n        [one] 1 file\n       *[other] { $num } files\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Dimension total: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copia le ligamine pro compartir le file:\ncopyLinkButton = Copiar ligamine\ndownloadTitle = Discargar files\ndownloadDescription = Iste file era compartite via { -send-brand } con cryptographia bilateral e un ligamine que expira automaticamente.\ntrySendDescription = Prova { -send-brand } pro le compartimento de file simple e secur.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Solmente 1 file pote ser incargate al vice.\n       *[other] Solmente { $count } files pote esser incargate al vice.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Solo 1 archivo es permittite.\n       *[other] Solo { $count } archivos es permitter.\n    }\nexpiredTitle = Iste ligamine ha expirate.\nnotSupportedDescription = { -send-brand } non functionara con iste navigator. { -send-short-brand } functiona melio con le ultime version de { -firefox }, e functionara con le version actual de plure navigatores.\ndownloadFirefox = Discargar { -firefox }\nlegalTitle = Aviso de confidentialitate de { -send-short-brand }\nlegalDateStamp = Version 1.0 del 12 martio 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Selige le files a incargar\ntrustWarningMessage = Verifica que tu te fide a tu destinatario quando tu comparti datos sensibile.\nuploadButton = Incargar\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Traher e deponer files\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = o cliccar pro inviar usque { $size }\naddPassword = Proteger per contrasigno\nemailPlaceholder = Insere tu adresse de e-mail\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Aperi session pro inviar usque a { $size }\nsignInOnlyButton = Aperir session\naccountBenefitTitle = Crea un conto { -firefox } o registra te\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Comparti files usque { $size }\naccountBenefitDownloadCount = Comparti files con plus de personas\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Retene active le ligamine pro 1 die\n       *[other] Retene active le ligamine pro { $count } dies\n    }\naccountBenefitSync = Gere files compartite ab non importa qual apparato\naccountBenefitMoz = Discoperi altere servicios de { -mozilla }\nsignOut = Clauder session\nokButton = OK\ndownloadingTitle = Discargamento\nnoStreamsWarning = Es possibile que iste navigator non pote decryptar un file de iste proportiones.\nnoStreamsOptionCopy = Copiar le ligamine e aperir lo in un altere navigator\nnoStreamsOptionFirefox = Prova nostre navigator favorite\nnoStreamsOptionDownload = Continuar con iste navigator\ndownloadFirefoxPromo = { -send-short-brand } es portate a te per le novissime { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Condivide le ligamine a tu file:\nshareLinkButton = Condivide ligamine\n# $name is the name of the file\nshareMessage = Discarga “{ $name }” con { -send-brand }: condivide files in modo simple e secur\ntrailheadPromo = Il ha un via pro proteger tu confidentialitate. Junge te a Firefox!\nlearnMore = Saper plus.\ndownloadFlagged = Iste ligamine ha essite disactivate per violation del terminos de servicio.\ndownloadConfirmTitle = Un altere cosa\ndownloadConfirmDescription = Verifica que tu te fide al persona qui te inviava iste file, perque nos non pote verificar que illo non violara tu apparato.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Io me fide al persona qui inviava iste file\n       *[other] Io me fide al persona qui inviava iste files\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] reportar iste file como suspecte\n       *[other] reportar iste files como suspecte\n    }\nreportDescription = Adjuta nos a comprender lo que eveni. Que pensa tu es problematic con iste files?\nreportUnknownDescription = Va al URL del ligamine que tu desira signalar e clicca “{ reportFile }”.\nreportButton = Reportar\nreportReasonMalware = Iste files contine malware o es parte de un attacco fraudulente.\nreportReasonPii = Iste files contine informationes personal identificabile re me.\nreportReasonAbuse = Iste files contine contento illegal o abusive.\nreportReasonCopyright = Pro signalar violation de derectos de autor o marca de fabrica, usa le procedura describite a <a>iste pagina</a>.\nreportedTitle = Files reportate\nreportedDescription = Gratias. Nos ha recipite tu reporto sur iste files.\n"
  },
  {
    "path": "public/locales/id/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Mengimpor…\nencryptingFile = Mengenkripsi...\ndecryptingFile = Mendekripsi...\ndownloadCount =\n    { $num ->\n       *[other] { $num } unduhan\n    }\ntimespanHours =\n    { $num ->\n       *[other] { $num } jam\n    }\ncopiedUrl = Tersalin!\nunlockInputPlaceholder = Sandi\nunlockButtonLabel = Buka\ndownloadButtonLabel = Unduh\ndownloadFinish = Unduhan Selesai\nfileSizeProgress = ({ $partialSize } dari { $totalSize })\nsendYourFilesLink = Coba Send\nerrorPageHeader = Terjadi kesalahan!\nfileTooBig = Berkas terlalu besar untuk diunggah. Harus kurang dari { $size }.\nlinkExpiredAlt = Tautan kedaluwarsa\nnotSupportedHeader = Peramban Anda tidak mendukung.\nnotSupportedLink = Mengapa peramban saya tidak didukung?\nnotSupportedOutdatedDetail = Sayangnya Firefox versi ini tidak mendukung teknologi web yang menggerakkan Send. Anda perlu memperbarui peramban Anda.\nupdateFirefox = Perbarui Firefox\ndeletePopupCancel = Batal\ndeleteButtonHover = Hapus\nfooterLinkLegal = Legal\nfooterLinkPrivacy = Privasi\nfooterLinkCookies = Kuki\npasswordTryAgain = Sandi salah. Silakan coba lagi.\njavascriptRequired = Send membutuhkan JavaScript.\nwhyJavascript = Mengapa Send membutuhkan JavaScript?\nenableJavascript = Silakan aktifkan JavaScript dan coba lagi.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }j { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Panjang sandi maksimal: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Tidak bisa menyetel sandi ini\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Berbagi berkas dengan mudah dan privat\nintroDescription = { -send-brand } mudahkan Anda membagikan berkas dengan enkripsi ujung-ke-ujung dan tautan yang otomatis kadaluarsa. Sehingga Anda dapat menjaga apa yang Anda bagikan secara privat dan memastikan barang Anda tidak selamanya ada di daring.\nnotifyUploadEncryptDone = Berkas Anda terenkripsi dan siap untuk dikirim\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Berakhir setelah { $downloadCount } atau { $timespan }\ntimespanMinutes =\n    { $num ->\n       *[other] { $num } menit\n    }\ntimespanDays =\n    { $num ->\n       *[other] { $num } hari\n    }\ntimespanWeeks =\n    { $num ->\n       *[other] { $num } pekan\n    }\nfileCount =\n    { $num ->\n       *[other] { $num } berkas\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Total ukuran: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Salin tautan untuk membagikan berkas Anda:\ncopyLinkButton = Salin tautan\ndownloadTitle = Unduh berkas\ndownloadDescription = Berkas ini dibagikan lewat { -send-brand } dengan enkripsi ujung-ke-ujung dan tautan yang otomatis kadaluarsa.\ntrySendDescription = Coba { -send-brand } untuk berbagi berkas dengan mudah dan aman.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n       *[other] Hanya { $count } berkas dapat diunggah dalam sekali waktu.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n       *[other] Hanya { $count } arsip diperbolehkan.\n    }\nexpiredTitle = Tautan ini telah kadaluarsa.\nnotSupportedDescription = { -send-brand } tidak dapat digunakan dengan peramban ini. { -send-short-brand } bekerja maksimal dengan versi terbaru { -firefox }, dan akan bekerja dengan versi terkini mayoritas peramban.\ndownloadFirefox = Unduh { -firefox }\nlegalTitle = Pemberitahuan Privasi { -send-short-brand }\nlegalDateStamp = Versi 1.0, tertanggal 12 Maret 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }h { $hours }j { $minutes }m\naddFilesButton = Pilih berkas untuk diunggah\ntrustWarningMessage = Pastikan Anda mempercayai penerima Anda saat berbagi data sensitif.\nuploadButton = Unggah\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Seret dan jatuhkan berkas\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = atau klik untuk mengirim hingga { $size }\naddPassword = Lindungi dengan kata sandi\nemailPlaceholder = Masukkan surel Anda\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Masuk untuk dapat mengirim hingga { $size }\nsignInOnlyButton = Masuk\naccountBenefitTitle = Buat { -firefox } Account atau masuk\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Bagikan berkas hingga { $size }\naccountBenefitDownloadCount = Bagikan berkas kepada lebih banyak orang\naccountBenefitTimeLimit =\n    { $count ->\n       *[other] Buat tautan aktif selama { $count } hari\n    }\naccountBenefitSync = Kelola berkas yang dibagikan dari perangkat apa pun\naccountBenefitMoz = Pelajari tentang layanan { -mozilla } lainnya\nsignOut = Keluar\nokButton = Oke\ndownloadingTitle = Mengunduh\nnoStreamsWarning = Peramban ini mungkin tidak dapat mendekripsi berkas sebesar ini.\nnoStreamsOptionCopy = Salin tautan untuk dibuka di peramban lainnya\nnoStreamsOptionFirefox = Coba peramban favorit kami\nnoStreamsOptionDownload = Lanjutkan dengan peramban ini\ndownloadFirefoxPromo = { -send-short-brand } dipersembahkan untuk Anda oleh { -firefox } terbaru.\n# the next line after the colon contains a file name\nshareLinkDescription = Bagikan tautan ke berkas Anda:\nshareLinkButton = Bagikan tautan\n# $name is the name of the file\nshareMessage = Unduh \"{ $name }\" dengan { -send-brand }: berbagi berkas dengan sederhana dan aman\ntrailheadPromo = Ada cara untuk melindungi privasi Anda. Bergabunglah dengan Firefox.\nlearnMore = Pelajari lebih lanjut.\ndownloadFlagged = Tautan ini telah dinonaktifkan karena melanggar persyaratan layanan.\ndownloadConfirmTitle = Satu hal lagi\ndownloadConfirmDescription = Pastikan Anda memercayai orang yang mengirimi Anda file ini karena kami tidak dapat memverifikasi bahwa hal itu tidak akan merusak perangkat Anda.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n       *[other] Saya percaya orang yang mengirim file-file ini\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n       *[other] Laporkan file-file ini karena mencurigakan\n    }\nreportDescription = Bantu kami memahami apa yang sedang terjadi. Apa yang menurut Anda salah dengan file-file ini?\nreportUnknownDescription = Buka url tautan yang ingin Anda laporkan dan klik “{ reportFile }”.\nreportButton = Melaporkan\nreportReasonMalware = File-file ini mengandung malware atau merupakan bagian dari serangan phishing.\nreportReasonPii = File-file ini mengandung informasi pribadi tentang saya.\nreportReasonAbuse = File-file ini mengandung konten ilegal atau kasar.\nreportReasonCopyright = Untuk melaporkan pelanggaran hak cipta atau merek dagang, gunakan proses yang dijelaskan di <a> laman ini </a>.\nreportedTitle = File Dilaporkan\nreportedDescription = Terima kasih. Kami telah menerima laporan Anda tentang file-file ini.\n"
  },
  {
    "path": "public/locales/ig/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Firefox Zipu\nimportingFile = Mbubata…\nencryptingFile = ezoro ezo...\ndecryptingFile = Kpebie\ndownloadCount =\n    { $num ->\n        [one] ụbọchị { $num }\n       *[other] Abuọ\n    }\ntimespanHours =\n    { $num ->\n        [one] { $num } otu\n       *[other] { $num } abụọ\n    }\ncopiedUrl = edepụtachaghiri\nunlockInputPlaceholder = okwuntughe\nunlockButtonLabel = imeghe\ndownloadButtonLabel = budata\ndownloadFinish = Mbudata zuru ezu\nfileSizeProgress = ({ $partialSize } nke { $totalSize })\nsendYourFilesLink = Firefox Zipu\nerrorPageHeader = Onwere ihe na-adighi mma\nfileTooBig = Failu a ebuka ibulite. Ọ kwẹsịghi ịkalị { $size }\nlinkExpiredAlt = Njiko jedebe\nnotSupportedHeader = Adighi akwado ihe nchogharị gị\nnotSupportedLink = Gịnị kpatara na akwadoghị ihe nchọgharị m?\nnotSupportedOutdatedDetail = Ọ dị nwute na ụdị Firefox a anaghị akwado teknụzụ weebụ na-eji Firefox Zipụ. Ikwesiri imelite ihe nchọgharị gị.\nupdateFirefox = Melite Firefox\ndeletePopupCancel = Kagbuo\ndeleteButtonHover = Hichapụ\nfooterLinkLegal = n'Iwu\nfooterLinkPrivacy = nzuzo\nfooterLinkCookies = Kuki ga\npasswordTryAgain = okwuntughe ezighi ezi.Nwaa ọzọ\njavascriptRequired = Firefox Zipu chọrọ\nwhyJavascript = Kedu ihe kpatara Send jiri chọ JavaScript?\nenableJavascript = Biko họrọ JavaScript ma nwaa ọzọ\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Oke okwuntughe kachasị: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Enweghị ike ịtọ paswọọdụ a\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Zipu, Ziga\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Mfe, nkekọrịta faịlụ nkeonwe\nintroDescription = na-ahapu gị  ịkekọrịta faịlụ na izo ya na njedebe na njedebe na-akwụsị na akpaghị aka. Yabụ ị nwere ike idobe ihe ị na -eche ma hụ na ngwongwo gị agaghị adị n'ịntanetị ruo mgbe ebighi ebi.\nnotifyUploadEncryptDone = Failu gi zoro ezo ma di njikere iziga\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Ọ ga-agwu mgbe { $downloadCount } ma ọ bụ { $timespan } gasịrị\ntimespanDays =\n    { $num ->\n        [one] 1 ụbọchị\n       *[other] ụbọchị { $num }\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 izu\n       *[other] izu { $num }\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $Number } { $nkeji }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = { $nha }\n# the next line after the colon contains a file name\ncopyLinkDescription = Detuo njikọ ahụ iji kee faịlụ gị\ncopyLinkButton = Detuo njikọ\ndownloadTitle = Budata faịlụ gasi\ndownloadDescription = Nkekọrịta faịlụ a site na site na iji zoo njedebe na-njedebe yana otu njikọ na-akwụsị na-akpaghị aka.\ntrySendDescription = Gbalịa maka nyefe faịlụ dị mfe.\nexpiredTitle = Njikọ a emebiela.\nnotSupportedDescription = agaghị eji ihe nchọgharị a rụọ ọrụ. na arụ ọrụ kacha mma na ụdị nke , ọ ga-arụkwa ụdị nke ihe nchọgharị ka ugbu a.\ndownloadFirefox = Budata\nlegalTitle = Nkwupụta Nzuzo\nlegalDateStamp = 1.dị 1.0, akara ụbọchị Maachi 12, 2019\nokButton = O\n"
  },
  {
    "path": "public/locales/it/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importazione in corso…\nencryptingFile = Crittazione in corso…\ndecryptingFile = Decrittazione in corso…\ndownloadCount =\n    { $num ->\n        [one] 1 download\n       *[other] { $num } download\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 ora\n       *[other] { $num } ore\n    }\ncopiedUrl = Copiato\nunlockInputPlaceholder = Password\nunlockButtonLabel = Sblocca\ndownloadButtonLabel = Scarica\ndownloadFinish = Download completato\nfileSizeProgress = ({ $partialSize } di { $totalSize })\nsendYourFilesLink = Prova Send\nerrorPageHeader = Si è verificato un errore.\nfileTooBig = Le dimensioni di questo file sono eccessive. Dovrebbe essere inferiore a { $size }.\nlinkExpiredAlt = Link scaduto\nnotSupportedHeader = Il browser in uso non è supportato.\nnotSupportedLink = Perché questo browser non risulta supportato?\nnotSupportedOutdatedDetail = Purtroppo questa versione di Firefox non supporta le tecnologie web alla base di Send. È necessario aggiornare il browser.\nupdateFirefox = Aggiorna Firefox\ndeletePopupCancel = Annulla\ndeleteButtonHover = Elimina\nfooterLinkLegal = Note legali\nfooterLinkPrivacy = Privacy\nfooterLinkCookies = Cookie\npasswordTryAgain = Password errata, riprovare.\njavascriptRequired = Send richiede JavaScript\nwhyJavascript = Perché Send richiede JavaScript?\nenableJavascript = Attiva JavaScript e riprova.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Lunghezza massima della password: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Impossibile impostare la password\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Condividi file in modo semplice e riservato\nintroDescription = { -send-brand } permette di condividere file con crittografia end-to-end attraverso un link che scade automaticamente. In questo modo hai la garanzia che i tuoi contenuti vengano condivisi in modo riservato e non rimangano online per sempre.\nnotifyUploadEncryptDone = Il file è crittato e pronto per l’invio\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Scade dopo { $downloadCount } o tra { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuto\n       *[other] { $num } minuti\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 giorno\n       *[other] { $num } giorni\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 settimana\n       *[other] { $num } settimane\n    }\nfileCount = { $num } file\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = kB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Dimensione totale: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copia il link per condividere il file:\ncopyLinkButton = Copia link\ndownloadTitle = Scarica file\ndownloadDescription = Questo file è stato condiviso tramite { -send-brand } con crittografia end-to-end e un link che scade automaticamente.\ntrySendDescription = Prova { -send-brand } per condividere file in modo semplice e sicuro.\n# count will always be > 10\ntooManyFiles = È possibile caricare solo { $count } file alla volta.\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] È consentito solo un archivio.\n       *[other] Sono consentiti solo { $count } archivi.\n    }\nexpiredTitle = Questo link è scaduto.\nnotSupportedDescription = Non è possibile utilizzare { -send-brand } con questo browser. { -send-short-brand } funziona al meglio con l’ultima versione di { -firefox } ma è compatibile con l’ultima versione della maggior parte dei browser.\ndownloadFirefox = Scarica { -firefox }\nlegalTitle = Informativa sulla privacy di { -send-short-brand }\nlegalDateStamp = Versione 1.0 del 12 marzo 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }g { $hours }h { $minutes }m\naddFilesButton = Seleziona i file da caricare\ntrustWarningMessage = Assicurati che il destinatario sia affidabile quando condividi dati sensibili.\nuploadButton = Carica\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Trascina e rilascia i file\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = o fai clic per inviare fino a { $size }\naddPassword = Proteggi con una password\nemailPlaceholder = Inserisci il tuo indirizzo email\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Accedi per inviare fino a { $size }\nsignInOnlyButton = Accedi\naccountBenefitTitle = Crea un account { -firefox } o accedi\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Condividi file fino a { $size }\naccountBenefitDownloadCount = Condividi file con più persone\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Mantieni link attivi per 1 giorno\n       *[other] Mantieni link attivi per { $count } giorni\n    }\naccountBenefitSync = Gestisci i file condivisi da qualsiasi dispositivo\naccountBenefitMoz = Scopri altri servizi { -mozilla }\nsignOut = Disconnetti\nokButton = OK\ndownloadingTitle = Download in corso…\nnoStreamsWarning = Questo browser potrebbe non essere in grado di decrittare un file così grande.\nnoStreamsOptionCopy = Copia il link e aprilo in un altro browser\nnoStreamsOptionFirefox = Prova il nostro browser preferito\nnoStreamsOptionDownload = Continua con questo browser\ndownloadFirefoxPromo = { -send-short-brand } è offerto dal nuovissimo { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Condividi il link al tuo file:\nshareLinkButton = Condividi link\n# $name is the name of the file\nshareMessage = Scarica “{ $name }” con { -send-brand }: condivisione di file semplice e sicura\ntrailheadPromo = C’è un modo per proteggere la tua privacy. Entra in Firefox.\nlearnMore = Ulteriori informazioni.\ndownloadFlagged = Questo link è stato disattivato perché vìola i termini di servizio.\ndownloadConfirmTitle = Un’ultima cosa\ndownloadConfirmDescription = Assicurati che la persona che ti ha inviato questo file sia affidabile perché non possiamo garantire che non sia in grado di danneggiare il tuo dispositivo.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Considero affidabile la persona che ha inviato questo file\n       *[other] Considero affidabile la persona che ha inviato questi file\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Segnala questo file come sospetto\n       *[other] Segnala questi file come sospetti\n    }\nreportDescription = Aiutaci a capire che cosa è successo. Qual è il problema con questi file?\nreportUnknownDescription = Vai all’indirizzo del link che vuoi segnalare e fai clic su “{ reportFile }”.\nreportButton = Segnala\nreportReasonMalware = Questi file contengono malware o fanno parte di un attacco phishing.\nreportReasonPii = Questi file contengono informazioni personali identificabili che mi riguardano.\nreportReasonAbuse = Questi file contengono contenuti illegali o offensivi.\nreportReasonCopyright = Per segnalare violazioni del copyright o abusi di marchi registrati, utilizzare la procedura descritta in <a>questa pagina</a>.\nreportedTitle = File segnalati\nreportedDescription = Grazie, abbiamo ricevuto la tua segnalazione relativa a questi file.\n"
  },
  {
    "path": "public/locales/ixl/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Aq'a yol sti'\nimportingFile = Eq'otzan\nencryptingFile = La muj isik'lele\ndecryptingFile = Ni jaj ve't isik'lele'\ndownloadCount =\n    { $num ->\n        [one] Eq'omal ku'tzan\n       *[other] { $num } Eq'omalaj ku'tzan\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 Ch'ich'\n       *[other] { $num } Nimalaj ch'ich'\n    }\ncopiedUrl = Eesamal ivatz!\nunlockInputPlaceholder = Kach'ub'al\nunlockButtonLabel = Eesa ikach'ub'al\ndownloadButtonLabel = Eq'o ku'tzan\ndownloadFinish = Eq'o ku'tzan kaajayil\nfileSizeProgress = ({ $partialSize }tetz{ $totalSize })\nsendYourFilesLink = B'anb'e ve't u Send\nerrorPageHeader = At ma'l kam valexh kat eli!\nnotSupportedHeader = U chukb'al aq'one' ye' ni toleb'e'.\nnotSupportedLink = Kam q'ii uve' ye' kuxh ni toleb' u chukb'al vaq'one'?\nupdateFirefox = Tz'ajsa tatine' Firefox\ndeletePopupCancel = Ya'samal\ndeleteButtonHover = Sojsa\nfooterLinkPrivacy = Tetz kuxhtu'\nfooterLinkCookies = Cookies\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Aq'b'en\n-firefox = Firefox\n-mozilla = Mozilla\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\nemailPlaceholder = Aq'ku' a correo\nshareLinkButton = La jatxb'en u vaa'\nlearnMore = Ootzi ka'te.\n"
  },
  {
    "path": "public/locales/ja/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = インポート中...\nencryptingFile = 暗号化中...\ndecryptingFile = 復号化中...\ndownloadCount =\n    { $num ->\n       *[other] { $num } 回のダウンロード\n    }\ntimespanHours =\n    { $num ->\n       *[other] { $num } 時間\n    }\ncopiedUrl = コピー完了！\nunlockInputPlaceholder = パスワード\nunlockButtonLabel = ロック解除\ndownloadButtonLabel = ダウンロード\ndownloadFinish = ダウンロード完了\nfileSizeProgress = ({ $partialSize } / { $totalSize })\nsendYourFilesLink = Send を試す\nerrorPageHeader = 何か問題が発生しました。\nfileTooBig = このファイルは大きすぎるためアップロードできません。上限は { $size } です。\nlinkExpiredAlt = リンク期限切れ\nnotSupportedHeader = お使いのブラウザーには対応していません。\nnotSupportedLink = なぜ私のブラウザーには対応していないのでしょうか？\nnotSupportedOutdatedDetail = 残念ながらお使いのバージョンの Firefox は Send が活用しているウェブ技術に対応していません。ブラウザーを更新する必要があります。\nupdateFirefox = Firefox を更新\ndeletePopupCancel = キャンセル\ndeleteButtonHover = 削除\nfooterLinkLegal = 法的情報\nfooterLinkPrivacy = プライバシー\nfooterLinkCookies = Cookie\npasswordTryAgain = パスワードが正しくありません。再度入力してください。\njavascriptRequired = Send を使うには JavaScript が必要です\nwhyJavascript = Send が JavaScript を必要とする理由\nenableJavascript = JavaScript を有効にして再度試してください。\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } 時間 { $minutes } 分\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } 分\n# A short status message shown when the user enters a long password\nmaxPasswordLength = パスワード最長文字数: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = このパスワードは設定できませんでした\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = 簡単に、プライベートにファイル共有\nintroDescription = { -send-brand } では、暗号化してファイル共有でき、リンクは自動的に期限切れになります。そのため、共有するものをプライベートに保管でき、オンライン上に永遠に残さないようにできます。\nnotifyUploadEncryptDone = ファイルが暗号化され、送信する準備ができました\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = 有効期間: { $downloadCount } または { $timespan }\ntimespanMinutes =\n    { $num ->\n       *[other] { $num } 分\n    }\ntimespanDays =\n    { $num ->\n       *[other] { $num } 日\n    }\ntimespanWeeks =\n    { $num ->\n       *[other] { $num } 週間\n    }\nfileCount =\n    { $num ->\n       *[other] { $num } ファイル\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = 合計サイズ: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = リンクをコピーしてファイルを共有:\ncopyLinkButton = リンクをコピー\ndownloadTitle = ファイルをダウンロード\ndownloadDescription = このファイルは { -send-brand } により、暗号化されて共有されました。リンクは自動的に期限切れになります。\ntrySendDescription = 簡単で安全なファイル共有ができる { -send-brand } を試してください。\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n       *[other] 一度にアップロードできるのは { $count } ファイルまでです。\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n       *[other] { $count } 回までしかダウンロードできません。\n    }\nexpiredTitle = このリンクは期限切れです。\nnotSupportedDescription = { -send-brand } は、このブラウザーでは動作しません。{ -send-short-brand } は最新バージョンの { -firefox } で最もよく動作し、その他の現バージョンのブラウザーでも動作します。\ndownloadFirefox = { -firefox } をダウンロード\nlegalTitle = { -send-short-brand } プライバシー通知\nlegalDateStamp = バージョン 1.0, 2019年3月12日時点\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } 日 { $hours } 時 { $minutes } 分\naddFilesButton = アップロードするファイルを選択\ntrustWarningMessage = 機密データを共有する場合は、受信者が信頼できる相手であることを確認してください。\nuploadButton = アップロード\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = ファイルをドラッグ＆ドロップ\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = または、クリックして最大 { $size } のファイルを送信\naddPassword = パスワードで保護\nemailPlaceholder = メールアドレスを入力\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = ログインすると最大 { $size } のファイルを送信できます\nsignInOnlyButton = ログイン\naccountBenefitTitle = { -firefox } アカウントを作成またはログイン\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = 最大 { $size } までのファイルを共有\naccountBenefitDownloadCount = より多くの人とファイルを共有\naccountBenefitTimeLimit =\n    { $count ->\n       *[other] リンクを { $count } 日間有効化\n    }\naccountBenefitSync = 様々な端末から共有したファイルを管理\naccountBenefitMoz = { -mozilla } の他のサービスについて詳しく学ぶ\nsignOut = ログアウト\nokButton = OK\ndownloadingTitle = ダウンロード中\nnoStreamsWarning = このブラウザーは、この大きさのファイルを復号化できません。\nnoStreamsOptionCopy = リンクをコピーして他のブラウザーで開いてください\nnoStreamsOptionFirefox = Firefox を試してみる\nnoStreamsOptionDownload = このブラウザーで続ける\ndownloadFirefoxPromo = { -send-short-brand } はすべてが新しくなった { -firefox } により提供されています。\n# the next line after the colon contains a file name\nshareLinkDescription = ファイルへのリンクを共有しましょう:\nshareLinkButton = リンクを共有\n# $name is the name of the file\nshareMessage = { -send-brand } で \"{ $name }\" をダウンロード: シンプルで安全なファイル共有\ntrailheadPromo = プライバシーを保護する方法があります。Firefox を試してください。\nlearnMore = 詳細情報\ndownloadFlagged = サービス利用規約に違反しているため、このリンクは無効になっています。\ndownloadConfirmTitle = さらにもう一つ\ndownloadConfirmDescription = このファイルが端末に悪影響を及ぼさないことを確かめられないため、送信者が信頼できる相手であることを確認してください。\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n       *[other] ファイルの送信者を信頼します\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n       *[other] 疑わしいファイルとして報告する\n    }\nreportDescription = 詳しく調べるためにお知らせください。これらのファイルの何が問題だと思われますか？\nreportUnknownDescription = 報告したい内容のリンクの URL にアクセスし、“{ reportFile }” をクリックしてください。\nreportButton = 問題を報告\nreportReasonMalware = これらのファイルにはマルウェアが含まれているか、フィッシング詐欺攻撃の一部です。\nreportReasonPii = これらのファイルには私に関する個人情報が含まれています。\nreportReasonAbuse = これらのファイルには違法または虐待的なコンテンツが含まれています。\nreportReasonCopyright = 著作権または商標の侵害を報告するには、<a>このページ</a> に記載された手続きに従ってください。\nreportedTitle = ファイルを報告しました\nreportedDescription = ご協力ありがとうございました。これらのファイルに関する報告を受け取りました。\n"
  },
  {
    "path": "public/locales/ka/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = გადმოტანა...\nencryptingFile = დაშიფვრა...\ndecryptingFile = გაშიფვრა...\ndownloadCount =\n    { $num ->\n        [one] 1 ჩამოტვირთვა\n       *[other] { $num } ჩამოტვირთვა\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 საათი\n       *[other] { $num } საათი\n    }\ncopiedUrl = ასლი აღებულია!\nunlockInputPlaceholder = პაროლი\nunlockButtonLabel = გახსნა\ndownloadButtonLabel = ჩამოტვირთვა\ndownloadFinish = ჩამოტვირთვა დასრულდა\nfileSizeProgress = ({ $partialSize } { $totalSize }-იდან)\nsendYourFilesLink = გამოცადეთ Send\nerrorPageHeader = რაღაც ხარვეზია!\nfileTooBig = ფაილი ზედმეტად დიდია. უნდა იყოს { $size } ზომაზე ნაკლები.\nlinkExpiredAlt = ბმული ვადაგასულია\nnotSupportedHeader = თქვენი ბრაუზერი არაა მხარდაჭერილი.\nnotSupportedLink = რატომ არაა ჩემი ბრაუზერი მხარდაჭერილი?\nnotSupportedOutdatedDetail = სამწუხაროდ, Firefox-ის ამ ვერსიას არ გააჩნია ის ტექნოლოგია, რომელიც აუცილებელია Send-ის მუშაობისთვის. გესაჭიროებათ, ბრაუზერის განახლება.\nupdateFirefox = Firefox-ის განახლება\ndeletePopupCancel = გაუქმება\ndeleteButtonHover = წაშლა\nfooterLinkLegal = სამართლებრივი საკითხები\nfooterLinkPrivacy = პირადულობა\nfooterLinkCookies = ფუნთუშები\npasswordTryAgain = პაროლი არასწორია. სცადეთ ხელახლა.\njavascriptRequired = Send საჭიროებს JavaScript-ს\nwhyJavascript = რატომ საჭიროებს Send JavaScript-ს?\nenableJavascript = გთხოვთ ჩართოთ JavaScript და სცადოთ ხელახლა.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }სთ { $minutes }წთ\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }წთ\n# A short status message shown when the user enters a long password\nmaxPasswordLength = პაროლის დაშვებული ზომა: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = ამ პაროლის დაყენება ვერ ხერხდება\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = ფაილის გაზიარება მარტივად, დაცულად\nintroDescription = { -send-brand } საშუალებას გაძლევთ გააზიაროთ ფაილები გამჭოლი დაშიფვრითა და ბმულით, რომელიც გარკვეული დროის შემდეგ თავისთავად გაუქმდება. ასე რომ, რასაც გააზიარებთ იქნება საიდუმლო და არც ინტერნეტში არ დარჩება სამუდამოდ.\nnotifyUploadEncryptDone = თქვენი ფაილი დაშიფრულია და მზადაა გასაგზავნად\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = ვადის გასვლამდე დარჩენილია { $downloadCount } ან { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 წუთი\n       *[other] { $num } წუთი\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 დღე\n       *[other] { $num } დღე\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 კვირა\n       *[other] { $num } კვირა\n    }\nfileCount =\n    { $num ->\n        [one] 1 ფაილი\n       *[other] { $num } ფაილი\n    }\n# byte abbreviation\nbytes = ბ\n# kibibyte abbreviation\nkb = კბ\n# mebibyte abbreviation\nmb = მბ\n# gibibyte abbreviation\ngb = გბ\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = სულ ზომა: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = ბმულის ასლი ფაილის გასაზიარებლად:\ncopyLinkButton = ბმულის ასლი\ndownloadTitle = ფაილების ჩამოტვირთვა\ndownloadDescription = ფაილი გაზიარებულია { -send-brand }-ის საშუალებით, გამჭოლი დაშიფვრითა და ვადიანი ბმულით.\ntrySendDescription = გამოსცადეთ { -send-brand }, ფაილების გაზიარება მარტივად, დაცულად.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] მხოლოდ 1 ფაილი შეიძლება აიტვირთოს ერთ ჯერზე.\n       *[other] მხოლოდ { $count } ფაილი შეიძლება აიტვირთოს ერთ ჯერზე.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] მხოლოდ 1 არქივია დაშვებული.\n       *[other] მხოლოდ { $count } არქივია დაშვებული.\n    }\nexpiredTitle = ბმული ვადაგასულია.\nnotSupportedDescription = { -send-brand } არ იმუშავებს ამ ბრაუზერთან. { -send-short-brand } საუკეთესოდ მუშაობს ახალ { -firefox }-ზე და აგრეთვე უმეტესი ბრაუზერების უახლეს ვერსიებზე.\ndownloadFirefox = ჩამოტვირთეთ { -firefox }\nlegalTitle = { -send-short-brand } პირადულობის განაცხადი\nlegalDateStamp = ვერსია 1.0, დათარიღებული 12 მარტით, 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } დღე { $hours } სთ { $minutes } წთ\naddFilesButton = ფაილების შერჩევა ასატვირთად\ntrustWarningMessage = დარწმუნდით, რომ ენდობით მიმღებს, სანამ მნიშვნელოვან მონაცემებს გაუზიარებთ.\nuploadButton = ატვირთვა\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = გადმოიტანეთ და მოათავსეთ ფაილები\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = ან დაწკაპეთ გასაგზავნად { $size }-მდე\naddPassword = პაროლით დაცვა\nemailPlaceholder = შეიყვანეთ ელფოსტა\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = შედით ანგარიშზე, რომ გაგზავნოთ { $size }-მდე\nsignInOnlyButton = შესვლა\naccountBenefitTitle = შექმენით { -firefox }-ანგარიში ან შედით\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = გააზიარეთ ფაილები { $size }-მდე\naccountBenefitDownloadCount = გაუზიარეთ ფაილები მეტ ხალხს\naccountBenefitTimeLimit =\n    { $count ->\n        [one] დატოვეთ ფაილები 1 დღემდე\n       *[other] დატოვეთ ფაილები { $count } დღემდე\n    }\naccountBenefitSync = მართეთ გაზიარებული ფაილები ნებისმიერი მოწყობილობიდან\naccountBenefitMoz = გაეცანით { -mozilla }-ს სხვა მომსახურებებს\nsignOut = გამოსვლა\nokButton = კარგი\ndownloadingTitle = მიმდინარეობს ჩამოტვირთვა\nnoStreamsWarning = ამ ბრაუზერმა, შესაძლოა ვერ მოახერხოს ასეთი დიდი ფაილის გაშიფვრა.\nnoStreamsOptionCopy = ბმულის ასლის აღება სხვა ბრაუზერში გასახსნელად\nnoStreamsOptionFirefox = სცადეთ ჩვენი რჩეული ბრაუზერი\nnoStreamsOptionDownload = განაგრძეთ ამ ბრაუზერით\ndownloadFirefoxPromo = { -send-short-brand }-ს წარმოგიდგინეთ უახლესი { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = ფაილის ბმულის გაზიარება:\nshareLinkButton = ბმულის გაზიარება\n# $name is the name of the file\nshareMessage = ჩამოტვირთეთ „{ $name }“ { -send-brand }-ით: ფაილების გაზიარება მარტივად, უსაფრთხოდ\ntrailheadPromo = გზა, თქვენი პირადულობის დასაცავად. შემოუერთდით Firefox-ს.\nlearnMore = იხილეთ ვრცლად.\ndownloadFlagged = ბმული გაუქმებულია, მომსახურების პირობების დარღვევის გამო.\ndownloadConfirmTitle = კიდევ ერთი რამ\ndownloadConfirmDescription = დარწმუნდით, რომ სანდოა პირი, ვინც ეს ფაილი გამოგიგზავნათ, რადგან ჩვენ ვერ დაგპირდებით, რომ არ დააზიანებს თქვენს მოწყობილობას.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] ვენდობი პირს, რომელმაც ეს ფაილი გამომიგზავნა\n       *[other] ვენდობი პირს, რომელმაც ეს ფაილები გამომიგზავნა\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] მოხსენება, საეჭვო ფაილზე\n       *[other] მოხსენება, საეჭვო ფაილებზე\n    }\nreportDescription = დაგვეხმარეთ გარკვევაში. თქვენი აზრით, რა ფაილებია?\nreportUnknownDescription = გთხოვთ გადახვიდეთ ბმულზე, რომლზეც გსურთ გვაცნობოთ და დაწკაპეთ „{ reportFile }“.\nreportButton = მოხსენება\nreportReasonMalware = ეს ფაილები შეიცავს მავნე კოდს ან თაღლითური შეტევის ნაწილია.\nreportReasonPii = ეს ფაილები შეიცავს ვინაობის ამსახველ მასალას ჩემზე.\nreportReasonAbuse = ეს ფაილები შეიცავს უკანონო ან შეურაცხმყოფელ მასალას.\nreportReasonCopyright = საავტორო უფლებებთან ან სავაჭრო ნიშნებთან დაკავშირებულ დარღვევებზე მოხსენებისთვის, გთხოვთ იხილოთ განმარტებითი მითითებები <a>ამ გვერდზე</a>.\nreportedTitle = ფაილებზე მოხსენება გაგზავნილია\nreportedDescription = გმადლობთ. მივიღეთ თქვენი მოხსენება, ამ ფაილებზე.\n"
  },
  {
    "path": "public/locales/kab/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Akter...\nencryptingFile = Awgelhen...\ndecryptingFile = Azmek...\ndownloadCount =\n    { $num ->\n        [one] 1 usider\n       *[other] { $num } isidar\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 usrag\n       *[other] { $num } isragen\n    }\ncopiedUrl = Yenɣel!\nunlockInputPlaceholder = Awal uffir\nunlockButtonLabel = Serreḥ\ndownloadButtonLabel = Sider\ndownloadFinish = Asider yemmed\nfileSizeProgress = ({ $partialSize } seg { $totalSize })\nsendYourFilesLink = Ɛreḍ Send\nerrorPageHeader = Yella wayen yeḍran!\nfileTooBig = Afaylu-agi meqqer aṭas. Yessefk ad yili daw n  { $size }.\nlinkExpiredAlt = Aseɣwen yemmut\nnotSupportedHeader = Iminig-ik ur ittusefrak ara\nnotSupportedLink = Ayγer iminig inu ur yettwasefrek ara?\nnotSupportedOutdatedDetail = Ad nesḥissef imilqem-agi n Firefox Firefox ur isefrak ara titiknulujiyin web yettwaseqdacen di Send. Yessefk ad tleqmeḍ iminig-ik.\nupdateFirefox = Leqqem Firefox\ndeletePopupCancel = Sefsex\ndeleteButtonHover = Kkes\nfooterLinkLegal = Usḍif\nfooterLinkPrivacy = Tabaḍnit\nfooterLinkCookies = Inagan n tuqqna\npasswordTryAgain = Yir awal uffir. Ɛreḍ tikelt nniḍen.\njavascriptRequired = Send yesra JavaScript\nwhyJavascript = Ayɣer firefox Send yesra JavaScript?\nenableJavascript = Ma ulac aɣilif rmed JavaScript sakin ɛreḍ tikkelt nniḍen.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }Isragen { $minutes }Tisdatin\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }Tisdatin\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Tuγzi tafellayt n wawal uffir: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Awal-agi uffir ur izmir ara ad ittwabaded\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Afessas, beṭṭu n ifuyla s wudem uslig\nintroDescription = { -send-brand } ad k·kem-yeǧǧ ad tebḍuḍ ifuyla iwgelhanen si ṭṭerf ɣer ṭṭerf akked useɣwen ara yemmten s wudem awurman. Daɣen, ad tizmireḍ ad tḥerzeḍ ayen i tbeṭṭuḍ s wudem uslig daɣen ad tamneḍ imi agbur-ik·im ur yettɣimi ara  i lebda.\nnotifyUploadEncryptDone = Afaylu-ik yewgelhen daɣen ihegga i tuzna\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Ad yemmet deffir { $downloadCount } neɣ { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 n tsedat\n       *[other] { $num } n tsedatin\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 n wass\n       *[other] { $num } n wussan\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 n dduṛt\n       *[other] { $num } n ledwaṛ\n    }\nfileCount =\n    { $num ->\n        [one] 1 n ufaylu\n       *[other] { $num } n yifuyla\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KAṬ\n# mebibyte abbreviation\nmb = MAṬ\n# gibibyte abbreviation\ngb = GAṬ\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Tuɣzi s umata: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Nɣel aseɣwen akken ad tebḍuḍ afaylu-inek\ncopyLinkButton = Nɣel aseɣwen\ndownloadTitle = Sider ifuyla\ndownloadDescription = Afaylu-a yettwabḍa s { -send-brand } s uwgelhen s ṭṭerf ɣer ṭṭerf s useɣwen ara yemmten s wudem awurman.\ntrySendDescription = Ɛreḍ { -send-brand } i beḍḍu afessas n ifuyla s wudem ameɣtu.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Ala 1 n ufaylu i yemzren ad yali i tikkelt.\n       *[other] Ala { $count } n yifuyla i yemzren ad alin i tikkelt.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Ala 1 n teṛcibt i yettwasirgen.\n       *[other] Ala { $count } n teṛcibin i yettwasiregn.\n    }\nexpiredTitle = Immut useɣwen.\nnotSupportedDescription = { -send-brand } ur iteddu ara s yiminig-a. { -send-short-brand } iteddu akken iwata s lqem aneggaru n { -firefox }, daɣen iteddu s lqem amiran n tuget n yiminigen.\ndownloadFirefox = Sider { -firefox }\nlegalTitle = Tasertit tabaḍnit n { -send-short-brand }\nlegalDateStamp = Lqem  1.0, azemz n 12 Meɣres 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } ass { $hours } srg { $minutes } tsd\naddFilesButton = Fren ifuyla ad tessaliḍ\ntrustWarningMessage = Ḍmen d akken tumneḍ anermis ticki tebḍiḍ isefka n tbadnit.\nuploadButton = Sali\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Ẓuɣer sakin sers ifuyla\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = neɣ sit akken ad tazneḍ arma d { $size }\naddPassword = Ḥrez s wawal uffir\nemailPlaceholder = Sekcem imayl inek\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Qqen akken ad tazneḍ arma d { $size }\nsignInOnlyButton = Qqen\naccountBenefitTitle = Rnu amiḍan { -firefox } akken ad teqqneḍ\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Bḍu ifuyla arma d { $size }\naccountBenefitDownloadCount = Bḍu ifuyla d wugan n medden\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Eǧǧ iseɣwan d urmiden arma d 1 n wass\n       *[other] Eǧǧ iseɣwan d urmiden arma d { $count } n wassan\n    }\naccountBenefitSync = Sefrek ifuyla yebdan seg yal ibenk\naccountBenefitMoz = Issin ugar ɣef yimeẓla-nniḍen n { -mozilla }\nsignOut = Ffeɣ\nokButton = IH\ndownloadingTitle = Azdam\nnoStreamsWarning = Iminig-a ur yezmir ara ad yezmek afaylu meqqren.\nnoStreamsOptionCopy = Nɣel aseɣwen i tulya deg yiminig-nniden\nnoStreamsOptionFirefox = Ɛreḍ iminig-ik ufrin\nnoStreamsOptionDownload = Kemmel akked iminig-a\ndownloadFirefoxPromo = { -send-short-brand } yettwasumer i yal { -firefox } amaynut.\n# the next line after the colon contains a file name\nshareLinkDescription = Bḍu aseɣwen ɣer ufaylu-ik:\nshareLinkButton = Bḍu aseɣwen\n# $name is the name of the file\nshareMessage = Sider \"{ $name }\" s { -send-brand }: d fessas, d aɣelsan i beṭṭu n yifuyla.\ntrailheadPromo = Yella wallal n ummesten n tudert-ik tusligt. Ddu ɣer Firefox.\nlearnMore = Issin ugar.\ndownloadFlagged = Aseɣwen-a yensa acku ur iquder ara tiwtilin n useqdec.\ndownloadConfirmTitle = Taɣawsa-nniḍen\ndownloadConfirmDescription = Ḍmen d akken tumneḍ amdan i ak-d-yuznen afaylu-a acku ur nezmir ara ad nwali ma yella ur iṭuṛṛu ara ibenk-ik.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Umneɣ amdan i yi-d-yuznen afaylu-a.\n       *[other] Umneɣ amdan i yi-d-yuznen ifuyla-a.\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Mmel-d afaylu-a ma tkukraḍ\n       *[other] Mmel-d ifuyla-a ma tkukraḍ\n    }\nreportDescription = Mudd-aɣ-d afus n tallalt akken ad negzu acu i la iḍerrun. Acu twalaḍ cwiya-t kan deg yifuyla-a?\nreportUnknownDescription = Ttxil-k·m rzu ɣer url n useɣwen i tebɣiḍ ad t-tceggreḍ syen sit ɣef “{ reportFile }”.\nreportButton = Aneqqis\nreportReasonMalware = Ifuyla-a deg-sen yir iseɣzanen neɣ d aḥric seg uẓdam n ṣṣyada.\nreportReasonPii = Ifuyla-a deg-sen talɣut tudmawant yettwassnen i yi-yeɛnan.\nreportReasonAbuse = Ifuyla-a deg-sen agbur arusḍif neɣ anaffal.\nreportReasonCopyright = I ucegger n tkerḍa n yizerfan n umeskar neɣ n tecraḍ, seqdec asesfer i d-yettwagelmen ɣef <a>usebter-a</a>.\nreportedTitle = Ifuyla i d-yettwaceqqren\nreportedDescription = Tanemmirt. Nermes-d aneqqis-ik·im ɣef yifuyla-a.\n"
  },
  {
    "path": "public/locales/ko/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = 가져오는 중…\nencryptingFile = 암호화 중…\ndecryptingFile = 복호화 중…\ndownloadCount = 다운로드 { $num }회\ntimespanHours = { $num }시간\ncopiedUrl = 복사 완료!\nunlockInputPlaceholder = 비밀번호\nunlockButtonLabel = 잠금 해제\ndownloadButtonLabel = 다운로드\ndownloadFinish = 다운로드 완료\nfileSizeProgress = ({ $partialSize } / { $totalSize })\nsendYourFilesLink = Send 써보기\nerrorPageHeader = 오류가 발생했습니다!\nfileTooBig = 파일의 크기가 너무 큽니다. { $size } 보다 작아야 합니다.\nlinkExpiredAlt = 링크가 만료됨\nnotSupportedHeader = 이 브라우저는 지원되지 않습니다.\nnotSupportedLink = 왜 이 브라우저는 지원이 되지 않나요?\nnotSupportedOutdatedDetail = 안타깝게도 사용중인 Firefox 버전에서는 Send에 사용되는 웹 기술을 지원하지 않습니다. 브라우저 업데이트가 필요합니다.\nupdateFirefox = Firefox 업데이트\ndeletePopupCancel = 아니오\ndeleteButtonHover = 삭제\nfooterLinkLegal = 법적 정보\nfooterLinkPrivacy = 개인정보 보호\nfooterLinkCookies = 쿠키\npasswordTryAgain = 비밀번호가 맞지 않습니다. 다시 시도해 주세요.\njavascriptRequired = Send는 JavaScript를 필요로 합니다\nwhyJavascript = 왜 Send에 JavaScript가 필요하죠?\nenableJavascript = JavaScript를 활성화하고 다시 시도해 주세요.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }시간 { $minutes }분\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }분\n# A short status message shown when the user enters a long password\nmaxPasswordLength = 최대 비밀번호 길이: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = 이 비밀번호를 설정할 수 없었습니다\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = 간단하고, 사생활을 보호하는 파일 공유\nintroDescription = { -send-brand }를 사용하면 종단 암호화와 자동으로 만료되는 링크를 사용해 파일을 공유할 수 있습니다. 안전하게 공유할 수 있고 공유된 파일이 계속 온라인에 남지 않게 됩니다.\nnotifyUploadEncryptDone = 파일이 암호화 되어서 보낼 수 있게 됐습니다\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = { $downloadCount } 혹은 { $timespan } 후 만료됨\ntimespanMinutes =\n    { $num ->\n       *[other] { $num }분\n    }\ntimespanDays =\n    { $num ->\n       *[other] { $num }일\n    }\ntimespanWeeks =\n    { $num ->\n       *[other] { $num }주\n    }\nfileCount =\n    { $num ->\n       *[other] { $num } 파일\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = 전체 크기: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = 링크를 복사해서 파일을 공유하세요:\ncopyLinkButton = 링크 복사\ndownloadTitle = 파일 다운로드\ndownloadDescription = 이 파일은 종단간 암호화 및 자동으로 만료되는 링크를 지원하는 { -send-brand }를 통해 공유되었습니다.\ntrySendDescription = 간단하고 안전한 파일 공유를 원하시나요? { -send-brand }를 사용해보세요.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n       *[other] 한번에 { $count }개의 파일만 업로드 할 수 있습니다.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n       *[other] { $count }개의 아카이브만 허용됩니다.\n    }\nexpiredTitle = 이 링크는 만료되었습니다.\nnotSupportedDescription = { -send-brand }는 이 브라우저와 작동하지 않습니다. { -send-short-brand }는 최신 { -firefox }와 가장 잘 작동하며, 대부분의 최신 웹 브라우저와도 잘 작동합니다.\ndownloadFirefox = { -firefox } 다운로드\nlegalTitle = { -send-short-brand } 개인정보처리방침\nlegalDateStamp = 버전 1.0, 2019년 3월 12일자\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }일 { $hours }시간 { $minutes }분\naddFilesButton = 업로드할 파일들을 선택하세요\ntrustWarningMessage = 중요한 정보를 공유할 때는 수신자들이 모두 믿을 만한 사람들인지를 꼭 확인하세요.\nuploadButton = 업로드\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = 파일들을 여기에 끌어서 놓으세요\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = 또는 여기를 클릭하여 { $size }까지의 파일을 공유하세요.\naddPassword = 비밀번호로 파일 보호\nemailPlaceholder = 이메일 입력\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = { $size }까지 파일을 보낼 수 있게 로그인\nsignInOnlyButton = 로그인\naccountBenefitTitle = { -firefox } 계정 생성 또는 로그인\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = { $size }까지의 파일 공유\naccountBenefitDownloadCount = 더 많은 사람들과 함께 파일 공유\naccountBenefitTimeLimit =\n    { $count ->\n       *[other] 최대 { $count }일까지 링크 유지\n    }\naccountBenefitSync = 어떤 기기에서든지 공유된 링크 관리\naccountBenefitMoz = 다른 { -mozilla } 서비스에 대해 알아보기\nsignOut = 로그아웃\nokButton = 확인\ndownloadingTitle = 다운로드 중\nnoStreamsWarning = 이 브라우저는 이렇게 큰 파일은 암호화 해제를 못할 수도 있습니다.\nnoStreamsOptionCopy = 다른 브라우저에서 열 수 있도록 링크를 복사\nnoStreamsOptionFirefox = 우리가 애용하는 브라우저를 사용해 보세요\nnoStreamsOptionDownload = 이 브라우저로 계속하기\ndownloadFirefoxPromo = 완전히 새로운 { -firefox }로 { -send-short-brand }가 제공됩니다.\n# the next line after the colon contains a file name\nshareLinkDescription = 파일 링크 공유:\nshareLinkButton = 링크 공유\n# $name is the name of the file\nshareMessage = { -send-brand }으로 “{ $name }” 파일을 내려받으세요: 쉽고 안전한 파일 공유입니다.\ntrailheadPromo = 개인 정보를 보호하는 방법이 있습니다. Firefox에 가입하세요.\nlearnMore = 더 알아보기.\ndownloadFlagged = 서비스 약관 위반으로 인해 비활성화된 링크입니다.\ndownloadConfirmTitle = 한 가지 더\ndownloadConfirmDescription = 이 파일이 기기에 해를 끼치지 않는 다는 점을 확인하지 못했기 때문에 이 파일을 보낸 사람을 신뢰할 수 있는지 확인하세요.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n       *[other] 이 파일을 보낸 사람을 신뢰함\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n       *[other] 이 파일을 의심스러운 것으로 신고\n    }\nreportDescription = 어떤 일이 발생했는지 알려 주세요. 이 파일의 어느 부분이 문제인 것 같나요?\nreportUnknownDescription = 신고하려는 링크의 URL로 가서 “{ reportFile }”를 클릭하세요.\nreportButton = 신고\nreportReasonMalware = 이 파일은 악성 코드를 포함하고 있거나 피싱 공격의 일부입니다.\nreportReasonPii = 이 파일에는 본인에 대한 개인 식별 정보가 포함되어 있습니다.\nreportReasonAbuse = 이 파일에는 불법적이거나 모욕적인 내용이 들어 있습니다.\nreportReasonCopyright = 저작권 또는 상표권 침해를 신고하려면 <a>이 페이지</a>에 설명된 절차를 따르십시오.\nreportedTitle = 파일 신고됨\nreportedDescription = 파일에 대한 신고를 접수했습니다. 감사합니다.\n"
  },
  {
    "path": "public/locales/lt/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importuojama…\nencryptingFile = Šifruojama…\ndecryptingFile = Iššifruojama…\ndownloadCount =\n    { $num ->\n        [one] { $num } kartą\n        [few] { $num } kartus\n       *[other] { $num } kartų\n    }\ntimespanHours =\n    { $num ->\n        [one] { $num } valandos\n        [few] { $num } valandų\n       *[other] { $num } valandų\n    }\ncopiedUrl = Nukopijuota!\nunlockInputPlaceholder = Slaptažodis\nunlockButtonLabel = Atrakinti\ndownloadButtonLabel = Parsisiųsti\ndownloadFinish = Parsiuntimas baigtas\nfileSizeProgress = ({ $partialSize } iš { $totalSize })\nsendYourFilesLink = Išbandyti „Send“\nerrorPageHeader = Nutiko kažkas negero!\nfileTooBig = Pasirinktas failas yra per didelis, kad jį būtų galima įkelti. Failo dydis neturėtų viršyti { $size }\nlinkExpiredAlt = Saitas nebegalioja\nnotSupportedHeader = Jūsų naršyklė nepalaikoma.\nnotSupportedLink = Kodėl mano naršyklė nepalaikoma?\nnotSupportedOutdatedDetail = Deja, šioje „Firefox“ naršyklės laidoje nepalaikoma „Send“ veikti reikalinga technologija. Jeigu norite naudotis šia paslauga, turėsite atnaujinti savo naršyklę.\nupdateFirefox = Atnaujinti „Firefox“\ndeletePopupCancel = Atsisakyti\ndeleteButtonHover = Šalinti\nfooterLinkLegal = Teisinė informacija\nfooterLinkPrivacy = Privatumas\nfooterLinkCookies = Slapukai\npasswordTryAgain = Slaptažodis netinka. Bandykite dar kartą.\njavascriptRequired = „Send“ veikimui būtina įgalinti „JavaScript“ palaikymą\nwhyJavascript = Kodėl „Send“ neveikia išjungus „JavaScript“?\nenableJavascript = Įgalinkit „JavaScript“ ir bandykite dar kartą.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } val. { $minutes } min.\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } min.\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Didžiausias leistinas slaptažodžio ilgis: { $length } simb.\n# A short status message shown when there was an error setting the password\npasswordSetError = Slaptažodžio nustatyti nepavyko\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla =\n    { $case ->\n       *[nominative] Mozilla\n        [genitive] Mozillos\n        [dative] Mozillai\n        [accusative] Mozillą\n        [instrumental] Mozilla\n        [locative] Mozilloje\n    }\nintroTitle = Paprastas ir privatus dalijimasis failais\nintroDescription = „{ -send-brand }“ suteikia galimybę dalintis failais, pasitelkiant abipusį šifravimą ir riboto galiojimo saitus. Tai padeda pasidalintus failus išlaikyti privačiais ir užtikrina, jog trumpam įkelti failai neliks pasiekiami internete amžinai.\nnotifyUploadEncryptDone = Failas užšifruotas ir parengtas išsiuntimui\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Nustos galioti parsisiuntus { $downloadCount } arba po { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] { $num } minutės\n        [few] { $num } minučių\n       *[other] { $num } minučių\n    }\ntimespanDays =\n    { $num ->\n        [one] { $num } dienos\n        [few] { $num } dienų\n       *[other] { $num } dienų\n    }\ntimespanWeeks =\n    { $num ->\n        [one] { $num } savaitės\n        [few] { $num } savaičių\n       *[other] { $num } savaičių\n    }\nfileCount =\n    { $num ->\n        [one] { $num } failas\n        [few] { $num } failai\n       *[other] { $num } failų\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = kB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Bendras dydis: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Nukopijuokite saitą, jeigu norite pasidalinti failu:\ncopyLinkButton = Kopijuoti saitą\ndownloadTitle = Parsisiųsti failus\ndownloadDescription = Šiuo failu pasidalinta per „{ -send-brand }“, pasitelkiant abipusį šifravimą ir riboto galiojimo saitą.\ntrySendDescription = Išbandykite „{ -send-brand }“ paprastam ir saugiam dalijimuisi failais.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Vienu metu galima įkelti ne daugiau kaip { $count } failą.\n        [few] Vienu metu galima įkelti ne daugiau kaip { $count } failus.\n       *[other] Vienu metu galima įkelti ne daugiau kaip { $count } failų.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Leidžiama turėti iki ne daugiau kaip { $count } archyvą.\n        [few] Leidžiama turėti iki ne daugiau kaip { $count } archyvus.\n       *[other] Leidžiama turėti iki ne daugiau kaip { $count } archyvų.\n    }\nexpiredTitle = Šis saitas nebegalioja.\nnotSupportedDescription = „{ -send-brand }“ su šia naršykle neveikia. „{ -send-short-brand }“ geriausiai veikia su paskiausia „{ -firefox }“ laida, o taip pat veikia su daugumos kitų naršyklių paskiausiomis laidomis.\ndownloadFirefox = Parsisiųsti „{ -firefox }“\nlegalTitle = „{ -send-short-brand }“ privatumo pranešimas\nlegalDateStamp = 1.0 versija, 2019 m. kovo 12 d\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } d. { $hours } val. { $minutes } min.\naddFilesButton = Rinktis failus įkėlimui\ntrustWarningMessage = Dalindamiesi svarbiais duomenimis įsitikinkite, kad pasitikite gavėju.\nuploadButton = Įkelti\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Užtempkite ir numeskite failus čia\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = arba spustelėkite mygtuką ir dalinkitės failais iki { $size }\naddPassword = Apsaugoti slaptažodžiu\nemailPlaceholder = Įveskite savo el. pašto adresą\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Prisijunkite, jeigu norite siųsti iki { $size }\nsignInOnlyButton = Prisijungti\naccountBenefitTitle = Susikurkite „{ -firefox }“ paskyrą arba prisijunkite\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Dalinkitės iki { $size } dydžio failais\naccountBenefitDownloadCount = Dalinkitės su daugiau žmonių\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Išlaikykite saitus galiojančiais iki { $count } dienos.\n        [few] Išlaikykite saitus galiojančiais iki { $count } dienų.\n       *[other] Išlaikykite saitus galiojančiais iki { $count } dienų.\n    }\naccountBenefitSync = Tvarkykite failus, kuriais dalijatės, iš bet kurio įrenginio\naccountBenefitMoz = Sužinokite apie kitas „{ -mozilla(case: \"genitive\") }“ paslaugas\nsignOut = Atsijungti\nokButton = Gerai\ndownloadingTitle = Parsiunčiama\nnoStreamsWarning = jūsų naršyklei gali nepavykti iššifruoti tokio didelio failo.\nnoStreamsOptionCopy = Nukopijuokite saitą ir atverkite jį kita naršykle\nnoStreamsOptionFirefox = Išbandykite mūsų mėgstamiausią naršyklę\nnoStreamsOptionDownload = Tęsti naudojantis šia naršykle\ndownloadFirefoxPromo = „{ -send-short-brand }“ jums atkeliauja iš naujosios „{ -firefox }“.\n# the next line after the colon contains a file name\nshareLinkDescription = Pasidalinkite saitu į jūsų failą:\nshareLinkButton = Dalintis saitu\n# $name is the name of the file\nshareMessage = Atsisiųskite „{ $name }“ su „{ -send-brand }“: paprastas, saugus dalinimasis failais\ntrailheadPromo = Yra būdas apsaugoti jūsų privatumą. Naudokite „Firefox“.\nlearnMore = Sužinoti daugiau.\ndownloadFlagged = Šis saitas panaikintas dėl paslaugos teikimo nuostatų pažeidimo.\ndownloadConfirmTitle = Dar vienas dalykas\ndownloadConfirmDescription = Įsitikinkite, kad pasitikite asmeniu, atsiuntusiu šį failą, nes mes negalime užtikrinti, kad jis nepakenks jūsų įrenginiui.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Aš pasitikiu asmeniu, atsiuntusiu šį failą\n        [few] Aš pasitikiu asmeniu, atsiuntusiu šiuos failus\n       *[other] Aš pasitikiu asmeniu, atsiuntusiu šiuos failus\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Pranešti apie įtartiną failą\n        [few] Pranešti apie įtartinus failus\n       *[other] Pranešti apie įtartinus failus\n    }\nreportDescription = Padėkite mums suprasti situaciją. Kas jūsų nuomone negerai su šiais failais?\nreportUnknownDescription = Atverkite saitą, apie kurį norite pranešti, ir spustelėkite „{ reportFile }“.\nreportButton = Pranešti\nreportReasonMalware = Šiuose failuose yra kenkėjiškos programinės įrangos, arba jie yra dalis sukčiavimo atakos.\nreportReasonPii = Šiuose failuose yra mano asmeninės informacijos.\nreportReasonAbuse = Šiuose failuose yra nelegalaus arba neteisėto turinio.\nreportReasonCopyright = Norėdami pranešti apie autorių teisių ar prekės ženklo pažeidimus, vadovaukitės <a>šiame puslapyje</a> aprašytu procesu.\nreportedTitle = Apie failus pranešta\nreportedDescription = Ačiū. Mes gavome jūsų pranešimą apie šiuos failus.\n"
  },
  {
    "path": "public/locales/lus/send.ftl",
    "content": "encryptingFile = Encrypting...\ndecryptingFile = Decrypting\n\n## Send version 2 strings\n\n"
  },
  {
    "path": "public/locales/meh/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Tu'un jianininu\nimportingFile = Nasia´a…\nencryptingFile = Encriptando...\ndecryptingFile = Desencriptando…\ndownloadCount =\n    { $num ->\n       *[other] { $num } nxinuun\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hora\n       *[other] { $num } horas\n    }\ncopiedUrl = Ntɨɨn\nunlockInputPlaceholder = Contraseña\nunlockButtonLabel = Nkasɨ\ndownloadButtonLabel = Xinuu\ndownloadFinish = Nnɨ´ɨ xinuu\nfileSizeProgress = ({ $partialSize } de { $totalSize })\nsendYourFilesLink = Ni´i Send\nerrorPageHeader = ¡Iyo iin ntu nkene va´a!\nfileTooBig = Archivo ya´a ka´nu. Nejia chunku´va { $size }\nlinkExpiredAlt = Nnɨ´ɨ enlace\nnotSupportedHeader = Ntu íyo tiñu nuu ka̱a̱ nánuku ya´a.\nnotSupportedLink = ¿Navi ntu satiñu nuu ka̱a̱ nánuku ya´a?\nnotSupportedOutdatedDetail = Tuni Firefox ya´a ntu satiñu vii jii Send. Nejika xinunu a jíía ka̱a̱ nánuku.\nupdateFirefox = Naxi´ñá Firefox\ndeletePopupCancel = Nkuvi-ka\ndeleteButtonHover = Xita\nfooterLinkLegal = Tu´un nichi\nfooterLinkPrivacy = Tu´un xitu a kumiji noo´o\nfooterLinkCookies = Cookies\npasswordTryAgain = Contraseña ntu vatu. Nachu´un tuku.\njavascriptRequired = Send ni´i JavaScript\nwhyJavascript = ¿Navi Send ni´i JavaScript?\nenableJavascript = Kua´a jia´a JavaScript jee nachu´un tuku.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Naja ka´nu koo contraseña: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Ntu nkuvi sá´á contraseña\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Kua´a daa archivo ñama jee yu´u\nintroDescription = { -send-brand } taji jia´anu archivos jii cifrado uvi nuu jee iin enlace nɨ´ɨ. Sukuan kuvi kumi yu´unu daa archivo jia´anu jee kuninu nkino daa ya´a kue´e kuiya íchi nuu.\nnotifyUploadEncryptDone = Archivo noo´o íyo cifrado jee kuvi chu´un íchi\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Nɨ'ɨ dee nña´a { $downloadCount } a xiin { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuto\n       *[other] { $num } minutos\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 día\n       *[other] { $num } días\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 semana\n       *[other] { $num } semanas\n    }\nfileCount =\n    { $num ->\n        [one] 1 archivo\n       *[other] { $num } archivos\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Ka´nu: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Tɨɨn enlace jee kua´a archivo:\ncopyLinkButton = Tɨɨn enlacae\ndownloadTitle = Xinuu archivo\ndownloadDescription = Archivo ya´a nsajia { -send-brand } jíí cifrado punto a punto jee iin enlace naa.\ntrySendDescription = Nasá´á jii { -send-brand } kua´a ñama jee vatu.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Ntuxini 1 archivo kuvi ska.\n       *[other] Ntuxini { $count } archivos kuvi ska.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Ntu xini 1 archivo íyo\n       *[other] Ntu xini { $count } archivos íyo\n    }\nexpiredTitle = Nnɨ'ɨ link ya´a.\nnotSupportedDescription = { -send-brand } nsatiñu jii ka̱a̱ nánuku ya´a. { -send-short-brand } satiñu va´a jii tuni íchi yata { -firefox }, jee satiñu va´a jii tuni íyo ntañu´u kuaiyo daa ka̱a̱ nánuku.\ndownloadFirefox = Xinuun { -firefox }\nlegalTitle = Tu´un xitu a kumiji noo´o { -send-short-brand }\nlegalDateStamp = Versión 1.0 del 12 de marzo de 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Kaji archivos ska\nuploadButton = Ska\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Staka jee sía  daa archivo\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = a xiin kuaxin saa chu´un íchi nee { $size }\naddPassword = Iyo yu´u jii contraseña\nemailPlaceholder = Chu´un email noo´o\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Kajie´e sesión saa chu´un íchi nee { $size }\nsignInOnlyButton = Kajie´e sesión\naccountBenefitTitle = Sá´á iin cuenta { -firefox } a xiin kajie´e sesión\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Kua´a archivo ka´nu { $size }\naccountBenefitDownloadCount = Kua´a archivos jii inka ñivɨ\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Kuteku enlaces 1 kivɨ\n       *[other] Kuteku daa enlaces { $count } kivɨ\n    }\naccountBenefitSync = Tetiñu archivos jia´anu ntaka ka̱a̱\naccountBenefitMoz = Ka´vi kue´eka jiee inka tiñu { -mozilla }\nsignOut = Kasɨ sesión\nokButton = Kuvi\ndownloadingTitle = Xinuu\nnoStreamsWarning = Kuvi ka̱a̱ nánaku ya´a nxituvi a vaji nuu iin archivo ka´nu.\nnoStreamsOptionCopy = Tɨɨn enlace jee síne nuu inka ka̱a̱ nánuku\nnoStreamsOptionFirefox = Ni´i ka̱a̱ nánuku va´a\nnoStreamsOptionDownload = Kaka jii ka̱a̱ nánuku ya´a\ndownloadFirefoxPromo = { -send-short-brand } taji jíía { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Kua´a enlace archivo noo´o\nshareLinkButton = Kua´a link\n# $name is the name of the file\nshareMessage = Xinuu “{ $name }” jii { -send-brand }: ntu viji\ntrailheadPromo = Iyo iin kuvi kumi privacidad noo´o. Nayonika Firefox.\nlearnMore = Ka´vi kue´eka\n"
  },
  {
    "path": "public/locales/mix/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Ndakiin…\nencryptingFile = Ndasami tu'un…\ndecryptingFile = Nchiko tu'un…\ndownloadCount =\n    { $num ->\n        [one] 1 snuú\n       *[other] { $num } snuú\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hora\n       *[other] { $num } horas\n    }\ncopiedUrl = ¡Tsa ndatavi ña!\nunlockInputPlaceholder = Tu'un seè\nunlockButtonLabel = Kuna\ndownloadButtonLabel = Snuù\ndownloadFinish = Ntsinu snui\nfileSizeProgress = ({ $partialSize } ña { $totalSize })\nsendYourFilesLink = Kuachu'un Send\nerrorPageHeader = ¡Yee ña va'a!\nfileTooBig = Kanu tutu yo. Tsini ñu'u koi tana { $size }.\nlinkExpiredAlt = Ntoo enlace\nnotSupportedHeader = Kue ku kuni página.\nnotSupportedLink = ¿Chanu kue ku kuncheuña?\nnotSupportedOutdatedDetail = Firefox kue ku kuni página web takua kuachu'un Send. tsiniñu'u ndu tsa'a navegador.\nupdateFirefox = Ndu tsa'a Firefox\ndeletePopupCancel = Kunchatu\ndeleteButtonHover = Stoò\nfooterLinkLegal = Aviso legal\nfooterLinkPrivacy = Ña meu\nfooterLinkCookies = Cookies\npasswordTryAgain = Kue vaa ni chau sivi siki. Chai tuku.\njavascriptRequired = Send tsiniñui JavaScript\nwhyJavascript = ¿Chanu Send tsiniñui JavaScript?\nenableJavascript = Saá ña mani katsi JavaScript chá kitsa tuku.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Kua tu'un see: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Ma ku ntanii tu'un see\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Stucha kue tutu ku\nintroDescription = { -send-brand } ku stuchaku tutu seé tsi inkana tsi iin enlace ña ntóo mituin. Sa'an ku kunka va'a ña stuchaku cha ma ku kunchee na kue tutu ku.\nnotifyUploadEncryptDone = Tsa inka va'a tutu ku tsa ku stuchaku ña\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Ku kunkai mancha { $downloadCount } a { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuto\n       *[other] { $num } minutos\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 kii\n       *[other] { $num } kii\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 semana\n       *[other] { $num } semanas\n    }\nfileCount =\n    { $num ->\n        [one] 1 tutu\n       *[other] { $num } tutu\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Kua: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Ndatava enlace takua stuchaku tutú.\ncopyLinkButton = Ndatava enlace\ndownloadTitle = Snuú tutu\ndownloadDescription = Tutu yo stuchaku ña tsi { -send-brand } inka si'i chá ku nto'o mituin.\ntrySendDescription = Kuachu'un { -send-brand } takua stuchaku nchi tutu niku\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Ku skau 1 tutu ni.\n       *[other] Mitu'un { $count }tutu ku skau.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] 1 tutu ni ku.\n       *[other] Mitu'un { $count } tutu ni ku.\n    }\nexpiredTitle = Koo enlace inka\nnotSupportedDescription = { -send-brand } ma ku Kuachu'un navegador yo. { -send-short-brand } Sachu'in va'a la  versión da ntii { -firefox }, sachu'un tsi  versión tsa'a su inka kue navegador.\ndownloadFirefox = Snuú { -firefox }\nlegalTitle = Tu'un privacidad { -send-short-brand }\nlegalDateStamp = Versión 1.0 del 12 de marzo de 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Katsi tutu ku skau\ntrustWarningMessage = Kunche'e a va'a nu ku ntachuún ña.\nuploadButton = Skaa\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Xita cha sia kue tutu\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = katavi takua stuchaku ña mancha { $size }\naddPassword = Inka vai tsi tu'un seé\nemailPlaceholder = Chaa korreo ku\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = kitsa takua kuachu'una mancha { $size }\nsignInOnlyButton = Kitsaa\naccountBenefitTitle = Saa iin kuenta ña { -firefox } a kitsa\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Stucha tutu mancha { $size }\naccountBenefitDownloadCount = Stucha tutu tsi kuaka nivi\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Ku kunka tutu ku mancha 1 kii\n       *[other] Ku kunka tutu ku mancha { $count } kii\n    }\naccountBenefitSync = Stucha tutu tsí nchi kaa ndusu niku\naccountBenefitMoz = Kavi tutú tsa { -mozilla }\nsignOut = Kee\nokButton = Vaá\ndownloadingTitle = Snuì\nnoStreamsWarning = Ku ña navegador yo ma ku mini iin tutú kanu.\nnoStreamsOptionCopy = Ndatava enlace takua kunu tsí inka navegador\nnoStreamsOptionFirefox = Kuachu'un navegador ña va'a nu ntia\nnoStreamsOptionDownload = Kunka tsi navegador yo\ndownloadFirefoxPromo = { -send-short-brand } snai ña tsaa { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Stucha enlace tutu ku:\nshareLinkButton = Stucha Enlace\n# $name is the name of the file\nshareMessage = Snuu «{ $name }» tsi { -send-brand }: kue nchichi\ntrailheadPromo = Ku china vau ña chau. Kita'an tsi Firefox.\nlearnMore = Skua'a kuakaa.\ndownloadFlagged = Va'á enlace yo.\ndownloadConfirmTitle = Una cosa más\ndownloadConfirmDescription = A tsinu nivo tachu'un tutu yo takua ma stivia kàa ndusu ku.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Va'a nivi ntachu'un tutu yo\n       *[other] Va'a nivi ntachu'un tutu yo\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Katu'un ña va'á tutu yo\n       *[other] Katu'un ña va'á kue tutu yo\n    }\nreportDescription = Chinche kue yu na kunikue ña yee. ¿A va'á kue tutu yo?\nreportUnknownDescription = Sa'a ña mani kuncheu,  url ña enlace ña va'á cha katavi “{ reportFile }”.\nreportButton = Ka tu'un\nreportReasonMalware = Inka ña va'á nu kue tutu yo.\nreportReasonPii = Inka kue tu'un me nu kue tutu yo.\nreportReasonAbuse = Yee ña va'á nu kue tutu yo.\nreportReasonCopyright = Tatu ye ña va'á nu derechos de autor a marca registrada, kavi tutu yo <a>esta página</a>.\nreportedTitle = Ku ncheé tutu\nreportedDescription = Ti tsavu. tsa kumikue tu'un tsa'a tutuku.\n"
  },
  {
    "path": "public/locales/ml/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = ഫയർഫോക്സ് സെൻഡ്\nsiteFeedback = പ്രതികരണം\nimportingFile = ഇറക്കുമതി ചെയ്യുന്നു...\nencryptingFile = എൻക്രിപ്റ്റ് ചെയ്യുന്നു...\ndecryptingFile = ഡീക്രിപ്റ്റ് ചെയ്യുന്നു...\ndownloadCount =\n    { $num ->\n        [one] ഒരു ഡൗൺലോഡ്\n       *[other] { $num } ഡൗൺലോഡുകൾ\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 മണിക്കൂർ\n       *[other] { $num } മണിക്കൂറുകൾ\n    }\ncopiedUrl = പകർത്തി!\nunlockInputPlaceholder = രഹസ്യവാക്ക്\nunlockButtonLabel = തുറക്കുക\ndownloadButtonLabel = ഡൗൺലോഡ്\ndownloadFinish = ഡൗൺലോഡ് പൂർത്തിയായി\nfileSizeProgress = ({ $totalSize } -ന്റെ { $partialSize })\nsendYourFilesLink = ഫയർഫോക്സ് സെൻഡ് പരീക്ഷിക്കൂ\nerrorPageHeader = എന്തോ പ്രശ്നമുണ്ട്!\nfileTooBig = ഈ ഫയൽ വളരെ വലുതായതിനാൽ അപ്‌ലോഡ് ചെയ്യാൻ സാധിച്ചില്ല. പരമാവധി വലുപ്പം { $size } ആണ്.\nlinkExpiredAlt = കണ്ണി കാലഹരണപ്പെട്ടു\nnotSupportedHeader = താങ്കളുടെ ബ്രൗസറിന് പിന്തുണയില്ല.\nnotSupportedLink = എന്തുകൊണ്ടാണ് എന്റെ ബ്രൗസറിന് പിന്തുണയില്ലാത്തത്?\nnotSupportedOutdatedDetail = ദൗർഭാഗ്യവശാൽ ഫയർഫോക്സിന്റെ ഈ പതിപ്പ് ഫയർഫോക്സ് സെൻഡ് ഉപയോഗിക്കുന്ന വെബ് സാങ്കേതികവിദ്യ പിന്തുണയ്ക്കുന്നില്ല. താങ്കൾ താങ്കളുടെ ബ്രൗസർ പുതുക്കേണ്ടി വരും.\nupdateFirefox = ഫയർഫോക്സ് പുതുക്കൂ\ndeletePopupCancel = റദ്ദാക്കുക\ndeleteButtonHover = നീക്കം ചെയ്യുക\nfooterLinkLegal = നിയമസംബന്ധവിവരങ്ങൾ\nfooterLinkPrivacy = സ്വകാര്യത\nfooterLinkCookies = കുക്കികൾ\npasswordTryAgain = രഹസ്യവാക്ക് തെറ്റാണ്. വീണ്ടും ശ്രമിക്കുക.\njavascriptRequired = ഫയർഫോക്സ് സെൻഡ് പ്രവർത്തിക്കാൻ ജാവാസ്ക്രിപ്റ്റ് വേണം\nwhyJavascript = ഫയർഫോക്സ് സെൻഡ് പ്രവർത്തിക്കാൻ എന്തിനാണ് ജാവാസ്ക്രിപ്റ്റ്?\nenableJavascript = ദയവായി ജാവാസ്ക്രിപ്റ്റ് പ്രവർത്തനസജ്ജമാക്കിയിട്ട് വീണ്ടും ശ്രമിക്കുക.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } മണിക്കൂർ { $minutes } മിനുട്ട്\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } മിനുട്ട്\n# A short status message shown when the user enters a long password\nmaxPasswordLength = രഹസ്യവാക്കിന്റെ പരമാവധി നീളം: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = ഈ രഹസ്യവാക്ക് ക്രമീകരിക്കാനായില്ല\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = ഫയർഫോക്സ് സെൻഡ്\n-send-short-brand = സെൻഡ്\n-firefox = ഫയർഫോക്സ്\n-mozilla = മോസില്ല\nintroTitle = ലളിതവും സ്വകാര്യവുമായ ഫയൽ പങ്കിടൽ\nintroDescription = തനിയെ കാലഹരണപ്പെടുന്ന ലിങ്ക് ഉപയോഗിച്ച്  തുടക്കം മുതല്‍ അവസാനം വരെയുള്ള എന്‍ക്രിപ്ഷന്‍ സാങ്കേതികതയോടെ ഫയലുകള്‍ പങ്കിടാന്‍ { -send-brand } ഉപയോഗിക്കാം. അത് കൊണ്ട് തന്നെ നിങ്ങള്‍ പങ്കിടുന്നത് സ്വകാര്യമായി സൂക്ഷിക്കാനും അത് ഓണ്‍ലൈനില്‍ എക്കാലവും കാണില്ലെന്ന് ഉറപ്പാക്കാനും പറ്റും.\nnotifyUploadEncryptDone = നിങ്ങളുടെ ഫയൽ എൻക്രിപ്റ്റ് ചെയ്തിരിക്കുന്നു, അയയ്ക്കാൻ തയ്യാറാണ്\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = { $downloadCount } അല്ലെങ്കിൽ { $timespan } കഴിഞ്ഞാൽ കാലഹരണപ്പെടും\ntimespanMinutes =\n    { $num ->\n        [one] മിനുട്ട്\n       *[other] { $num } മിനുട്ട്\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 ദിവസം\n       *[other] { $num } ദിവസം\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 ആഴ്ച\n       *[other] { $num } ആഴ്ച\n    }\nfileCount =\n    { $num ->\n        [one] 1 ഫയൽ\n       *[other] { $num } ഫയലുകൾ\n    }\n# byte abbreviation\nbytes = ബൈറ്റ്\n# kibibyte abbreviation\nkb = കി.ബൈ\n# mebibyte abbreviation\nmb = എംബി\n# gibibyte abbreviation\ngb = ജിബി\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = ആകെ വലിപ്പം: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = നിങ്ങളുടെ ഫയൽ പങ്കിടാനുള്ള ലിങ്ക് പകർത്തുക:\ncopyLinkButton = ലിങ്ക് പകർത്തുക\ndownloadTitle = ഫയലുകൾ ഡൗൺലോഡുചെയ്യുക\ndownloadDescription = ഈ ഫയൽ { -send-brand } ഉപയോഗിച്ച് എൻഡ്-ടു-എൻഡ് എൻക്രിപ്ഷനോടും തനിയെ കാലഹരണപ്പെടുന്ന ഒരു ലിങ്കോടും കൂടി പങ്കിട്ടതാണ്.\ntrySendDescription = ലളിതവും സുരക്ഷിതവുമായ ഫയൽ പങ്കിടലിനായി { -send-brand } പരീക്ഷിക്കുക.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] ഒരേസമയം 1 ഫയൽ മാത്രമേ അപ്‌ലോഡു ചെയ്യാൻ കഴിയൂ.\n       *[other] ഒരേസമയം { $count } ഫയലുകൾ മാത്രമേ അപ്‌ലോഡു ചെയ്യാൻ കഴിയൂ.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] ഒരു ആർക്കൈവ് മാത്രമേ അനുവദിച്ചിട്ടുള്ളൂ.\n       *[other] { $count } ആർക്കൈവുകൾ മാത്രമേ അനുവദിച്ചിട്ടുള്ളൂ.\n    }\nexpiredTitle = ഈ ലിങ്ക് കാലഹരണപ്പെട്ടു.\nnotSupportedDescription = ഈ ബ്രൌസറിൽ { -send-brand } പ്രവർത്തിക്കില്ല. { -send-short-brand } { -firefox }- ന്റെ ഏറ്റവും പുതിയ പതിപ്പിൽ വളരെ നന്നായി പ്രവർത്തിക്കുന്നു, കൂടാതെ മിക്ക ബ്രൌസറുകളുടെയും നിലവിലെ പതിപ്പിൽ പ്രവർത്തിക്കുകയും ചെയ്യും.\ndownloadFirefox = { -firefox } ഡൗണ്‍ലോഡ് ചെയ്യുക\nlegalTitle = { -send-short-brand } സ്വകാര്യതാ അറിയിപ്പ്\nlegalDateStamp = 2019 മാർച്ച് 12 തീയതിയിൽ പതിപ്പ് 1.0\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } ദിവസം { $hours } മണിക്കൂർ { $minutes } മിനിറ്റ്\naddFilesButton = അപ്‌ലോഡ് ചെയ്യാനുള്ള ഫയലുകൾ തിരഞ്ഞെടുക്കുക\nuploadButton = അപ്‍ലോഡ്\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = ഫയലുകൾ വലിച്ചിടുക\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = അല്ലെങ്കിൽ { $size } വരെ അയയ്ക്കുന്നതിന് അമർത്തുക\naddPassword = രഹസ്യവാക്ക് ഉപയോഗിച്ച് സംരക്ഷിക്കുക\nemailPlaceholder = നിങ്ങളുടെ ഇമെയിൽ നൽകുക\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = { $size } വരെയുള്ള ഫയലുകൾ അയയ്ക്കുന്നതിന് പ്രവേശിക്കുക\nsignInOnlyButton = പ്രവേശിയ്ക്കുക\naccountBenefitTitle = ഒരു { -firefox } അക്കൗണ്ട് സൃഷ്ടിക്കുക അല്ലെങ്കിൽ പ്രവേശിക്കുക\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = { $size } വരെയുള്ള ഫയലുകൾ പങ്കിടുക\naccountBenefitDownloadCount = കൂടുതൽ ആളുകളുമായി ഫയലുകൾ പങ്കിടുക\naccountBenefitTimeLimit =\n    { $count ->\n        [one] ഒരു ദിവസം വരെ ലിങ്കുകൾ സജീവമായി നിലനിർത്തുക\n       *[other] { $count } ദിവസം വരെ ലിങ്കുകൾ സജീവമായി നിലനിർത്തുക\n    }\naccountBenefitSync = ഏതൊരു ഉപകരണത്തിൽ നിന്നും പങ്കിട്ട ഫയലുകൾ കൈകാര്യം ചെയ്യുക\naccountBenefitMoz = മറ്റ് { -mozilla } സേവനങ്ങളെക്കുറിച്ച് അറിയുക\nsignOut = പുറത്തിറങ്ങുക\nokButton = ശരി\ndownloadingTitle = ഡൌണ്‍ലോഡ് ചെയ്യുന്നു\nnoStreamsWarning = ഇത്ര വലിയ ഫയൽ ബ്രൌസറില്‍ ഡീക്രിപ്റ്റ് ചെയ്യാൻ കഴിഞ്ഞേക്കില്ല.\nnoStreamsOptionCopy = മറ്റൊരു ബ്രൗസറിൽ തുറക്കുന്നതിന് ലിങ്ക് പകർത്തുക\nnoStreamsOptionFirefox = ഞങ്ങളുടെ പ്രിയപ്പെട്ട ബ്രൗസർ പരീക്ഷിക്കുക\nnoStreamsOptionDownload = ഈ ബ്രൗസറിൽ തുടരുക\ndownloadFirefoxPromo = എറ്റവും പുതിയ { -firefox } { -send-short-brand } മുഖേന നിങ്ങൾക്ക് എത്തിച്ചിരിക്കുന്നു.\n# the next line after the colon contains a file name\nshareLinkDescription = നിങ്ങളുടെ ഫയലിനുള്ള കണ്ണി പങ്കിടുക:\nshareLinkButton = കണ്ണി പങ്കിടുക\n# $name is the name of the file\nshareMessage = \"{ -send-brand }\" ഉപയോഗിച്ച് { $name } ഡൌൺലോഡ് ചെയ്യുക: ലളിതവും സുരക്ഷിതവുമായ ഫയൽ പങ്കിടൽ\n"
  },
  {
    "path": "public/locales/ms/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteSubtitle = experimen web\nsiteFeedback = Maklum balas\nuploadPageHeader = Peribadi, Perkongsian Fail Dienkrip\nuploadPageExplainer = Hantar fail melalui pautan yang selamat, peribadi dan dienkrip, yang akan luput secara automatik untuk memastikan fail anda itu tidak terus berada dalam talian selama-lamanya.\nuploadPageLearnMore = Ketahui selanjutnya\nuploadPageDropMessage = Letakkan fail anda di sini untuk mulakan memuat naik\nuploadPageSizeMessage = Untuk operasi yang paling selamat, lebih baik pastikan fail anda itu kurang 1GB\nuploadPageBrowseButton = Pilih fail dalam komputer anda\nuploadPageBrowseButton1 = Pilih fail untuk dimuat naik\nuploadPageMultipleFilesAlert = Memuat naik pelbagai fail atau satu folder masih belum disokong.\nuploadPageBrowseButtonTitle = Muat naik fail\nuploadingPageProgress = Memuat naik { $filename } ({ $size })\nimportingFile = Mengimport…\nverifyingFile = Mengesahkan...\nencryptingFile = Mengenkripsi...\ndecryptingFile = Mengenkripsi...\nnotifyUploadDone = Muat naik anda sudah siap.\nuploadingPageMessage = Setelah siap fail anda dimuat naik, akan boleh tetapkan pilihan luput.\nuploadingPageCancel = Batal muat naik\nuploadCancelNotification = Muat naik anda dibatalkan.\nuploadingPageLargeFileMessage = Fail ini besar dan mungkin mengambil masa untuk dimuat naik. Tunggu!\nuploadingFileNotification = Maklumkan saya apabila muat naik selesai.\nuploadSuccessConfirmHeader = Sedia untuk Hantar\nuploadSvgAlt = Muat naik\nuploadSuccessTimingHeader = Pautan ke fail anda akan luput selepas 1 muat turun atau dalam 24 jam.\nexpireInfo = Pautan ke fail anda akan luput selepas { $downloadCount } atau { $timespan }.\ndownloadCount =\n    { $num ->\n       *[other] { $num } muat turun\n    }\ntimespanHours =\n    { $num ->\n       *[other] { $num } jam\n    }\ncopyUrlFormLabelWithName = Salin dan kongsi pautan untuk menghantar fail anda: { $filename }\ncopyUrlFormButton = Salin ke Klipbod\ncopiedUrl = Disalin!\ndeleteFileButton = Buang Fail\nsendAnotherFileLink = Hantar fail lain\n# Alternative text used on the download link/button (indicates an action).\ndownloadAltText = Muat turun\ndownloadsFileList = Muat turun\n# Used as header in a column indicating the amount of time left before a\n# download link expires (e.g. \"10h 5m\")\ntimeFileList = Masa\n# Used as header in a column indicating the number of times a file has been\n# downloaded\ndownloadFileName = Muat turun { $filename }\ndownloadFileSize = ({ $size })\nunlockInputLabel = Masukkan Kata Laluan\nunlockInputPlaceholder = Kata laluan\nunlockButtonLabel = Buka\ndownloadFileTitle = Muat turun Fail Enkripsi\n# Send is a brand name and should not be localized.\ndownloadMessage = Rakan anda menghantar satu fail kepada anda menggunakan Send, satu perkhidmatan yang membolehkan anda berkongsi fail dengan pautan yang selamat, peribadi dan dienkrip, yang secara automatik akan luput bagi memastikan fail anda tidak terus berada dalam talian selama-lamanya.\n# Text and title used on the download link/button (indicates an action).\ndownloadButtonLabel = Muat turun\ndownloadNotification = Muat turun anda sudah siap.\ndownloadFinish = Muat turun Selesai\n# This message is displayed when uploading or downloading a file, e.g. \"(1,3 MB of 10 MB)\".\nfileSizeProgress = ({ $partialSize } daripada { $totalSize })\n# Send is a brand name and should not be localized.\nsendYourFilesLink = Cuba Send\ndownloadingPageProgress = Memuat turun { $filename } ({ $size })\ndownloadingPageMessage = Sila biarkan tab ini terbuka semasa kami mengambil fail anda dan menghuraikannya.\nerrorAltText = Ralat memuat naik\nerrorPageHeader = Ada sesuatu yang tidak kena!\nerrorPageMessage = Ada ralat semasa memuat naik fail.\nerrorPageLink = Hantar fail lain\nfileTooBig = Fail terlalu besar untuk dimuat naik. Perlu kurang daripada { $size }.\nlinkExpiredAlt = Pautan sudah luput\nexpiredPageHeader = Pautan ini sudah luput atau pun tidak pernah wujud!\nnotSupportedHeader = Pelayar anda tidak disokong.\n# Send is a brand name and should not be localized.\nnotSupportedDetail = Malangnya, pelayar ini tidak menyokong teknologi web yang melaksanakan Send. Anda perlu cuba pelayar lain. Kami syorkan Firefox!\nnotSupportedLink = Kenapa pelayar saya tidak disokong?\nnotSupportedOutdatedDetail = Malangnya versi Firefox ini tidak menyokong teknologi web yang menguasakan Send. Anda perlu mengemaskini pelayar anda.\nupdateFirefox = Kemaskini Firefox\ndownloadFirefoxButtonSub = Muat turun Percuma\nuploadedFile = Fail\ncopyFileList = Salin URL\n# expiryFileList is used as a column header\nexpiryFileList = Luput Pada\ndeleteFileList = Buang\nnevermindButton = Tak apalah\nlegalHeader = Terma & Privasi\nlegalNoticeTestPilot = Send adalah eksperimen Ujian Perintis, dan tertakluk kepada <a>Terma Perkhidmatan</a> dan <a>Notis Privasi</a> Ujian Perintis. Anda boleh ketahui selanjutnya perihal eksperimen ini dan pengumpulan data <a>di sini</a>.\nlegalNoticeMozilla = Penggunaan laman web Send juga tertakluk kepada <a>Notis Privasi Laman web</a> dan <a>Terma Penggunaan Laman web</a> Mozilla.\ndeletePopupText = Buang fail ini?\ndeletePopupYes = Ya\ndeletePopupCancel = Batal\ndeleteButtonHover = Buang\ncopyUrlHover = Salin URL\nfooterLinkLegal = Perundangan\n# Test Pilot is a proper name and should not be localized.\nfooterLinkAbout = Perihal Ujian Perintis\nfooterLinkPrivacy = Privasi\nfooterLinkTerms = Terma\nfooterLinkCookies = Kuki\nrequirePasswordCheckbox = Perlu kata laluan untuk memuat turun fail ini\naddPasswordButton = Tambah Kata laluan\nchangePasswordButton = Tukar\npasswordTryAgain = Kata laluan tidak betul. Cuba lagi.\nreportIPInfringement = Lapor Pencerobohan IP\njavascriptRequired = Send perlukan JavaScript\nwhyJavascript = Kenapa Send perlukan JavaScript?\nenableJavascript = Sila dayakan JavaScript dan cuba lagi.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when a password is successfully set\npasswordIsSet = Kata laluan ditetapkan\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Panjang kata laluan maksimum: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Kata laluan ini tidak boleh ditetapkan\n"
  },
  {
    "path": "public/locales/nb-NO/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importerer…\nencryptingFile = Krypterer...\ndecryptingFile = Dekrypterer...\ndownloadCount =\n    { $num ->\n        [one] 1 nedlasting\n       *[other] { $num } nedlastinger\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 time\n       *[other] { $num } timer\n    }\ncopiedUrl = Kopiert!\nunlockInputPlaceholder = Passord\nunlockButtonLabel = Lås opp\ndownloadButtonLabel = Last ned\ndownloadFinish = Nedlastingen er fullført.\nfileSizeProgress = ({ $partialSize } av { $totalSize })\nsendYourFilesLink = Prøv Send\nerrorPageHeader = Det oppstod en feil.\nfileTooBig = Filen er for stor til å laste opp. Det må være mindre enn { $size }.\nlinkExpiredAlt = Lenke utløpt\nnotSupportedHeader = Din nettleser er ikke støttet.\nnotSupportedLink = Hvorfor er ikke nettleseren min støttet?\nnotSupportedOutdatedDetail = Dessverre støtter ikke denne versjonen av Firefox netteknologien som driver Send. Du trenger å oppdatere nettleseren din.\nupdateFirefox = Oppdater Firefox\ndeletePopupCancel = Avbryt\ndeleteButtonHover = Slett\nfooterLinkLegal = Juridisk informasjon\nfooterLinkPrivacy = Personvern\nfooterLinkCookies = Infokapsler\npasswordTryAgain = Feil passord. Prøv igjen.\njavascriptRequired = Send krever JavaScript.\nwhyJavascript = Hvorfor krever Send JavaScript?\nenableJavascript = Slå på JavaScript og prøv igjen.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }t { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maksimum passordlengde: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Dette passordet kunne ikke settes\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Enkel, privat fildeling\nintroDescription = { -send-brand } lar deg dele filer via en tidsbegrenset lenke med ende-til-ende-kryptering. På den måten kan du dele filer privat og samtidig være trygg på at filene dine ikke blir liggende på nettet for alltid.\nnotifyUploadEncryptDone = Filen din er kryptert og klar til å sende\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Utløper etter { $downloadCount } eller { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minutt\n       *[other] { $num } minutter\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 dag\n       *[other] { $num } dager\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 uke\n       *[other] { $num } uker\n    }\nfileCount =\n    { $num ->\n        [one] 1 fil\n       *[other] { $num } filer\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Total størrelse: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopier lenken for å dele filen din:\ncopyLinkButton = Kopier lenke\ndownloadTitle = Last ned filer\ndownloadDescription = Denne filen ble delt via { -send-brand } med ende-til-ende-kryptering og en lenke som automatisk utløper.\ntrySendDescription = Prøv { -send-brand } for enkel, sikker fildeling.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Kun 1 fil kan lastes opp om gangen.\n       *[other] Kun { $count } filer kan lastes opp om gangen.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Kun 1 arkiv er tillatt.\n       *[other] Kun { $count } arkiver er tillatt.\n    }\nexpiredTitle = Denne lenken er utløpt.\nnotSupportedDescription = { -send-brand } virker ikke med denne nettleseren. { -send-short-brand } fungerer best med den nyeste versjonen av { -firefox }, og vil fungere med den nyeste versjonen av de fleste nettlesere.\ndownloadFirefox = Last ned { -firefox }\nlegalTitle = { -send-short-brand } Personvernerklæring\nlegalDateStamp = Versjon 1.0, datert den 12. mars 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }t { $minutes }m\naddFilesButton = Velg filer du vil laste opp\ntrustWarningMessage = Forsikre deg om at du stoler på mottakeren din når du deler sensitive data.\nuploadButton = Last opp\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Dra og slipp filer\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = eller klikk for å sende filer på opptil { $size }\naddPassword = Beskytt med passord\nemailPlaceholder = Skriv inn e-postadressen din\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Logg inn for å sende opptil { $size }\nsignInOnlyButton = Logg inn\naccountBenefitTitle = Opprett en { -firefox }-konto eller logg inn\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Del filer på opptil { $size }\naccountBenefitDownloadCount = Del filer med flere personer\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Hold lenker aktiv opptil 1 dag\n       *[other] Hold lenker aktiv opptil { $count } dager\n    }\naccountBenefitSync = Behandle delte filer fra en hvilken som helst enhet\naccountBenefitMoz = Les om andre { -mozilla }-tjenester\nsignOut = Logg ut\nokButton = OK\ndownloadingTitle = Laster ned\nnoStreamsWarning = Denne nettleseren kan kanskje ikke dekryptere en så stor fil.\nnoStreamsOptionCopy = Kopier lenken for å åpne den i en annen nettleser\nnoStreamsOptionFirefox = Prøv favorittnettleseren vår\nnoStreamsOptionDownload = Fortsett med denne nettleseren\ndownloadFirefoxPromo = { -send-short-brand } presenteres for deg av den helt nye { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Del lenken til filen din:\nshareLinkButton = Del lenke\n# $name is the name of the file\nshareMessage = Last ned ‹{ $name }› med { -send-brand }: enkel, trygg fildeling\ntrailheadPromo = Det finnes en måte å ta vare på personvernet ditt. Bruk Firefox.\nlearnMore = Les mer.\ndownloadFlagged = Denne koblingen er deaktivert på grunn av brudd på vilkårene for tjenesten.\ndownloadConfirmTitle = En ting til\ndownloadConfirmDescription = Forsikre deg om at du stoler på personen som sendte deg denne filen, fordi vi ikke kan bekrefte at den ikke vil skade enheten din.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Jeg stoler på personen som sendte denne filen\n       *[other] Jeg stoler på personen som sendte disse filene\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Rapporter denne filen som mistenkelig\n       *[other] Rapporter disse filene som mistenkelige\n    }\nreportDescription = Hjelp oss å forstå hva som skjer. Hva tror du er galt med disse filene?\nreportUnknownDescription = Gå til adressen til lenken du ønsker å rapportere, og klikk «{ reportFile }».\nreportButton = Rapporter\nreportReasonMalware = Disse filene inneholder skadelig programvare eller er del av et nettfiskingsangrep (phishing-angrep).\nreportReasonPii = Disse filene inneholder personlig identifiserbar informasjon om meg.\nreportReasonAbuse = Disse filene inneholder ulovlig eller voldelig innhold.\nreportReasonCopyright = For å rapportere brudd på opphavsrett eller varemerke, bruk prosessen som er beskrevet på <a>denne siden</a>.\nreportedTitle = Filer rapportert\nreportedDescription = Takk skal du ha. Vi har mottatt rapporten din om disse filene.\n"
  },
  {
    "path": "public/locales/nl/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importeren…\nencryptingFile = Versleutelen…\ndecryptingFile = Ontsleutelen…\ndownloadCount =\n    { $num ->\n        [one] 1 download\n       *[other] { $num } downloads\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 uur\n       *[other] { $num } uur\n    }\ncopiedUrl = Gekopieerd!\nunlockInputPlaceholder = Wachtwoord\nunlockButtonLabel = Ontgrendelen\ndownloadButtonLabel = Downloaden\ndownloadFinish = Downloaden voltooid\nfileSizeProgress = ({ $partialSize } van { $totalSize })\nsendYourFilesLink = Send proberen\nerrorPageHeader = Er is iets misgegaan!\nfileTooBig = Dat bestand is te groot om te worden geüpload. Het moet kleiner zijn dan { $size }.\nlinkExpiredAlt = Koppeling verlopen\nnotSupportedHeader = Uw browser wordt niet ondersteund.\nnotSupportedLink = Waarom wordt mijn browser niet ondersteund?\nnotSupportedOutdatedDetail = Helaas ondersteunt deze versie van Firefox de webtechnologie die Send gebruikt niet. U dient uw browser bij te werken.\nupdateFirefox = Firefox bijwerken\ndeletePopupCancel = Annuleren\ndeleteButtonHover = Verwijderen\nfooterLinkLegal = Juridisch\nfooterLinkPrivacy = Privacy\nfooterLinkCookies = Cookies\npasswordTryAgain = Onjuist wachtwoord. Probeer het opnieuw.\njavascriptRequired = Send vereist JavaScript\nwhyJavascript = Waarom vereist Send JavaScript?\nenableJavascript = Schakel JavaScript in en probeer het opnieuw.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }u { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maximale wachtwoordlengte: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Dit wachtwoord kon niet worden ingesteld\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Eenvoudig, privé bestanden delen\nintroDescription = Met { -send-brand } kunt u bestanden delen met end-to-endversleuteling en een koppeling die automatisch verloopt. Hierdoor kunt u privé houden wat u wilt delen en er zeker van zijn dat uw zaken niet voor altijd online blijven.\nnotifyUploadEncryptDone = Uw bestand is versleuteld en klaar voor verzending\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Verloopt na { $downloadCount } of { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuut\n       *[other] { $num } minuten\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 dag\n       *[other] { $num } dagen\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 week\n       *[other] { $num } weken\n    }\nfileCount =\n    { $num ->\n        [one] 1 bestand\n       *[other] { $num } bestanden\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Totale grootte: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopieer de koppeling om uw bestand te delen:\ncopyLinkButton = Koppeling kopiëren\ndownloadTitle = Bestanden downloaden\ndownloadDescription = Dit bestand is gedeeld via { -send-brand } met end-to-endversleuteling en een koppeling die automatisch verloopt.\ntrySendDescription = Probeer { -send-brand } voor eenvoudig, veilig bestanden delen.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Er kan slechts één bestand tegelijk worden geüpload.\n       *[other] Er kunnen slechts { $count } bestanden tegelijk worden geüpload.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Slechts één archief is toegestaan.\n       *[other] Slechts { $count } archieven zijn toegestaan.\n    }\nexpiredTitle = Deze koppeling is verlopen.\nnotSupportedDescription = { -send-brand } werkt niet met deze browser. { -send-short-brand } werkt het beste met de nieuwste versie van { -firefox }, en werkt met de huidige versie van de meeste browsers.\ndownloadFirefox = { -firefox } downloaden\nlegalTitle = Privacybeleid van { -send-short-brand }\nlegalDateStamp = Versie 1.0 d.d. 12 maart 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }u { $minutes }m\naddFilesButton = Selecteer te uploaden bestanden\ntrustWarningMessage = Zorg ervoor dat u uw ontvanger vertrouwt wanneer u gevoelige gegevens deelt.\nuploadButton = Uploaden\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Versleep bestanden\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = of klik om tot { $size } te versturen\naddPassword = Beveiligen met wachtwoord\nemailPlaceholder = Voer uw e-mailadres in\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Meld u aan om tot { $size } te versturen\nsignInOnlyButton = Aanmelden\naccountBenefitTitle = Maak een { -firefox }-account of meld u aan\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Bestanden tot { $size } delen\naccountBenefitDownloadCount = Bestanden met meerdere personen delen\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Koppelingen tot één dag actief houden\n       *[other] Koppelingen tot { $count } dagen actief houden\n    }\naccountBenefitSync = Gedeelde bestanden vanaf andere apparaten beheren\naccountBenefitMoz = Info over andere services van { -mozilla }\nsignOut = Afmelden\nokButton = OK\ndownloadingTitle = Downloaden\nnoStreamsWarning = Deze browser kan een bestand van deze omvang mogelijk niet ontcijferen.\nnoStreamsOptionCopy = Koppeling kopiëren om in een andere browser te openen\nnoStreamsOptionFirefox = Onze favoriete browser proberen\nnoStreamsOptionDownload = Doorgaan met deze browser\ndownloadFirefoxPromo = { -send-short-brand } wordt u aangeboden door het volledig vernieuwde { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Deel de koppeling naar uw bestand:\nshareLinkButton = Koppeling delen\n# $name is the name of the file\nshareMessage = Download ‘{ $name }’ met { -send-brand }: eenvoudig, veilig bestanden delen\ntrailheadPromo = Er is een manier om uw privacy te beschermen. Doe mee met Firefox.\nlearnMore = Meer info.\ndownloadFlagged = Deze koppeling is uitgeschakeld wegens schending van de servicevoorwaarden.\ndownloadConfirmTitle = Nog een ding\ndownloadConfirmDescription = Zorg ervoor dat u de persoon vertrouwt die u dit bestand heeft gestuurd, omdat we niet kunnen verifiëren dat het uw apparaat niet zal schaden.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Ik vertrouw de persoon die dit bestand heeft verzonden\n       *[other] Ik vertrouw de persoon die deze bestanden heeft verzonden\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Dit bestand als verdacht rapporteren\n       *[other] Deze bestanden als verdacht rapporteren\n    }\nreportDescription = Help ons te begrijpen wat er aan de hand is. Wat is er volgens u mis met deze bestanden?\nreportUnknownDescription = Ga naar de URL van de koppeling die u wilt melden en klik op ‘{ reportFile }’.\nreportButton = Rapporteren\nreportReasonMalware = Deze bestanden bevatten malware of zijn onderdeel van een phishingaanval.\nreportReasonPii = Deze bestanden bevatten persoonlijk identificeerbare informatie over mij.\nreportReasonAbuse = Deze bestanden bevatten illegale of beledigende inhoud.\nreportReasonCopyright = Gebruik de procedure op <a>deze pagina</a> om inbreuk op auteursrechten of handelsmerken te melden.\nreportedTitle = Bestanden gerapporteerd\nreportedDescription = Dank u. We hebben uw rapport over deze bestanden ontvangen.\n"
  },
  {
    "path": "public/locales/nn-NO/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importerer…\nencryptingFile = Krypterer…\ndecryptingFile = Dekrypterer...\ndownloadCount =\n    { $num ->\n        [one] 1 nedlasting\n       *[other] { $num } nedlastingar\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 time\n       *[other] { $num } timar\n    }\ncopiedUrl = Kopiert!\nunlockInputPlaceholder = Passord\nunlockButtonLabel = Lås opp\ndownloadButtonLabel = Last ned\ndownloadFinish = Nedlastinga er fullført.\nfileSizeProgress = ({ $partialSize } av { $totalSize })\nsendYourFilesLink = Prøv Send\nerrorPageHeader = Noko gjekk gale!\nfileTooBig = Fila er for stor, og kan ikkje lastast opp. Ho må vere mindre enn { $size }.\nlinkExpiredAlt = Lenka har gått ut\nnotSupportedHeader = Nettlesaren din er ikkje støtta.\nnotSupportedLink = Kvifor er ikkje nettlesaren min støtta?\nnotSupportedOutdatedDetail = Dessverre støttar ikkje denne versjonen av Firefox nett-teknologien som driv Send. Du må å oppdatere nettlesaren din.\nupdateFirefox = Oppdater Firefox\ndeletePopupCancel = Avbryt\ndeleteButtonHover = Slett\nfooterLinkLegal = Juridisk informasjon\nfooterLinkPrivacy = Personvern\nfooterLinkCookies = Infokapslar\npasswordTryAgain = Feil passord. Prøv på nytt.\njavascriptRequired = Send krev JavaScript.\nwhyJavascript = Kvifor krev Send JavaScript?\nenableJavascript = Slå på JavaScript og prøv igjen.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }t { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maksimum passordlengde: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Dette passordet kunne ikkje stillast inn\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Enkel, privat fildeling\nintroDescription = { -send-brand } lèt deg dele filer via ei tidsavgrensa lenke med ende-til-ende-kryptering. På den måten kan du dele filer privat og samstundes vere trygg på at det ikkje ligg på nettet for alltid.\nnotifyUploadEncryptDone = Fila di er kryptert og klar til å bli sendt\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Går ut etter { $downloadCount } eller { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minutt\n       *[other] { $num } minutt\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 dag\n       *[other] { $num } dagar\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 veke\n       *[other] { $num } veker\n    }\nfileCount =\n    { $num ->\n        [one] 1 fil\n       *[other] { $num } filer\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Total storleik: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopier lenka for å dele fila di:\ncopyLinkButton = Kopier lenke\ndownloadTitle = Last ned filer\ndownloadDescription = Denne fila vart delt via { -send-brand }, med ende-til-ende-kryptering, og ei lenke som automatisk går ut.\ntrySendDescription = Prøv { -send-brand } for enkel og sikker fildeling.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Berre 1 fil  kan lastast opp om gongen.\n       *[other] Berre { $count } filer kan lastast opp om gongen.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Berre 1 arkiv er lov.\n       *[other] Berre { $count } arkiv er lov.\n    }\nexpiredTitle = Denne lenka har gått ut.\nnotSupportedDescription = { -send-brand } fungerer ikkje med denne nettlesaren. { -send-short-brand } fungerer best med siste versjon av { -firefox } og med dei fleste andre nye nettlesarar.\ndownloadFirefox = Last ned { -firefox }\nlegalTitle = { -send-short-brand }, om personvernpraksis\nlegalDateStamp = Versjon 1.0, datert den 12 mars 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }t { $minutes }m\naddFilesButton = Vel filer som skal lastast opp\ntrustWarningMessage = Forsikre deg om at du stolar på mottakaren din når du deler sensitive data.\nuploadButton = Last opp\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Dra og slepp filer\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = eller klikk for å sende filer på opptil { $size }\naddPassword = Vern med passord\nemailPlaceholder = Skriv inn e-postadressa di\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Logg inn for å sende filer på opptil { $size }\nsignInOnlyButton = Logg inn\naccountBenefitTitle = Lag ein { -firefox }-konto eller logg inn\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Del filer på opptil { $size }\naccountBenefitDownloadCount = Del filer med fleire personar\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Hald lenka aktiv opptil 1 dag\n       *[other] Hald lenker aktive opptil { $count } dagar\n    }\naccountBenefitSync = Handter delte filer frå kva som helst eining\naccountBenefitMoz = Les om andre { -mozilla }-tenster\nsignOut = Logg ut\nokButton = OK\ndownloadingTitle = Lastar ned\nnoStreamsWarning = Denne nettlesaren kan kanskje ikkje dekryptere ei så stor fil.\nnoStreamsOptionCopy = Kopier lenka for å opne henne i ein annan nettlesar\nnoStreamsOptionFirefox = Prøv favorittnettlesaren vår\nnoStreamsOptionDownload = Fortset med denne nettlesaren\ndownloadFirefoxPromo = { -send-short-brand } vert presentert for deg av den heilt nye { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Del lenka til fila di:\nshareLinkButton = Del lenke\n# $name is the name of the file\nshareMessage = Last ned \"{ $name }\" med { -send-brand }: enkel, trygg fildelning\ntrailheadPromo = Det finst ein måte å ta vare på personvernet ditt. Ver med Firefox på ferda.\nlearnMore = Les meir.\ndownloadFlagged = Denne koplinga er deaktivert på grunn av brot på vilkåra for tenesta.\ndownloadConfirmTitle = Ein ting til\ndownloadConfirmDescription = Forsikre deg om at du stolar på personen som sende deg denne fila fordi, vi ikkje kan stadfeste at ho ikkje vil skade eininga di.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Eg stolar på personen som sende denne fila\n       *[other] Eg stolar på personen som sende desse filene\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Rapporter denne fila som mistenkjeleg\n       *[other] Rapporter desse filene som mistenkjelege\n    }\nreportDescription = Hjelp oss å forstå kva som skjer. Kva trur du er gale med desse filene?\nreportUnknownDescription = Gå til lenkeadressa du ønskjer å rapportere, og klikk «{ reportFile }».\nreportButton = Rapporter\nreportReasonMalware = Desse filene inneheld skadeleg programvare eller er del av eit nettfiskingsangrep (phishing-angrep).\nreportReasonPii = Desse filene inneheld personleg identifiserbar informasjon om meg.\nreportReasonAbuse = Desse filene inneheld ulovleg eller valdeleg innhald.\nreportReasonCopyright = For å rapportere brot på opphavsrett eller varemerke, bruk prosessen som er beskriven på <a>denne sida</a>.\nreportedTitle = Rapporterte filer\nreportedDescription = Takk skal du ha. Vi har fått rapporten din om desse filene.\n"
  },
  {
    "path": "public/locales/oc/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importacion…\nencryptingFile = Chiframent…\ndecryptingFile = Deschiframent…\ndownloadCount =\n    { $num ->\n        [one] 1 telecargament\n       *[other] { $num } telecargaments\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 ora\n       *[other] { $num } oras\n    }\ncopiedUrl = Copiat !\nunlockInputPlaceholder = Senhal\nunlockButtonLabel = Desverrolhar\ndownloadButtonLabel = Telecargar\ndownloadFinish = Telecargament acabat\nfileSizeProgress = ({ $partialSize } sus { $totalSize })\nsendYourFilesLink = Ensajar Send\nerrorPageHeader = I a quicòm que truca.\nfileTooBig = Aqueste fichièr es tròp gròs per l’enviar. Sa talha deu èsser inferiora a { $size }.\nlinkExpiredAlt = Lo ligam a expirat\nnotSupportedHeader = Vòstre navegador es pas compatible.\nnotSupportedLink = Perqué mon navegador es pas compatible ?\nnotSupportedOutdatedDetail = Aquesta version de Firefox es pas compatibla amb la tecnologia web amb la quala fonciona Send. Vos cal metre a jorn lo navegador.\nupdateFirefox = Metre a jorn Firefox\ndeletePopupCancel = Anullar\ndeleteButtonHover = Suprimir\nfooterLinkLegal = Mencions legalas\nfooterLinkPrivacy = Vida privada\nfooterLinkCookies = Cookies\npasswordTryAgain = Senhal incorrècte. Tornatz ensajar.\njavascriptRequired = Send requesís JavaScript\nwhyJavascript = Perque Send requesís JavaScript ?\nenableJavascript = Volgatz activar lo JavaScript e ensajatz tornamai.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } h { $minutes } min\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } min\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Talha maximala del senhal : { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Aqueste senhal a pas pogut èsser definit\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Partatge simple e privat de fichièrs\nintroDescription = { -send-brand } vos permet de partejar de fichièr amb un chiframent del cap a la fin e un ligam qu’expira automaticament. Atal podètz gardar  privat çò que partejatz e vos assegurar que demorarà pas en linha per totjorn.\nnotifyUploadEncryptDone = Vòstre fichièr es chifrat e prèst per mandadís\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Expira aprèp { $downloadCount } o { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuta\n       *[other] { $num } minutas\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 jorn\n       *[other] { $num } jorns\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 setmana\n       *[other] { $num } setmanas\n    }\nfileCount =\n    { $num ->\n        [one] 1 fichièr\n       *[other] { $num } fichièrs\n    }\n# byte abbreviation\nbytes = o\n# kibibyte abbreviation\nkb = Ko\n# mebibyte abbreviation\nmb = Mo\n# gibibyte abbreviation\ngb = Go\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Talha totala : { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copiatz lo ligam per partejar vòstre fichièr :\ncopyLinkButton = Copiar lo ligam\ndownloadTitle = Telecargar los fichièrs\ndownloadDescription = Aqueste fichièr foguèt partejat via { -send-brand } amb chiframent del cap a la fin e un ligam qu’expira automaticament.\ntrySendDescription = Ensajatz { -send-brand } per un partiment de fichièrs simple e segur.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Òm pòt pas qu’enviar 1 fichièr al còp.\n       *[other] Òm pòt pas qu’enviar { $count } fichièrs al còp.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Pas qu’un archiu es autorizat.\n       *[other] Pas que { $count } archius son autorizats.\n    }\nexpiredTitle = Aqueste ligam a expirat.\nnotSupportedDescription = { -send-brand } foncionarà pas amb aqueste navegador. { -send-short-brand } fonciona melhor amb la darrièra version de { -firefox } e foncionarà amb la version mai recenta de la màger part dels navegadors.\ndownloadFirefox = Telecargar { -firefox }\nlegalTitle = Avís de confidencialitat de { -send-short-brand }\nlegalDateStamp = Version 1.0 del 12 de març de 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } j { $hours } h { $minutes } min\naddFilesButton = Seleccionatz los fichièrs de mandar\ntrustWarningMessage = Asseguratz-vos que vos fisatz del destinari quand partejatz de donadas confidencialas.\nuploadButton = Enviar\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Lisatz-depausatz de fichièrs\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = o clicatz per enviar fins a { $size }\naddPassword = Protegir amb un senhal\nemailPlaceholder = Picatz vòstra adreça electronica\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Connectatz-vos per enviar fins a { $size }\nsignInOnlyButton = Connexion\naccountBenefitTitle = Creatz un compte { -firefox } o connectatz-vos\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Partejatz de fichièrs fins a { $size }\naccountBenefitDownloadCount = Partejatz de fichièrs amb mai de personas\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Mantenètz los ligams actius fins a 1 jorn\n       *[other] Mantenètz los ligams actius fins a { $count } jorns\n    }\naccountBenefitSync = Gerissètz los fichièrs partejats de qualque siá periferic estant\naccountBenefitMoz = Aprenètz-ne mai suls autres servicis { -mozilla }\nsignOut = Desconnexion\nokButton = D'acòrd\ndownloadingTitle = Telecargament\nnoStreamsWarning = Pòt arribar qu’aqueste navegador pòsca pas deschifrar un fichièr tan gròs.\nnoStreamsOptionCopy = Copiatz lo ligam per lo dobrir dins un autre navegador\nnoStreamsOptionFirefox = Ensajatz nòstre navegador preferit\nnoStreamsOptionDownload = Contunhar amb aqueste navegador\ndownloadFirefoxPromo = Lo nòu { -firefox } vos provesís { -send-short-brand }.\n# the next line after the colon contains a file name\nshareLinkDescription = Partejatz lo ligam cap a vòstre fichièr :\nshareLinkButton = Partejar lo ligam\n# $name is the name of the file\nshareMessage = Telecargar « { $name } » amb { -send-brand } : un biais simple e segur de partejar de fichièrs.\ntrailheadPromo = Existís un biais de protegir vòstra vida privada. Rejonhètz Firefox.\nlearnMore = Ne saber mai.\ndownloadFlagged = Aqueste ligam foguèt desactivat a causa d’una infraccions a las condicions d’utilizacion.\ndownloadConfirmTitle = Un quicomet mai\ndownloadConfirmDescription = Asseguratz-vos que la persona que vos mandèt aqueste fichièr perque podèm pas verificar qu’es pas malfasent per vòstre periferic\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Me fisi de la persona que me mandèt lo fichièr\n       *[other] Me fisi de la persona que me mandèt los fichièrs\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Senhalar aqueste fichièr coma suspècte\n       *[other] Senhalar aquestes fichièrs coma suspèctes\n    }\nreportDescription = Ajudatz-nos a comprendre qué passa. Qué vos fa pensar que quicòm truca amb aquestes fichièrs ?\nreportUnknownDescription = Anatz a l’URL del ligam que volètz senhalar e clicatz « { reportFile } ».\nreportButton = Senhalar\nreportReasonMalware = Aquestes fichièrs contenon de logicials malvolents o forman part d’un atac de pesca electronica.\nreportReasonPii = Aquestes fichièrs contenon d’informacions d’identificacion personala que me concernisson.\nreportReasonAbuse = Aquestes fichièrs contenon de contengut illegal o abusiu.\nreportReasonCopyright = Per senhalar una violacion de drech d’autor o de marca, seguissètz la procedura descricha sus <a>aquesta pagina</a>.\nreportedTitle = Fichièrs senhalats\nreportedDescription = Mercés. Avèm recebut vòstre senhalament d’aquestes fichièrs.\n"
  },
  {
    "path": "public/locales/pa-IN/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = ...ਦਰਾਮਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ\nencryptingFile = ...ਇੰਕ੍ਰਿਪਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ\ndecryptingFile = ...ਡਿਕ੍ਰਿਪਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ\ndownloadCount =\n    { $num ->\n        [one] 1 ਡਾਊਨਲੋਡ\n       *[other] { $num } ਡਾਊਨਲੋਡ\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 ਘੰਟਾ\n       *[other] { $num } ਘੰਟੇ\n    }\ncopiedUrl = ਨਕਲ ਕੀਤਾ!\nunlockInputPlaceholder = ਪਾਸਵਰਡ\nunlockButtonLabel = ਅਣ-ਲਾਕ ਕਰੋ\ndownloadButtonLabel = ਡਾਊਨਲੋਡ ਕਰੋ\ndownloadFinish = ਡਾਊਨਲੋਡ ਪੂਰਾ ਹੋਇਆ\nfileSizeProgress = ({ $totalSize } ਵਿੱਚੋਂ { $partialSize })\nsendYourFilesLink = Send ਵਰਤੋ\nerrorPageHeader = ਕੁਝ ਗਲਤ ਵਾਪਰਿਆ!\nfileTooBig = ਇਹ ਫਾਇਲ ਅੱਪਲੋਡ ਕਰਨ ਲਈ ਬਹੁਤ ਵੱਡੀ ਹੈ। ਇਸ { $size } ਤੋਂ ਘੱਟ ਚਾਹੀਦੀ ਹੈ\nlinkExpiredAlt = ਲਿੰਕ ਦੀ ਮਿਆਦ ਪੁੱਗੀ\nnotSupportedHeader = ਤੁਹਾਡਾ ਬਰਾਊਜ਼ਰ ਸਹਾਇਕ ਨਹੀਂ ਹੈ।\nnotSupportedLink = ਮੇਰਾ ਬਰਾਊਜ਼ਰ ਸਹਾਇਕ ਕਿਉ ਨਹੀਂ ਹੈ?\nnotSupportedOutdatedDetail = ਅਫ਼ਸੋਸ ਹੈ ਕਿ ਫਾਇਰਫਾਕਸ ਦਾ ਇਹ ਵਰਜ਼ਨ ਵੈੱਬ ਤਕਨਾਲੋਜੀ ਲਈ ਸਹਾਇਕ ਨਹੀਂ ਹੈ, ਜੋ ਕਿ Send ਨੂੰ ਬਣਾਉਂਦੀਆਂ ਹਨ। ਤੁਹਾਨੂੰ ਆਪਣੇ ਬਰਾਊਜ਼ਰ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਦੀ ਲੋੜ ਹੋਵੇਗੀ।\nupdateFirefox = ਫਾਇਰਫਾਕਸ ਅੱਪਡੇਟ ਕਰੋ\ndeletePopupCancel = ਰੱਦ ਕਰੋ\ndeleteButtonHover = ਹਟਾਓ\nfooterLinkLegal = ਕਨੂੰਨ\nfooterLinkPrivacy = ਪਰਦੇਦਾਰੀ\nfooterLinkCookies = ਕੂਕੀਜ਼\npasswordTryAgain = ਗਲਤ ਪਾਸਵਰਡ ਹੈ। ਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰੋ।\njavascriptRequired = Send ਲਈ ਜਾਵਾ-ਸਕ੍ਰਿਪਟ ਚਾਹੀਦੀ ਹੈ\nwhyJavascript = Send ਨੂੰ ਜਾਵਾ-ਸਕ੍ਰਿਪਟ ਦੀ ਲੋੜ ਕਿਓ ਹੈ?\nenableJavascript = ਜਾਵਾ-ਸਕ੍ਰਿਪਟ ਸਮਰੱਥ ਕਰੋ ਤੇ ਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰੋ।\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }ਘੰ { $minutes }ਮਿੰ\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }ਮਿੰ\n# A short status message shown when the user enters a long password\nmaxPasswordLength = ਵੱਧ ਤੋਂ ਵੱਧ ਪਾਸਵਰਡ ਦੀ ਲੰਬਾਈ: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = ਇਹ ਪਾਸਵਰਡ ਸੈੱਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = ਭੇਜੋ\n-firefox = ਫਾਇਰਫਾਕਸ\n-mozilla = ਮੋਜ਼ੀਲਾ\nintroTitle = ਸੌਖਾ, ਪ੍ਰਾਈਵੇਟ ਫਾਇਲ ਸਾਂਝਾ ਕਰਨਾ\nintroDescription = { -send-brand } ਤੁਹਾਨੂੰ ਸਿਰੇ-ਤੋਂ-ਸਿਰੇ ਤੱਕ ਇੰਕ੍ਰਿਪਸ਼ਨ ਨਾਲ ਫਾਇਲਾਂ ਸਾਂਝੀਆਂ ਕਰਨ ਦਿੰਦਾ ਹੈ ਅਤੇ ਲਿੰਕ ਦੀ ਮਿਆਦ ਆਪਣੇ ਆਪ ਪੁੱਗ ਜਾਂਦੀ ਹੈ। ਇਸ ਕਰਕੇ ਤੁਸੀਂ ਤੁਹਾਡੇ ਵਲੋਂ ਸਾਂਝੇ ਕੀਤੇ ਨੂੰ ਨਿੱਜੀ ਬਣਾਈ ਰੱਖਦੇ ਹੋ ਅਤੇ ਪੱਕਾ ਕਰਦੇ ਹੋ ਕਿ ਤੁਹਾਡਾ ਸਾਮਾਨ ਹਮੇਸ਼ਾਂ ਆਨਲਾਈਨ ਨਹੀਂ ਰਹਿੰਦਾ ਹੈ।\nnotifyUploadEncryptDone = ਤੁਹਾਡਾ ਫਾਇਲ ਇੰਕ੍ਰਿਪਟ ਕੀਤੀ ਗਈ ਤੇ ਭੇਜਣ ਲਈ ਤਿਆਰ ਹੈ\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = { $downloadCount } ਜਾਂ { $timespan } ਦੇ ਬਾਅਦ ਮਿਆਦ ਪੁੱਗਦੀ ਹੈ\ntimespanMinutes =\n    { $num ->\n        [one] 1 ਮਿੰਟ\n       *[other] { $num } ਮਿੰਟ\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 ਦਿਨ\n       *[other] { $num } ਦਿਨ\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 ਹਫ਼ਤਾ\n       *[other] { $num } ਹਫ਼ਤੇ\n    }\nfileCount =\n    { $num ->\n        [one] 1 ਫ਼ਾਇਲ\n       *[other] { $num } ਫ਼ਾਇਲ\n    }\n# byte abbreviation\nbytes = ਬਾਈਟ\n# kibibyte abbreviation\nkb = ਕਿਲੋਬਾਈਟ\n# mebibyte abbreviation\nmb = ਮੈਗਾਬਾਈਟ\n# gibibyte abbreviation\ngb = ਗੀਗਾਬਾਈਟ\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = ਕੁੱਲ ਆਕਾਰ: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = ਆਪਣੀ ਫਾਇਲ ਸਾਂਝਾ ਕਰਨ ਲਈ ਲਿੰਕ ਨੂੰ ਕਾਪੀ ਕਰੋ:\ncopyLinkButton = ਲਿੰਕ ਕਾਪੀ ਕਰੋ\ndownloadTitle = ਫਾਇਲਾਂ ਡਾਊਨਲੋਡ ਕਰੋ\ndownloadDescription = ਇਹ ਫਾਇਲ ਨੂੰ ਸਿਰੇ-ਤੋਂ-ਸਿਰੇ ਤੱਕ ਇੰਕ੍ਰਿਪਟ ਕਰਕੇ { -send-brand } ਸਾਂਝਾ ਕੀਤਾ ਗਿਆ ਸੀ ਅਤੇ ਲਿੰਕ ਆਪਣੇ-ਆਪ ਮਿਆਦ ਪੁੱਗਦੀ ਹੈ।\ntrySendDescription = ਸੌਖਾ, ਸੁਰੱਖਿਅਤ ਫਾਇਲਾਂ ਸਾਂਝੀਆਂ ਕਰਨ ਲਈ { -send-brand } ਵਰਤ ਕੇ ਵੇਕੋ।\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] ਇੱਕ ਵੇਲੇ ਸਿਰਫ਼ 1 ਫਾਇਲ ਹੀ ਅੱਪਲੋਡ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ।\n       *[other] ਇੱਕ ਵੇਲੇ ਸਿਰਫ਼ { $count } ਫਾਇਲਾਂ ਨੂੰ ਅੱਪਲੋਡ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] ਸਿਰਫ਼ 1 ਅਕਾਇਵ ਦੀ ਇਜਾਜ਼ਤ ਹੈ।\n       *[other] ਸਿਰਫ਼ { $count } ਅਕਾਇਵਾਂ ਦੀ ਇਜਾਜ਼ਤ ਹੈ।\n    }\nexpiredTitle = ਇਹ ਲਿੰਕ ਦੀ ਮਿਆਦ ਪੁੱਗੀ ਹੈ।\nnotSupportedDescription = { -send-brand } ਇਸ ਬਰਾਊਜ਼ਰ ਨਾਲ ਕੰਮ ਨਹੀਂ ਕਰਦਾ ਹੈ। { -send-short-brand } { -firefox } ਦੇ ਨਵੇਂ ਵਰਜ਼ਨ ਨਾਲ ਸਭ ਤੋਂ ਵਧੀਆ ਕੰਮ ਕਰਦਾ ਹੈ ਅਤੇ ਬਹੁਤੇ ਬਰਾਊਜ਼ਰ ਦੇ ਮੌਜੂਦਾ ਵਰਜ਼ਨ ਨਾਲ ਕੰਮ ਕਰਦਾ ਹੈ।\ndownloadFirefox = { -firefox } ਡਾਊਨਲੋਡ ਕਰੋ\nlegalTitle = { -send-short-brand } ਪਰਦੇਦਾਰੀ ਸੂਚਨਾ\nlegalDateStamp = ਵਰਜ਼ਨ 1.0, ਮਿਤੀ 12 ਮਾਰਚ 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } ਦਿਨ { $hours } ਘੰ { $minutes } ਮਿੰ\naddFilesButton = ਚੁਣੀਆਂ ਫਾਇਲਾਂ ਅੱਪਲੋਡ ਕਰੋ\nuploadButton = ਅੱਪਲੋਡ ਕਰੋ\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = ਫਾਇਲਾਂ ਖਿੱਚੋ ਅਤੇ ਸੁੱਟੋ\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = ਜਾਂ { $size } ਤੱਕ ਭੇਜਣ ਲਈ ਕਲਿੱਕ ਕਰੋ\naddPassword = ਪਾਸਵਰਡ ਨਾਲ ਸੁਰੱਖਿਅਤ ਕਰੋ\nemailPlaceholder = ਆਪਣੀ ਈਮੇਲ ਦਿਓ\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = { $size } ਤੱਕ ਭੇਜਣ ਲਈ ਸਾਇਨ ਅੱਪ ਕਰੋ\nsignInOnlyButton = ਸਾਇਨ ਇਨ\naccountBenefitTitle = { -firefox } ਖਾਤਾ ਬਣਾਓ ਜਾਂ ਸਾਇਨ ਕਰੋ\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = { $size } ਤੱਕ ਫਾਇਲਾਂ ਸਾਂਝੀਆਂ ਕਰੋ\naccountBenefitDownloadCount = ਹੋਰ ਲੋਕਾਂ ਨਾਲ ਫਾਇਲਾਂ ਸਾਂਝੀਆਂ ਕਰੋ\naccountBenefitTimeLimit =\n    { $count ->\n        [one] ਲਿੰਕਾਂ ਨੂੰ  1 ਦਿਨ ਲਈ ਸਰਗਰਮ ਰੱਖੋ\n       *[other] ਲਿੰਕਾਂ ਨੂੰ { $count } ਦਿਨਾਂ ਲਈ ਸਰਗਰਮ ਰੱਖੋ\n    }\naccountBenefitSync = ਕਿਸੇ ਵੀ ਡਿਵਾਇਸ ਤੋਂ ਸਾਂਝੀਆਂ ਕੀਤੀਆਂ ਫਾਇਲਾਂ ਦਾ ਬੰਦੋਬਸਤ ਕਰੋ\naccountBenefitMoz = ਹੋਰ { -mozilla } ਸੇਵਾਵਾਂ ਬਾਰੇ ਜਾਣੋ\nsignOut = ਸਾਈਨ ਆਉਟ\nokButton = ਠੀਕ ਹੈ\ndownloadingTitle = ਡਾਊਨਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ\nnoStreamsWarning = ਇਹ ਬਰਾਊਜ਼ਰ ਨੂੰ ਇਸ ਵੱਡੀ ਫਾਇਲ ਨੂੰ ਡਿਕ੍ਰਿਪਟ ਕਰਨ ਲਈ ਸਮਰੱਥ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ।\nnoStreamsOptionCopy = ਹੋਰ ਬਰਾਊਜ਼ਰ ਵਿੱਚ ਖੋਲ੍ਹਣ ਲਈ ਲਿੰਕ ਨੂੰ ਕਾਪੀ ਕਰੋ\nnoStreamsOptionFirefox = ਸਾਡੇ ਮਨਪਸੰਦ ਬਰਾਊਜ਼ਰ ਵਰਤ ਕੇ ਵੇਖੋ\nnoStreamsOptionDownload = ਇਸ ਬਰਾਊਜ਼ਰ ਨਾਲ ਜਾਰੀ ਰੱਖੋ\ndownloadFirefoxPromo = { -send-short-brand } ਤੁਹਾਡੇ ਲਈ  ਬਿਲਕੁਲ ਨਵਾਂ { -firefox } ਹੈ।\n# the next line after the colon contains a file name\nshareLinkDescription = ਆਪਣੀ ਫਾਇਲ ਲਈ ਲਿੰਕ ਸਾਂਝਾ ਕਰੋ:\nshareLinkButton = ਲਿੰਕ ਸਾਂਝਾ ਕਰੋ\n# $name is the name of the file\nshareMessage = { -send-brand } ਨਾਲ \"{ $name }\" ਡਾਊਨਲੋਡ ਕਰੋ: ਸੌਖਾ, ਸੁਰੱਖਿਅਤ ਫਾਇਲ ਸਾਂਝਾ ਕਰਨਾ\ntrailheadPromo = ਤੁਹਾਡੀ ਪਰਦੇਦਾਰੀ ਦੀ ਸੁਰੱਖਿਆ ਦਾ ਢੰਗ ਹੈ। ਫਾਇਰਫਾਕਸ ਨਾਲ ਜੁੜੋ।\nlearnMore = ਹੋਰ ਸਿੱਖੋ\ndownloadConfirmTitle = ਇੱਕ ਗੱਲ ਹੋਰ\n"
  },
  {
    "path": "public/locales/pai/send.ftl",
    "content": "siteFeedback = Tkweek uk kabyuwuha\n\n## Send version 2 strings\n\n"
  },
  {
    "path": "public/locales/pl/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importowanie…\nencryptingFile = Szyfrowanie…\ndecryptingFile = Odszyfrowywanie…\ndownloadCount =\n    { $num ->\n        [one] 1 pobraniu\n        [few] { $num } pobraniach\n       *[many] { $num } pobraniach\n    }\ntimespanHours =\n    { $num ->\n        [one] godzinie\n        [few] { $num } godzinach\n       *[many] { $num } godzinach\n    }\ncopiedUrl = Skopiowano\nunlockInputPlaceholder = Hasło\nunlockButtonLabel = Odblokuj\ndownloadButtonLabel = Pobierz\ndownloadFinish = Ukończono pobieranie\nfileSizeProgress = ({ $partialSize } z { $totalSize })\nsendYourFilesLink = Wypróbuj Send\nerrorPageHeader = Coś się nie udało.\nfileTooBig = Ten plik jest za duży, aby go wysłać. Musi być mniejszy niż { $size }\nlinkExpiredAlt = Odnośnik wygasł\nnotSupportedHeader = Używana przeglądarka nie jest obsługiwana.\nnotSupportedLink = Dlaczego ta przeglądarka nie jest obsługiwana?\nnotSupportedOutdatedDetail = Ta wersja Firefoksa nie obsługuje technologii internetowej, która napędza Send. Należy uaktualnić przeglądarkę.\nupdateFirefox = Uaktualnij Firefoksa\ndeletePopupCancel = Anuluj\ndeleteButtonHover = Usuń\nfooterLinkLegal = Kwestie prawne\nfooterLinkPrivacy = Prywatność\nfooterLinkCookies = Ciasteczka\npasswordTryAgain = Niepoprawne hasło. Spróbuj ponownie.\njavascriptRequired = Send wymaga języka JavaScript\nwhyJavascript = Dlaczego Send wymaga języka JavaScript?\nenableJavascript = Włącz obsługę języka JavaScript i spróbuj ponownie.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } godz. { $minutes } min\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } min\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maksymalna długość hasła: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Nie można ustawić tego hasła\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Proste, prywatne udostępnianie plików\nintroDescription = { -send-brand } umożliwia udostępnianie plików za pomocą szyfrowania typu „end-to-end” i odnośników, które automatycznie wygasają. Dzięki temu możesz mieć pewność, że to co udostępniasz jest bezpieczne i nie pozostanie w Internecie na zawsze.\nnotifyUploadEncryptDone = Plik jest zaszyfrowany i gotowy do wysłania\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Wygasa po { $downloadCount } lub { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] minucie\n        [few] { $num } minutach\n       *[many] { $num } minutach\n    }\ntimespanDays =\n    { $num ->\n        [one] dniu\n        [few] { $num } dniach\n       *[many] { $num } dniach\n    }\ntimespanWeeks =\n    { $num ->\n        [one] tygodniu\n        [few] { $num } tygodniach\n       *[many] { $num } tygodniach\n    }\nfileCount =\n    { $num ->\n        [one] 1 plik\n        [few] { $num } pliki\n       *[many] { $num } plików\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Całkowity rozmiar: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Skopiuj odnośnik, aby udostępnić plik:\ncopyLinkButton = Kopiuj odnośnik\ndownloadTitle = Pobierz pliki\ndownloadDescription = Ten plik został udostępniony przez { -send-brand } za pomocą szyfrowania typu „end-to-end” i odnośnika, który automatycznie wygasa.\ntrySendDescription = Wypróbuj { -send-brand }, aby prosto i bezpiecznie udostępniać pliki.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Jednocześnie można wysyłać tylko jeden plik.\n        [few] Jednocześnie można wysyłać tylko { $count } pliki.\n       *[many] Jednocześnie można wysyłać tylko { $count } plików.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Dozwolone jest tylko jedno archiwum.\n        [few] Dozwolone są tylko { $count } archiwa.\n       *[many] Dozwolonych jest tylko { $count } archiwów.\n    }\nexpiredTitle = Ten odnośnik wygasł.\nnotSupportedDescription = { -send-brand } nie będzie działać w tej przeglądarce. { -send-short-brand } najlepiej działa w najnowszej wersji przeglądarki { -firefox }, ale będzie działać także w aktualnych wersjach większości przeglądarek.\ndownloadFirefox = Pobierz przeglądarkę { -firefox }\nlegalTitle = Zasady ochrony prywatności serwisu { -send-short-brand }\nlegalDateStamp = Wersja 1.0 z 12 marca 2019 r.\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } d. { $hours } godz. { $minutes } min\naddFilesButton = Wybierz pliki do wysłania\ntrustWarningMessage = Upewnij się, że ufasz odbiorcy, kiedy udostępniasz prywatne dane.\nuploadButton = Wyślij\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Przeciągnij pliki\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = lub kliknij, aby wysłać do { $size }\naddPassword = Chroń hasłem\nemailPlaceholder = Wpisz adres e-mail\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Zaloguj się, aby wysłać do { $size }\nsignInOnlyButton = Zaloguj się\naccountBenefitTitle = Utwórz konto { -firefox } lub zaloguj się\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Udostępniaj pliki do { $size }\naccountBenefitDownloadCount = Udostępniaj pliki większej liczbie osób\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Odnośniki aktywne przez jeden dzień\n        [few] Odnośniki aktywne przez { $count } dni\n       *[many] Odnośniki aktywne przez { $count } dni\n    }\naccountBenefitSync = Zarządzaj udostępnionymi plikami z każdego urządzenia\naccountBenefitMoz = Poznaj inne serwisy organizacji { -mozilla }\nsignOut = Wyloguj się\nokButton = OK\ndownloadingTitle = Pobieranie\nnoStreamsWarning = Ta przeglądarka może nie być w stanie odszyfrować tak dużego pliku.\nnoStreamsOptionCopy = Skopiuj odnośnik, aby otworzyć w innej przeglądarce\nnoStreamsOptionFirefox = Wypróbuj naszą ulubioną przeglądarkę\nnoStreamsOptionDownload = Kontynuuj za pomocą tej przeglądarki\ndownloadFirefoxPromo = { -send-short-brand } jest oferowany przez zupełnie nową przeglądarkę { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Udostępnij odnośnik do pliku:\nshareLinkButton = Udostępnij odnośnik\n# $name is the name of the file\nshareMessage = Pobierz „{ $name }” za pomocą { -send-brand }: prostego i bezpiecznego udostępniania plików\ntrailheadPromo = Jest sposób na ochronę swojej prywatności. Dołącz do Firefoksa.\nlearnMore = Więcej informacji.\ndownloadFlagged = Ten odnośnik został wyłączony z powodu naruszenia warunków korzystania z usługi.\ndownloadConfirmTitle = Jeszcze jedna rzecz\ndownloadConfirmDescription = Upewnij się, że ufasz osobie, która wysłała Ci ten plik, ponieważ nie możemy zweryfikować, czy nie spowoduje on uszkodzenia Twojego urządzenia.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Ufam osobie, która wysłała ten plik\n        [few] Ufam osobie, która wysłała te pliki\n       *[many] Ufam osobie, która wysłała te pliki\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Zgłoś ten plik jako podejrzany\n        [few] Zgłoś te pliki jako podejrzane\n       *[many] Zgłoś te pliki jako podejrzane\n    }\nreportDescription = Pomóż nam zrozumieć, co się stało. Co według Ciebie jest nie tak z tymi plikami?\nreportUnknownDescription = Przejdź do adresu odnośnika, który chcesz zgłosić, i kliknij „{ reportFile }”.\nreportButton = Zgłoś\nreportReasonMalware = Te pliki zawierają złośliwe oprogramowanie lub są częścią próby oszustwa.\nreportReasonPii = Te pliki zawierają informacje umożliwiające identyfikację mojej osoby.\nreportReasonAbuse = Te pliki zawierają nielegalne lub obraźliwe treści.\nreportReasonCopyright = Aby zgłosić naruszenie praw autorskich lub znaków towarowych, skorzystaj z procedury opisanej na <a>ten stronie</a>.\nreportedTitle = Pliki zostały zgłoszone\nreportedDescription = Dziękujemy. Otrzymaliśmy Twoje zgłoszenie dotyczące tych plików.\n"
  },
  {
    "path": "public/locales/ppl/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Shitechnawati\nimportingFile = Mukalaktia nemi…\nencryptingFile = Tikichtakawiat tinemit…\ndecryptingFile = Tikichtakapuat tinemit…\ndownloadCount =\n    { $num ->\n        [one] temultijtuk\n       *[other] { $num } temultijtuk\n    }\ntimespanHours =\n    { $num ->\n        [one] oraj\n       *[other] { $num } oraj\n    }\ncopiedUrl = Muishkupintuk!\nunlockInputPlaceholder = Ichtakatajkwilul\nunlockButtonLabel = Shiktapua\ndownloadButtonLabel = Shiktemulti\ndownloadFinish = Senkiska mutemultij\nfileSizeProgress = ({ $partialSize } ipal { $totalSize })\nsendYourFilesLink = Shikejeku Send\nerrorPageHeader = IJtakawtuk!\nfileTooBig = Ini tajkwilul sujsul etek pal tiktejkultia. Ma nemi san { $size }.\nlinkExpiredAlt = Ne ilpika pulijtuk\nnotSupportedHeader = Te tikishmatit ne mutachialuni.\nnotSupportedLink = Taika te ankishmatit nutachialuni?\nnotSupportedOutdatedDetail = Ini tamakalis ipal Firefox tesu kimati ne tzawaltekitilis ne kiyulitia Send. Nemi pal tikyankwilia ne mutachialuni.\nupdateFirefox = Shikyankwili Firefox\ndeletePopupCancel = Shikilwi tesu\ndeleteButtonHover = Shikpulu\nfooterLinkLegal = Ipanpa ne tajtuli\nfooterLinkPrivacy = Teichtakayu\nfooterLinkCookies = Cookies\npasswordTryAgain = Ne ichtakatajkwilul tesu yek. Shikejeku uksenpa.\njavascriptRequired = Send muneki JavaScript\nwhyJavascript = Taika Send muneki JavaScript?\nenableJavascript = Shichiwa ma JavaScript tekiti wan shikejeku uksenpa.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Ne iweyaka ne ichtakatajkwilul muneki: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Te tiweliket tiktaliat ini ichtakataketzalis\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Shiktitani\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Shikmajmaka se tajkwilul, te uij wan ichtaka\nintroDescription = { -send-brand } metzpalewia tikmajmaka se tajkwilul iwan taichtakawilis wan se ilpika puliwi nemanha. Yajika, tikpia muichtakayu pal tikmajmaka wan tesu naka senpa mutajtatka tik matapan.\nnotifyUploadEncryptDone = Ne archivoj nemi ichtakawijtuk wan weli tiktitania\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Puliwi kwak ajsi { $downloadCount } ush { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] { $num } minutoj\n       *[other] { $num } minutoj\n    }\ntimespanDays =\n    { $num ->\n        [one] { $num } tunal\n       *[other] { $num } tunal\n    }\ntimespanWeeks =\n    { $num ->\n        [one] { $num } semanaj\n       *[other] { $num } semanaj\n    }\nfileCount =\n    { $num ->\n        [one] { $num } tajkwilul\n       *[other] { $num } tajkwilul\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Itamachiwka: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Shikishkupina ne ilpika pal tikmajmaka mutajkwilul:\ncopyLinkButton = Shikishkupina ne ilpika\ndownloadTitle = Shiktemulti tajkwilul\ndownloadDescription = Ini tajkwilul kiski itech { -send-brand } iwan taichtakawilis wan se ilpika ka puliwi nemanha.\ntrySendDescription = Shikejeku { -send-brand } wan shiktakuli ichtaka wan te uij.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Semaya se tajkwilul weli pal tiktejkultia sansepa.\n       *[other] Semaya { $count } tajkwilul weli pal tiktejkultia sansepa.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Semaya se amapial weli mutitania.\n       *[other] Semaya { $count } amapial weli mutitania.\n    }\nexpiredTitle = Ne ilpika puliwik.\nnotSupportedDescription = { -send-brand } tesu yawi tekiti iwan ini tachialuni. { -send-short-brand } tekiti sujsul yek iwan ne tipan tamakalis ipal { -firefox }, wan nusan iwan ne tipan tamakalis ipal miak tachialuni.\ndownloadFirefox = Shiktemulti { -firefox }\nlegalTitle = { -send-short-brand } Tanawatilis ipanpa teichtakayu\nlegalDateStamp = Tamakalis 1.0, tik marzoj 12, 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } t { $hours } h { $minutes } m\naddFilesButton = Shikpejpena ne tajkwilul pal tiktejkultia\nuploadButton = Shiktejkulti\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Shiktilana wan shikmayawi ne tajkwilul\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = u shikpachu pal tiktitania { $size }\naddPassword = Shiktajpia iwan ichtakatajkwilul\nemailPlaceholder = Shiktali mutepusamaw\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Shiktali mutukay pal tiktitania { $size }\nsignInOnlyButton = Shiktali mutukay\naccountBenefitTitle = Shikchiwa se mutapujka tik { -firefox } ush shiktali mutukay\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Shiktakuli tajtajkwilul ka { $size }\naccountBenefitDownloadCount = Shiktakuli tajtajkwilul iwan seuk\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Shikpia ne ilpika tapujtuk 1 tunal\n       *[other] Shikpia ne ilpika tapujtuk { $count } tunal\n    }\naccountBenefitSync = Shiktajpia ne tajkwilul takulijtuk ka kanaj\naccountBenefitMoz = Shikmati ipanpa ukse { -mozilla } tayekultilis\nsignOut = Shikisa\nokButton = Yek\ndownloadingTitle = Kitemultia nemi\nnoStreamsWarning = Ini tachialuni anka te weli kichtakapua ini tajkwilul wey.\nnoStreamsOptionCopy = Shikishkupina ne ilpika pal tiktapua tik ukse tachialuni\nnoStreamsOptionFirefox = Shikejeku ne tachialuni tikishwelitat\nnoStreamsOptionDownload = Ma ninemi senpa iwan ini tachialuni\ndownloadFirefoxPromo = Ne yankwik { -firefox } metzwikilia { -send-short-brand }.\n# the next line after the colon contains a file name\nshareLinkDescription = Shiktakuli ne ilpika ipal mutajkwilul:\nshareLinkButton = Shiktakuli ne ilpika\n# $name is the name of the file\nshareMessage = Shiktemulti “{ $name }” iwan { -send-brand }: ichtaka wan te uij\ntrailheadPromo = Nemi ken pal tiktajpia ne muichtakayu. Shimuishtuka iwan Firefox.\nlearnMore = Shimumachti ukchupi.\n"
  },
  {
    "path": "public/locales/pt-BR/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importando…\nencryptingFile = Criptografando…\ndecryptingFile = Descriptografando…\ndownloadCount =\n    { $num ->\n        [one] baixar 1 vez\n       *[other] baixar { $num } vezes\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hora\n       *[other] { $num } horas\n    }\ncopiedUrl = Copiado!\nunlockInputPlaceholder = Senha\nunlockButtonLabel = Desbloquear\ndownloadButtonLabel = Baixar\ndownloadFinish = Download concluído\nfileSizeProgress = ({ $partialSize } de { $totalSize })\nsendYourFilesLink = Experimente o Send\nerrorPageHeader = Oops, ocorreu um erro!\nfileTooBig = Esse arquivo ou grupo de arquivos é grande demais para ser enviado. Deve ser menor que { $size }.\nlinkExpiredAlt = Link expirado\nnotSupportedHeader = Seu navegador não é suportado.\nnotSupportedLink = Por que meu navegador não é suportado?\nnotSupportedOutdatedDetail = Infelizmente essa versão do Firefox não suporta a tecnologia web que faz o Send funcionar. Você precisa atualizar o seu navegador.\nupdateFirefox = Atualizar o Firefox\ndeletePopupCancel = Cancelar\ndeleteButtonHover = Remover da lista\nfooterLinkLegal = Jurídico\nfooterLinkPrivacy = Privacidade\nfooterLinkCookies = Cookies\npasswordTryAgain = Senha incorreta. Tente novamente.\njavascriptRequired = O Send requer JavaScript\nwhyJavascript = Por que o Send precisa do JavaScript?\nenableJavascript = Ative o JavaScript e tente novamente.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }min\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }min\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Tamanho máximo da senha: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Essa senha não pôde ser definida\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Compartilhamento de arquivos fácil e privativo\nintroDescription = O { -send-brand } permite compartilhar arquivos com criptografia de ponta a ponta através de um link que expira automaticamente. Assim você pode proteger o que compartilha e ter certeza que suas coisas não ficarão online para sempre.\nnotifyUploadEncryptDone = Seu arquivo foi criptografado e está pronto para ser enviado\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Expira após { $downloadCount } ou { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuto\n       *[other] { $num } minutos\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 dia\n       *[other] { $num } dias\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 semana\n       *[other] { $num } semanas\n    }\nfileCount =\n    { $num ->\n        [one] 1 arquivo\n       *[other] { $num } arquivos\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Tamanho total: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copie o link para compartilhar seu arquivo:\ncopyLinkButton = Copiar link\ndownloadTitle = Baixar arquivos\ndownloadDescription = Este arquivo foi compartilhado via { -send-brand } com criptografia de ponta a ponta e um link que expira automaticamente.\ntrySendDescription = Experimente o { -send-brand } para compartilhar arquivos com simplicidade e segurança.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Somente 1 arquivo pode ser enviado por vez.\n       *[other] Somente { $count } arquivos podem ser enviados por vez.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Só é permitido 1 pacote.\n       *[other] Só são permitidos { $count } pacotes.\n    }\nexpiredTitle = Este link expirou.\nnotSupportedDescription = O { -send-brand } não funciona com este navegador. O { -send-short-brand } funciona melhor com a versão mais recente do { -firefox } e funcionará com a versão atual da maioria dos navegadores.\ndownloadFirefox = Baixar o { -firefox }\nlegalTitle = Aviso de privacidade do { -send-short-brand }\nlegalDateStamp = Versão 1.0, de 12 de março de 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Selecionar arquivos para enviar\ntrustWarningMessage = Certifique-se de que confia no destinatário ao compartilhar dados sensíveis.\nuploadButton = Enviar\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Arraste e solte arquivos aqui\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = ou clique para enviar até { $size }\naddPassword = Proteger com senha\nemailPlaceholder = Informe seu e-mail\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Entre na sua conta para enviar até { $size }\nsignInOnlyButton = Entrar\naccountBenefitTitle = Crie uma Conta { -firefox } ou entre se já tiver\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Compartilhe arquivos até { $size }.\naccountBenefitDownloadCount = Compartilhe arquivos com mais pessoas.\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Mantenha links ativos por até 1 dia.\n       *[other] Mantenha links ativos por até { $count } dias.\n    }\naccountBenefitSync = Gerencie arquivos compartilhados a partir de qualquer dispositivo.\naccountBenefitMoz = Conheça outros serviços da { -mozilla }.\nsignOut = Sair\nokButton = OK\ndownloadingTitle = Baixando\nnoStreamsWarning = Este navegador pode não conseguir descriptografar um arquivo tão grande.\nnoStreamsOptionCopy = Copiar o link para abrir em outro navegador\nnoStreamsOptionFirefox = Experimente nosso navegador preferido\nnoStreamsOptionDownload = Continuar com este navegador\ndownloadFirefoxPromo = O { -send-short-brand } é apresentado pelo novo { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Compartilhe o link para o seu arquivo:\nshareLinkButton = Compartilhar link\n# $name is the name of the file\nshareMessage = Baixe \"{ $name }\" com o { -send-brand }: compartilhamento de arquivos simples e seguro\ntrailheadPromo = Existe um meio de proteger sua privacidade. Use o Firefox.\nlearnMore = Saiba mais.\ndownloadFlagged = Este link foi desativado por violar os termos do serviço.\ndownloadConfirmTitle = Mais uma coisa\ndownloadConfirmDescription = Certifique-se de que confia na pessoa que enviou este arquivo, pois não podemos conferir se não prejudicará seu dispositivo.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Eu confio na pessoa que enviou este arquivo\n       *[other] Eu confio na pessoa que enviou estes arquivos\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Denunciar este arquivo como suspeito\n       *[other] Denunciar estes arquivos como suspeitos\n    }\nreportDescription = Ajude-nos a entender o que está acontecendo. O que você acha que há de errado com estes arquivos?\nreportUnknownDescription = Acesse o endereço do link que deseja denunciar e clique em “{ reportFile }”.\nreportButton = Denunciar\nreportReasonMalware = Estes arquivos contêm malware (código malicioso) ou fazem parte de um ataque de phishing (fraude).\nreportReasonPii = Estes arquivos contêm informações de identificação pessoal sobre mim.\nreportReasonAbuse = Estes arquivos contêm conteúdo ilegal ou abusivo.\nreportReasonCopyright = Para denunciar violação de direitos autorais ou de marca, siga o procedimento descrito <a>nesta página</a>.\nreportedTitle = Arquivos denunciados\nreportedDescription = Obrigado. Recebemos sua denúncia sobre estes arquivos.\n"
  },
  {
    "path": "public/locales/pt-PT/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = A importar...\nencryptingFile = A encriptar...\ndecryptingFile = A desencriptar...\ndownloadCount =\n    { $num ->\n        [one] 1 transferência\n       *[other] { $num } transferências\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hora\n       *[other] { $num } horas\n    }\ncopiedUrl = Copiado!\nunlockInputPlaceholder = Palavra-passe\nunlockButtonLabel = Desbloquear\ndownloadButtonLabel = Transferir\ndownloadFinish = Transferência concluída\nfileSizeProgress = ({ $partialSize } de { $totalSize })\nsendYourFilesLink = Experimentar o Send\nerrorPageHeader = Algo correu mal.\nfileTooBig = Esse ficheiro é muito grande para carregar. Deve ser menor do que { $size }.\nlinkExpiredAlt = Ligação expirada\nnotSupportedHeader = O seu navegador não é suportado.\nnotSupportedLink = Porque é que o meu navegador não é suportado?\nnotSupportedOutdatedDetail = Infelizmente esta versão do Firefox não suporta a tecnologia web que faz o Send funcionar. Precisa de atualizar o seu navegador.\nupdateFirefox = Atualizar o Firefox\ndeletePopupCancel = Cancelar\ndeleteButtonHover = Apagar\nfooterLinkLegal = Informação legal\nfooterLinkPrivacy = Privacidade\nfooterLinkCookies = Cookies\npasswordTryAgain = Palavra-passe incorreta. Tente novamente.\njavascriptRequired = O Send requer JavaScript\nwhyJavascript = Porque é que o Send requer JavaScript?\nenableJavascript = Por favor ative o JavaScript e tente novamente.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Comprimento máximo de palavra-passe: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Esta palavra-passe não pôde ser definida\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Partilha de ficheiros simples e privada\nintroDescription = O { -send-brand } permite partilhar ficheiros com encriptação de ponta a ponta e uma ligação que expira automaticamente. Para que possa manter o que partilha privado e garantir que as suas coisas não fiquem online para sempre.\nnotifyUploadEncryptDone = O seu ficheiro está encriptado e pronto a enviar\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Expira após { $downloadCount } ou { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuto\n       *[other] { $num } minutos\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 dia\n       *[other] { $num } dias\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 semana\n       *[other] { $num } semanas\n    }\nfileCount =\n    { $num ->\n        [one] 1 ficheiro\n       *[other] { $num } ficheiros\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Tamanho total: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copie a ligação para partilhar o seu ficheiro:\ncopyLinkButton = Copiar ligação\ndownloadTitle = Transfira ficheiros\ndownloadDescription = Este ficheiro foi partilhado via { -send-brand } com encriptação de ponta a ponta e uma ligação que expira automaticamente.\ntrySendDescription = Experimente o { -send-brand } para uma partilha de ficheiros simples e segura.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Apenas 1 ficheiro pode ser carregado de cada vez.\n       *[other] Apenas { $count } ficheiros podem ser carregados de cada vez.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Apenas 1 ficheiro é permitido.\n       *[other] Apenas { $count } ficheiros são permitidos.\n    }\nexpiredTitle = Esta ligação expirou.\nnotSupportedDescription = O { -send-brand } não funciona com este navegador. O { -send-short-brand } funciona melhor com a versão mais recente do { -firefox } e irá funcionar com a versão atual da maioria dos navegadores.\ndownloadFirefox = Transferir o { -firefox }\nlegalTitle = Aviso de privacidade do { -send-short-brand }\nlegalDateStamp = Versão 1.0, de 12 de março de 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Selecionar ficheiros para carregar\ntrustWarningMessage = Tenha a certeza que confia no destinatário ao partilhar dados sensíveis.\nuploadButton = Carregar\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Arraste e largue ficheiros\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = ou clique para enviar até { $size }\naddPassword = Proteger com palavra-passe\nemailPlaceholder = Introduzir o seu email\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Iniciar sessão para enviar até { $size }\nsignInOnlyButton = Iniciar sessão\naccountBenefitTitle = Crie uma Conta { -firefox } ou inicie sessão\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Partilhe ficheiros até { $size }\naccountBenefitDownloadCount = Partilhe ficheiros com mais pessoas\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Mantenha ligações ativas até 1 dia\n       *[other] Mantenha ligações ativas até { $count } dias\n    }\naccountBenefitSync = Gira ficheiros partilhas a partir de qualquer dispositivo\naccountBenefitMoz = Saiba mais acerca de outros serviços da { -mozilla }\nsignOut = Terminar sessão\nokButton = OK\ndownloadingTitle = A transferir\nnoStreamsWarning = Este navegador pode não conseguir desencriptar um ficheiro tão grande.\nnoStreamsOptionCopy = Copie a ligação para abrir noutro navegador\nnoStreamsOptionFirefox = Experimente o nosso navegador favorito\nnoStreamsOptionDownload = Continuar com este navegador\ndownloadFirefoxPromo = O { -send-short-brand } é trazido a si pelo novo { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Partilhe a ligação para o seu ficheiro:\nshareLinkButton = Partilhar ligação\n# $name is the name of the file\nshareMessage = Transferir “{ $name }“ com o { -send-brand }: partilha de ficheiros simples e segura\ntrailheadPromo = Existe um modo para proteger a sua privacidade. Adira ao Firefox.\nlearnMore = Saiba mais.\ndownloadFlagged = Esta ligação foi desativada por violar os termos do serviço.\ndownloadConfirmTitle = Mais uma coisa\ndownloadConfirmDescription = Tenha a certeza que confia na pessoa que lhe enviou este ficheiro, pois não podemos garantir que o mesmo não irá danificar o seu dispositivo.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Eu confio na pessoa que enviou este ficheiro\n       *[other] Eu confio na pessoa que enviou estes ficheiros\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Denunciar este ficheiro como suspeito\n       *[other] Denunciar estes ficheiros como suspeitos\n    }\nreportDescription = Ajude-nos a compreender o que está a acontecer. O que acha que está errado com estes ficheiros?\nreportUnknownDescription = Por favor, aceda ao endereço da ligação que pretende denunciar e clique em “{ reportFile }”.\nreportButton = Denunciar\nreportReasonMalware = Estes ficheiros contêm software malicioso ou fazem parte de um ataque de phishing.\nreportReasonPii = Estes ficheiros contêm dados pessoais sobre mim.\nreportReasonAbuse = Estes ficheiros contêm conteúdo ilegal ou abusivo.\nreportReasonCopyright = Para denunciar violação de direitos de autor ou de marca comercial, utilize o procedimento descrito <a>nesta página</a>.\nreportedTitle = Ficheiros denunciados\nreportedDescription = Obrigado. Recebemos a sua denúncia sobre estes ficheiros.\n"
  },
  {
    "path": "public/locales/quc/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Utzijoxik\nimportingFile = Ujek'ik…\nencryptingFile = Uwiqik…\ndecryptingFile = Usolik…\ndownloadCount =\n    { $num ->\n        [one] 1 uqasaxik\n       *[other] { $num } taq uqasaxik\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 ramaj\n       *[other] { $num } taq ramaj\n    }\ncopiedUrl = Copied!\nunlockInputPlaceholder = Retokib'al\nunlockButtonLabel = Utzoqopixik\ndownloadButtonLabel = Uqasaxik\ndownloadFinish = Tz'aqat uqasaxik\nfileSizeProgress = ({ $partialSize } rech { $totalSize })\nsendYourFilesLink = Chak'amb'ejaj Send\nerrorPageHeader = K'o man utz ta xub'ano\nfileTooBig = Le kemk'olib'al sib'alaj nim chech upaqab'isaxik. Rajawaxik nitz' chi uwach{ $size }\nlinkExpiredAlt = Xq'ax uq'ijol kemwiqb'al\nnotSupportedHeader = Man toq'am ta le anik'onel\nnotSupportedLink = ¿Jasche man toq'am ta le nunik'onel?\nnotSupportedOutdatedDetail = Chakuyu' we okib'al rech Firefox man kutoq'aj ta le k'ak'eta'm rech web' le kuya' uchuq'ab' Send. Rajawaxik kak'ak'arisaj le anik'onel.\nupdateFirefox = Chak'ak'arisaj Firefox\ndeletePopupCancel = Uq'atexik\ndeleteButtonHover = Uchupik\nfooterLinkLegal = Nim wuj\nfooterLinkPrivacy = Echeb'alil\nfooterLinkCookies = Cookies\npasswordTryAgain = Man utz ta le retokib'al. Chab'ana' chi jumul.\njavascriptRequired = Le Send kajawataj JavaScript chech\nwhyJavascript = ¿jasche kajawataj JavaScript chech  Send?\nenableJavascript = Chatzija' JavaScript k'ate k'u ri' chab'ana' chi jumul.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Nimalaj unimal retokib'al: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Man kkowimb'ex ta ujeqeb'axik le retokib'al\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Utaqik\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Man k'ax taj, ukomonexik taq kemk'olib'al pa echeb'alil\nintroDescription = { -send-brand } kuya' bé chi awech kakomonej taq kemk'olib'al ruk' wiqitajem chi'l jun kemwiqb'al le kq'ax uq'ijol pa utukelam. Are chi man katzaq ta le kakomone'j pa echeb'alil chi'l chasuk'ub'a' rilik chi le taq ajastaq man kk'oji' ta pa nimk'atz pa junelik.\nnotifyUploadEncryptDone = Le akemk'olib'al wiqitalik chi'l utz chi kataqo\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Kq'ax uq'ijol chi rij { $downloadCount } on { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 kajb'al\n       *[other] { $num } taq kajb'al\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 q'ij\n       *[other] { $num } taq q'ij\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 wuqq'ij\n       *[other] { $num } taq wuqq'ij\n    }\nfileCount =\n    { $num ->\n        [one] 1 kemk'olib'al\n       *[other] { $num } taq kemk'olib'al\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Ronojel unimal: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Chawinaqirisaj uwach le kemwiqb'al chech ukomone'xik le akemk'olib'al:\ncopyLinkButton = Relesaxik uwach kemwiqb'al\ndownloadTitle = Uqasaxik taq kemwiqb'al\ndownloadDescription = We kemk'olib'al xkomone'x pa { -send-brand } ruk' wiqitajem pa xkut chi xkut chi'l jun kemwiqb'al le kq'ax uq'ijol pa utukelam.\ntrySendDescription = Chak'amb'ejaj { -send-brand } chech man k'ax taj, ukomonexik kemk'olib'al pa chajib'al.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Xa 1 kemk'olib'al kkowinb'ex upaqab'isaxik pa jun uq'ijol.\n       *[other] Xew { $count } taq kemk'olib'al kkowinb'ex upaqab'isaxik pa jun uq'ijol.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Xew 1 kemk'olib'al ya'om b'e chech.\n       *[other] Xew { $count } taq kemk'olib'al ya'om b'e chech\n    }\nexpiredTitle = Xq'ax uq'ijol we kemwiqb'al\nnotSupportedDescription = { -send-brand } man kchakun ta ruk' we nik'onel. { -send-short-brand } are qas utz uchakunem ruk' le maja naj okib'al rech { -firefox }, xuquje' kchakun ruk' le okib'al rech chanim rech nima ronojel taq nik'onelab'.\ndownloadFirefox = Uqasaxik { -firefox }\nlegalTitle = { -send-short-brand } ub'ixikil rech echeb'alil\nlegalDateStamp = Okib'al 1.0, uq'ijol rech urox ik' 12, 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Ucha'ik taq kemk'olib'al chech upaqab'isaxik\nuploadButton = Upaqab'isaxik\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Uchararexik chi'l utzoqopixik taq kemk'olib'al\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = on chapitz'a' chech utaqik chech { $size }\naddPassword = Chajital rumal retokib'al\nemailPlaceholder = Chach'apa' le ataqoqxa'nib'al\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Chamajij kemchak chech utaqik chech { $size }\nsignInOnlyButton = Chamajij kemchak\naccountBenefitTitle = Chawinaqirisaj jun { -firefox } kemb'i'aj on chamajij kemchak\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Chakomone'j taq kemk'olib'al kq'ax pa uwi' { $size }\naccountBenefitDownloadCount = Chakomone'j taq kemk'olib'al kuk' nik'aj chi winaq\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Chatzija' taq kemwiqb'al are chi kq'ax pa uwi' 1 q'ij\n       *[other] Chatzija' taq kemwiqb'al are chi kq'ax pa uwi' { $count } taq q'ij\n    }\naccountBenefitSync = Chawilawachij komone'tal taq kemk'olib'al pa apachike wiqkemchakub'al\naccountBenefitMoz = Chaweta'maj chi rij jun chi { -mozilla } taq patanib'al\nsignOut = Chatz'apij kemchak\nokButton = Ja'e\ndownloadingTitle = Ktajin uqasaxik\nnoStreamsWarning = We nik'onel wene man kkowin taj kusol jun jewa' unimal kemk'olib'al\nnoStreamsOptionCopy = Chawelesaj uwach le kemwiqb'al chech ujaqik jun chi nik'onel\nnoStreamsOptionFirefox = Chak'amb'ejaj le ajawatal nik'onel\nnoStreamsOptionDownload = Chab'ana' na ruk' we nik'onel\ndownloadFirefoxPromo = { -send-short-brand } k'amom la chi awech rumal le k'ak' { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Chakomone'j le kemwiqb'al chech le akemk'olib'al:\nshareLinkButton = Chakomone'j kemwiqb'al\n# $name is the name of the file\nshareMessage = Chaqasaj “{ $name }” ruk' { -send-brand }: man k'ax ta ub'anik, ukomone'xik kemk'olib'al pa chajib'al\ntrailheadPromo = K'o jun ub'e'al chech uchajixik le a'echeb'alil. Chat'iqa' awib' pa. Firefox.\nlearnMore = Chaweta'maj nik'aj chik\n"
  },
  {
    "path": "public/locales/ro/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Se importă…\nencryptingFile = Se criptează…\ndecryptingFile = Se decriptează…\ndownloadCount =\n    { $num ->\n        [one] 1 descărcare\n        [few] { $num } descărcări\n       *[other] { $num } de descărcări\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 oră\n        [few] { $num } ore\n       *[other] { $num } de ore\n    }\ncopiedUrl = Copiat!\nunlockInputPlaceholder = Parolă\nunlockButtonLabel = Deblochează\ndownloadButtonLabel = Descarcă\ndownloadFinish = Descărcare încheiată\nfileSizeProgress = ({ $partialSize } din { $totalSize })\nsendYourFilesLink = Încearcă Send\nerrorPageHeader = Ceva nu a funcționat!\nfileTooBig = Acest fișier este prea mare. Ar trebuie să fie sub { $size }.\nlinkExpiredAlt = Link expirat\nnotSupportedHeader = Browserul tău nu este suportat.\nnotSupportedLink = De ce browserul meu nu este suportat?\nnotSupportedOutdatedDetail = Din păcate, această versiune de Firefox nu suportă tehnologiile web din spatele Send. Va trebui să actualizezi browserul.\nupdateFirefox = Actualizează Firefox\ndeletePopupCancel = Renunță\ndeleteButtonHover = Șterge\nfooterLinkLegal = Mențiuni legale\nfooterLinkPrivacy = Confidențialitate\nfooterLinkCookies = Cookie-uri\npasswordTryAgain = Parolă incorectă. Încearcă din nou.\njavascriptRequired = Send necesită JavaScript\nwhyJavascript = De ce Send necesită JavaScript?\nenableJavascript = Te rugăm să reactivezi JavaScript și să încerci din nou.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Lungime minimă a parolei: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Această parolă nu a putut fi setată\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Partajare de fișiere simplă și privată\nintroDescription = { -send-brand } îți permite să partajezi fișiere cu criptare capăt-la-capăt și un link care expiră automat. Deci, poți păstra confidențial ceea ce partajezi și te poți asigura că ce ai partajat nu rămâne online pentru totdeauna.\nnotifyUploadEncryptDone = Fișierul tău este criptat și gata de trimitere\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Expiră după { $downloadCount } sau { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minut\n        [few] { $num } minute\n       *[other] { $num } de minute\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 zi\n        [few] { $num } zile\n       *[other] { $num } de zile\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 săptămână\n        [few] { $num } săptămâni\n       *[other] { $num } de săptămâni\n    }\nfileCount =\n    { $num ->\n        [one] 1 fișier\n        [few] { $num } fișiere\n       *[other] { $num } de fișiere\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Mărime totală: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Copiază linkul pentru partajarea fișierului:\ncopyLinkButton = Copiază linkul\ndownloadTitle = Descarcă fișierele\ndownloadDescription = Acest fișier a fost partajat prin { -send-brand }, cu criptare capăt-la-capăt și un link care expiră automat.\ntrySendDescription = Încearcă { -send-brand } pentru o partajare simplă și sigură a fișierelor.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Numai 1 fișier poate fi încărcat simultan.\n        [few] Numai { $count } fișiere pot fi încărcate simultan.\n       *[other] Numai { $count } de fișiere pot fi încărcate simultan.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Numai 1 arhivă este permisă.\n        [few] Numai { $count } arhive sunt permise.\n       *[other] Numai { $count } de arhive sunt permise.\n    }\nexpiredTitle = Acest link a expirat.\nnotSupportedDescription = { -send-brand } nu va funcționa pe acest browser. { -send-short-brand } funcționează cel mai bine cu ultima versiune de { -firefox } și va funcționa cu versiunea curentă a majorității browserelor.\ndownloadFirefox = Descarcă { -firefox }\nlegalTitle = Notificare privind confidențialitatea { -send-short-brand }\nlegalDateStamp = Versiunea 1.0 din data de 12 martie 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }z { $hours }h { $minutes }m\naddFilesButton = Selectează fișierele pentru încărcare\ntrustWarningMessage = Asigură-te că destinatarul este de încredere când partajezi date sensibile.\nuploadButton = Încarcă\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Trage și plasează fișierele\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = sau dă clic pentru a trimite până la { $size }\naddPassword = Protejează cu parolă\nemailPlaceholder = Introdu e-mailul tău\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Autentifică-te pentru a trimite până la { $size }\nsignInOnlyButton = Autentificare\naccountBenefitTitle = Creează un cont { -firefox } sau autentifică-te\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Partajează fișiere de până la { $size }\naccountBenefitDownloadCount = Partajează fișiere cu mai multe persoane\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Păstrează linkurile active până la 1 zi\n        [few] Păstrează linkurile active până la { $count } zile\n       *[other] Păstrează linkurile active până la { $count } de zile\n    }\naccountBenefitSync = Gestionează fișierele partajate de pe orice dispozitiv\naccountBenefitMoz = Află despre celelalte servicii { -mozilla }\nsignOut = Deconectare\nokButton = Ok\ndownloadingTitle = Se descarcă\nnoStreamsWarning = Este posibil ca acest browser să nu poată decripta un fișier atât de mare.\nnoStreamsOptionCopy = Copiază linkul pentru a-l deschide într-un alt browser\nnoStreamsOptionFirefox = Încearcă browserul nostru favorit\nnoStreamsOptionDownload = Continuă cu acest browser\ndownloadFirefoxPromo = { -send-short-brand } îți este adus de noul { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Partajează linkul către fișier:\nshareLinkButton = Partajează linkul\n# $name is the name of the file\nshareMessage = Descarcă „{ $name }” cu { -send-brand }: partajare simplă și sigură a fișierelor\ntrailheadPromo = Există o modalitate de a-ți proteja viața privată. Folosește Firefox.\nlearnMore = Află mai multe.\ndownloadFlagged = Acest link a fost dezactivat pentru că încalcă termenii de utilizare a serviciului.\ndownloadConfirmTitle = Încă ceva\ndownloadConfirmDescription = Asigură-te că persoana care ți-a trimis acest fișier este de încredere pentru că noi nu putem verifica dacă nu cumva îți va afecta dispozitivul.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Am încredere în persoana care a trimis acest fișier\n        [few] Am încredere în persoana care a trimis aceste fișiere\n       *[other] Am încredere în persoana care a trimis aceste fișiere\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Raportează acest fișier ca suspect\n        [few] Raportează aceste fișiere ca suspecte\n       *[other] Raportează aceste fișiere ca suspecte\n    }\nreportDescription = Ajută-ne să înțelegem ce se întâmplă. Ce crezi că e în neregulă cu aceste fișiere?\nreportUnknownDescription = Intră pe URL-ul linkului pe care vrei să îl raportezi și dă clic pe „{ reportFile }”.\nreportButton = Raportează\nreportReasonMalware = Aceste fișiere conțin cod rău-intenționat sau fac parte dintr-un atac de înșelăciune.\nreportReasonPii = Aceste fișiere conțin date cu caracter personal identificabile despre mine.\nreportReasonAbuse = Aceste fișiere au un conținut ilegal sau ofensator.\nreportReasonCopyright = Pentru a raporta o încălcare a drepturilor de reproducere sau a mărcilor comerciale, folosește procedura descrisă <a>aici</a>.\nreportedTitle = Fișiere raportate\nreportedDescription = Îți mulțumim. Am primit raportarea ta despre aceste fișiere.\n"
  },
  {
    "path": "public/locales/ru/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Импортирование...\nencryptingFile = Шифрование...\ndecryptingFile = Расшифровка...\ndownloadCount =\n    { $num ->\n        [one] { $num } загрузки\n        [few] { $num } загрузок\n       *[other] { $num } загрузок\n    }\ntimespanHours =\n    { $num ->\n        [one] { $num } час\n        [few] { $num } часа\n       *[other] { $num } часов\n    }\ncopiedUrl = Скопировано!\nunlockInputPlaceholder = Пароль\nunlockButtonLabel = Разблокировать\ndownloadButtonLabel = Загрузить\ndownloadFinish = Загрузка завершена\nfileSizeProgress = ({ $partialSize } из { $totalSize })\nsendYourFilesLink = Попробовать Send\nerrorPageHeader = Что-то пошло не так!\nfileTooBig = Файл слишком большой. Он должен быть меньше { $size }.\nlinkExpiredAlt = Истёк срок действия ссылки\nnotSupportedHeader = Ваш браузер не поддерживается.\nnotSupportedLink = Почему мой браузер не поддерживается?\nnotSupportedOutdatedDetail = К сожалению, эта версия Firefox не поддерживает веб-технологию, благодаря которой работает Send. Ваш нужно обновить свой браузер.\nupdateFirefox = Обновить Firefox\ndeletePopupCancel = Отмена\ndeleteButtonHover = Удалить\nfooterLinkLegal = Права\nfooterLinkPrivacy = Приватность\nfooterLinkCookies = Куки\npasswordTryAgain = Неверный пароль. Попробуйте снова.\njavascriptRequired = Для Send необходим JavaScript\nwhyJavascript = Почему Send требуется JavaScript?\nenableJavascript = Пожалуйста, включите JavaScript и попробуйте снова.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } ч. { $minutes } мин.\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } мин.\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Максимальная длина пароля: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Этот пароль не может быть установлен\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Простой и безопасный обмен файлами\nintroDescription = { -send-brand } позволяет вам делиться файлами со сквозным шифрованием и ограниченным сроком действия ссылки на загрузку. Так что, вы сможете делиться файлами приватно и они не останутся в сети навсегда.\nnotifyUploadEncryptDone = Ваш файл зашифрован и готов к отправке\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Срок хранения истекает после { $downloadCount } или через { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] { $num } минуту\n        [few] { $num } минуты\n       *[other] { $num } минут\n    }\ntimespanDays =\n    { $num ->\n        [one] { $num } день\n        [few] { $num } дня\n       *[other] { $num } дней\n    }\ntimespanWeeks =\n    { $num ->\n        [one] { $num } неделю\n        [few] { $num } недели\n       *[other] { $num } недель\n    }\nfileCount =\n    { $num ->\n        [one] { $num } файл\n        [few] { $num } файла\n       *[other] { $num } файлов\n    }\n# byte abbreviation\nbytes = Б\n# kibibyte abbreviation\nkb = КБ\n# mebibyte abbreviation\nmb = МБ\n# gibibyte abbreviation\ngb = ГБ\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Общий размер: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Скопируйте ссылку, чтобы поделиться своим файлом:\ncopyLinkButton = Копировать ссылку\ndownloadTitle = Загрузить файлы\ndownloadDescription = Этот файл был отправлен через { -send-brand } со сквозным шифрованием и ограниченным сроком действия ссылки на загрузку.\ntrySendDescription = Испытайте простой и безопасный обмен файлами с помощью { -send-brand }.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Только { $count } файл может загружаться одновременно.\n        [few] Только { $count } файла могут загружаться одновременно.\n       *[other] Только { $count } файлов могут загружаться одновременно.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Только { $count } архив разрешён.\n        [few] Только { $count } архива разрешено.\n       *[other] Только { $count } архивов разрешено.\n    }\nexpiredTitle = Срок действия этой ссылки истёк.\nnotSupportedDescription = { -send-brand } не будет работать в этом браузере. { -send-short-brand } лучше всего работает с последней версией { -firefox }, и будет работать с последними версиями популярных браузеров.\ndownloadFirefox = Загрузить { -firefox }\nlegalTitle = Уведомление о конфиденциальности { -send-short-brand }\nlegalDateStamp = Версия 1.0, от 12 марта 2019 года\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } дн. { $hours } ч. { $minutes } мин.\naddFilesButton = Выберите файлы для выгрузки\ntrustWarningMessage = Убедитесь, что вы доверяете своему получателю при обмене конфиденциальными данными.\nuploadButton = Выгрузить\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Перетащите файлы сюда\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = или щёлкните здесь, чтобы отправить их (до { $size })\naddPassword = Защитить паролем\nemailPlaceholder = Введите ваш адрес электронной почты\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Войдите, чтобы отправлять файлы до { $size }\nsignInOnlyButton = Войти\naccountBenefitTitle = Создайте Аккаунт { -firefox } или войдите\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Делитесь файлами до { $size }\naccountBenefitDownloadCount = Делитесь файлами с несколькими людьми\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Оставить ссылку активной в течение { $count } дня\n        [few] Оставить ссылку активной в течение { $count } дней\n       *[other] Оставить ссылку активной в течение { $count } дней\n    }\naccountBenefitSync = Управляйте своими файлами с любого устройства\naccountBenefitMoz = Узнайте о других службах { -mozilla }\nsignOut = Выйти\nokButton = OK\ndownloadingTitle = Загрузка\nnoStreamsWarning = Этот браузер может не иметь возможности расшифровать такой большой файл.\nnoStreamsOptionCopy = Скопируйте ссылку, чтобы открыть в другом браузере\nnoStreamsOptionFirefox = Попробуйте наш любимый браузер\nnoStreamsOptionDownload = Продолжить в этом браузере\ndownloadFirefoxPromo = { -send-short-brand } доступен вам в полностью новом { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Поделитесь ссылкой на ваш файл:\nshareLinkButton = Поделиться ссылкой\n# $name is the name of the file\nshareMessage = Загрузите «{ $name }» с { -send-brand }: простой и безопасный обмен файлами\ntrailheadPromo = Существует способ защитить вашу приватность. Присоединяйтесь к Firefox.\nlearnMore = Подробнее.\ndownloadFlagged = Эта ссылка была отключена за нарушение условий использования.\ndownloadConfirmTitle = Ещё один совет\ndownloadConfirmDescription = Убедитесь, что вы доверяете человеку, который отправил вам этот файл, потому что мы не знаем, не повредит ли файл вашему устройству.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Я доверяю человеку, который отправил этот файл\n        [few] Я доверяю человеку, который отправил эти файлы\n       *[many] Я доверяю человеку, который отправил эти файлы\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Сообщить об этом файле как о подозрительном\n        [few] Сообщить об этих файлах как о подозрительных\n       *[many] Сообщить об этих файлах как о подозрительных\n    }\nreportDescription = Помогите нам понять, что происходит. Что по вашему мнению не так с этими файлами?\nreportUnknownDescription = Перейдите к адресу ссылки, о которой хотите сообщить, и щёлкните «{ reportFile }».\nreportButton = Сообщить\nreportReasonMalware = Эти файлы содержат вредоносные программы или являются частью фишинговой атаки.\nreportReasonPii = Эти файлы содержат мои личные данные.\nreportReasonAbuse = Эти файлы содержат незаконный или оскорбительный контент.\nreportReasonCopyright = Чтобы сообщить о нарушении авторских прав или товарных знаков, используйте процедуру, описанную на <a>этой странице</a>.\nreportedTitle = О файлах сообщено\nreportedDescription = Спасибо. Мы получили вашу жалобу на эти файлы.\n"
  },
  {
    "path": "public/locales/sk/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importuje sa…\nencryptingFile = Šifruje sa…\ndecryptingFile = Dešifruje sa…\ndownloadCount =\n    { $num ->\n        [one] 1 prevzatí\n        [few] { $num } prevzatiach\n       *[other] { $num } prevzatiach\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 hodine\n        [few] { $num } hodinách\n       *[other] { $num } hodinách\n    }\ncopiedUrl = Skopírované!\nunlockInputPlaceholder = Heslo\nunlockButtonLabel = Odomknúť\ndownloadButtonLabel = Prevziať\ndownloadFinish = Preberanie bolo dokončené\nfileSizeProgress = ({ $partialSize } z { $totalSize })\nsendYourFilesLink = Vyskúšajte Send\nerrorPageHeader = Vyskytol sa problém.\nfileTooBig = Súbor je príliš veľký. Mal by byť menší než { $size }.\nlinkExpiredAlt = Platnosť odkazu vypršala\nnotSupportedHeader = Váš prehliadač nie je podporovaný.\nnotSupportedLink = Prečo nie je môj prehliadač podporovaný?\nnotSupportedOutdatedDetail = Žiaľ, táto verzia Firefoxu nepodporuje webovú technológiu, ktorá poháňa Send. Budete musieť aktualizovať svoj prehliadač.\nupdateFirefox = Aktualizovať Firefox\ndeletePopupCancel = Zrušiť\ndeleteButtonHover = Odstrániť\nfooterLinkLegal = Právne informácie\nfooterLinkPrivacy = Súkromie\nfooterLinkCookies = Cookies\npasswordTryAgain = Nesprávne heslo. Skúste to znova.\njavascriptRequired = Send vyžaduje JavaScript\nwhyJavascript = Prečo Send vyžaduje JavaScript?\nenableJavascript = Prosím, povoľte JavaScript a skúste to znova.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } hod. { $minutes } min.\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } min.\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maximálna dĺžka hesla: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Heslo nešlo nastaviť\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Jednoduché a súkromné zdieľanie súborov\nintroDescription = S { -send-brand(case: \"ins\") } sú zdieľané súbory šifrované end-to-end, takže ani my nevieme, čo zdieľate. Platnosť odkazu je navyše obmedzená. Súbory tak môžete zdieľať súkromne a s istotou, že neostanú na internete naveky.\nnotifyUploadEncryptDone = Váš súbor je zašifrovaný a pripravený na odoslanie\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Platnosť odkazu vyprší po { $downloadCount } alebo po { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minúte\n        [few] { $num } minútach\n       *[other] { $num } minútach\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 dni\n        [few] { $num } dňoch\n       *[other] { $num } dňoch\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 týždni\n        [few] { $num } týždňoch\n       *[other] { $num } týždňoch\n    }\nfileCount =\n    { $num ->\n        [one] 1 súbor\n        [few] { $num } súbory\n       *[other] { $num } súborov\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = kB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Celková veľkosť: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Súbor môžete zdieľať pomocou tohto odkazu:\ncopyLinkButton = Kopírovať odkaz\ndownloadTitle = Prevziať súbory\ndownloadDescription = Tento súbor bol zdieľaný prostredníctvom služby { -send-brand }, ktorá poskytuje end-to-end šifrovanie a odkazy s obmedzenou platnosťou.\ntrySendDescription = Vyskúšajte jednoduché a bezpečné zdieľanie súborov so službou { -send-brand }\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Naraz možno nahrávať len 1 súbor.\n        [few] Naraz možno nahrávať len { $count } súbory.\n       *[other] Naraz možno nahrávať len { $count } súborov.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Povolený je najviac 1 archív.\n        [few] Povolené sú najviac { $count } archívy.\n       *[other] Povolených je najviac { $count } archívov.\n    }\nexpiredTitle = Platnosť odkazu vypršala.\nnotSupportedDescription = { -send-brand } nebude v tomto prehliadači fungovať. { -send-short-brand } najlepšie funguje v najnovšej verzii { -firefox(case: \"gen\") } alebo aktuálnych verziách najpoužívanejších prehliadačov.\ndownloadFirefox = Prevziať { -firefox }\nlegalTitle = Zásady ochrany súkromia služby { -send-short-brand }\nlegalDateStamp = Verzia 1.0, z 12. marca 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } d { $hours } h { $minutes } min\naddFilesButton = Vyberte súbory pre nahratie\ntrustWarningMessage = Uistite sa, že pri zdieľaní citlivých údajov dôverujete adresátovi.\nuploadButton = Nahrať\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Pretiahnutím súboru alebo kliknutím sem\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = môžete poslať až { $size }\naddPassword = Chrániť heslom\nemailPlaceholder = Zadajte e-mailovú adresu\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Pre odoslanie súborov s veľkosťou až { $size }, sa, prosím, prihláste\nsignInOnlyButton = Prihlásiť sa\naccountBenefitTitle = Vytvorte si účet { -firefox } alebo sa prihláste\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Zdieľanie súborov s veľkosťou až { $size }\naccountBenefitDownloadCount = Zdieľanie súborov s viacerými ľuďmi\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Odkazy platné až 1 deň\n        [few] Odkazy platné až { $count } dni\n       *[other] Odkazy platné až { $count } dní\n    }\naccountBenefitSync = Správa zdieľaných súborov z akéhokoľvek zariadenia\naccountBenefitMoz = Ďalšie informácie o ďalších službách od { -mozilla(case: \"gen\") }\nsignOut = Odhlásiť sa\nokButton = OK\ndownloadingTitle = Preberá sa\nnoStreamsWarning = Tento prehliadač nemusí byť schopný dešifrovať takto veľký súbor.\nnoStreamsOptionCopy = Skopírovať odkaz pre otvorenie v inom prehliadači\nnoStreamsOptionFirefox = Vyskúšajte náš obľúbený prehliadač\nnoStreamsOptionDownload = Pokračovať v tomto prehliadači\ndownloadFirefoxPromo = { -send-short-brand } vám prináša najnovší { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Zdieľajte odkaz na súbor:\nshareLinkButton = Zdieľať odkaz\n# $name is the name of the file\nshareMessage = Prevezmite si súbor „{ $name }“ so službou { -send-brand } - jednoduché a bezpečné zdieľanie súborov\ntrailheadPromo = Existuje spôsob, ako chrániť vaše súkromie. Prihláste sa do Firefoxu.\nlearnMore = Ďalšie informácie.\ndownloadFlagged = Tento odkaz bol pre porušenie podmienok používania služby deaktivovaný.\ndownloadConfirmTitle = Ešte jedna vec\ndownloadConfirmDescription = Uistite sa, že naozaj dôverujete odosielateľovi tohto súboru, pretože nemôžeme overiť jeho bezpečnosť.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Dôverujem odosielateľovi tohto súboru\n        [few] Dôverujem odosielateľovi týchto súborov\n       *[other] Dôverujem odosielateľovi týchto súborov\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Nahlásiť tento súbor ako podozrivý\n        [few] Nahlásiť tieto súbory ako podozrivé\n       *[other] Nahlásiť tieto súbory ako podozrivé\n    }\nreportDescription = Pomôžte nám pochopiť, čo sa deje. Čo si myslíte, že s týmito súbormi nie je v poriadku?\nreportUnknownDescription = Otvorte odkaz, ktorý chcete nahlásiť, a kliknite na „{ reportFile }“.\nreportButton = Nahlásiť\nreportReasonMalware = Tieto súbory obsahujú malvér alebo sú súčasťou pshishingového útoku.\nreportReasonPii = Tieto súbory obsahujú moje osobné údaje.\nreportReasonAbuse = Tieto súbory obsahujú nelegálny alebo urážlivý obsah.\nreportReasonCopyright = Ak chcete nahlásiť porušenie autorských práv alebo zneužitie ochranných známok, použite postup popísaný na <a>tejto stránke</a>.\nreportedTitle = Súbory boli nahlásené\nreportedDescription = Ďakujeme vám za nahlásenie týchto súborov.\n"
  },
  {
    "path": "public/locales/sl/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Uvažanje …\nencryptingFile = Šifriranje ...\ndecryptingFile = Dešifriranje ...\ndownloadCount =\n    { $num ->\n        [one] 1 prenosu\n        [two] { $num } prenosih\n        [few] { $num } prenosih\n       *[other] { $num } prenosih\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 uro\n        [two] { $num } uri\n        [few] { $num } ure\n       *[other] { $num } ur\n    }\ncopiedUrl = Kopirano!\nunlockInputPlaceholder = Geslo\nunlockButtonLabel = Odkleni\ndownloadButtonLabel = Prenesi\ndownloadFinish = Prenos končan\nfileSizeProgress = ({ $partialSize } od { $totalSize })\nsendYourFilesLink = Preskusite Send\nerrorPageHeader = Prišlo je do težave!\nfileTooBig = Ta datoteka je prevelika za nalaganje. Največja možna velikost je { $size }.\nlinkExpiredAlt = Povezava je potekla\nnotSupportedHeader = Vaš brskalnik ni podprt.\nnotSupportedLink = Zakaj moj brskalnik ni podprt?\nnotSupportedOutdatedDetail = Ta brskalnik žal ne podpira tehnologije, na kateri temelji Send. Svoj brskalnik boste morali posodobiti.\nupdateFirefox = Posodobi Firefox\ndeletePopupCancel = Prekliči\ndeleteButtonHover = Izbriši\nfooterLinkLegal = Pravno obvestilo\nfooterLinkPrivacy = Zasebnost\nfooterLinkCookies = Piškotki\npasswordTryAgain = Napačno geslo. Poskusite znova.\njavascriptRequired = Send zahteva JavaScript\nwhyJavascript = Zakaj Send zahteva JavaScript?\nenableJavascript = Omogočite JavaScript in poskusite znova.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Največja dolžina gesla: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Gesla ni mogoče nastaviti\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox =\n    { $sklon ->\n       *[imenovalnik] Firefox\n        [rodilnik] Firefoxa\n        [dajalnik] Firefoxu\n        [tozilnik] Firefox\n        [mestnik] Firefoxu\n        [orodnik] Firefoxom\n    }\n-mozilla =\n    { $sklon ->\n       *[imenovalnik] Mozilla\n        [rodilnik] Mozille\n        [dajalnik] Mozilli\n        [tozilnik] Mozillo\n        [mestnik] Mozilli\n        [orodnik] Mozillo\n    }\nintroTitle = Preprosto, zasebno deljenje datotek\nintroDescription = { -send-brand } vam omogoča v celoti šifrirano pošiljanje datotek s povezavo, ki samodejno poteče. Z njim lahko zasebno delite svoje datoteke in zagotovite, da ne bodo za vedno ostale na spletu.\nnotifyUploadEncryptDone = Vaša datoteka je šifrirana in pripravljena za pošiljanje\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Poteče po { $downloadCount } ali čez { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuto\n        [two] { $num } minuti\n        [few] { $num } minute\n       *[other] { $num } minut\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 dan\n        [two] { $num } dni\n        [few] { $num } dni\n       *[other] { $num } dni\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 teden\n        [two] { $num } tedna\n        [few] { $num } tedne\n       *[other] { $num } tednov\n    }\nfileCount =\n    { $num ->\n        [one] 1 datoteka\n        [two] { $num } datoteki\n        [few] { $num } datoteke\n       *[other] { $num } datotek\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Skupna velikost: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopirajte povezavo za deljenje datoteke:\ncopyLinkButton = Kopiraj povezavo\ndownloadTitle = Prenesi datoteke\ndownloadDescription = Ta datoteka je bila v skupni rabi preko { -send-brand } s šifriranjem od konca do konca in povezavo, ki samodejno poteče.\ntrySendDescription = Preizkusite { -send-brand } za preprosto in varno deljenje datotek.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Naložite lahko največ 1 datoteko naenkrat.\n        [two] Naložite lahko največ { $count } datoteki naenkrat.\n        [few] Naložite lahko največ { $count } datoteke naenkrat.\n       *[other] Naložite lahko največ { $count } datotek naenkrat.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Dovoljen je največ 1 arhiv.\n        [two] Dovoljena sta največ { $count } arhiva.\n        [few] Dovoljeni so največ { $count } arhivi.\n       *[other] Dovoljenih je največ { $count } arhivov.\n    }\nexpiredTitle = Ta povezava je potekla.\nnotSupportedDescription = { -send-brand } v tem brskalniku ne bo deloval. { -send-short-brand } najbolje deluje v najnovejši različici { -firefox(sklon: \"rodilnik\") }, deloval pa bo tudi v trenutni različici večine brskalnikov.\ndownloadFirefox = Prenesite { -firefox }\nlegalTitle = Obvestilo o zasebnosti za { -send-short-brand }\nlegalDateStamp = Različica 1.0, v veljavi od 12. marca 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Izberite datoteke za nalaganje\ntrustWarningMessage = Pri deljenju občutljivih podatkov bodite prepričani, da zaupate prejemniku.\nuploadButton = Naloži\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Povlecite in spustite datoteke\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = ali kliknite za pošiljanje do { $size }\naddPassword = Zaščiti z geslom\nemailPlaceholder = Vnesite e-poštni naslov\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Prijavite se za pošiljanje do { $size }\nsignInOnlyButton = Prijava\naccountBenefitTitle = Ustvarite { -firefox } Račun ali se prijavite\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Delite datoteke do velikosti { $size }\naccountBenefitDownloadCount = Delite datoteke z več osebami\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Ohranite povezave dejavne do en dan\n        [two] Ohranite povezave dejavne do { $count } dni\n        [few] Ohranite povezave dejavne do { $count } dni\n       *[other] Ohranite povezave dejavne do { $count } dni\n    }\naccountBenefitSync = Upravljajte deljene datoteke s katerekoli naprave\naccountBenefitMoz = Več o drugih storitvah { -mozilla(sklon: \"rodilnik\") }\nsignOut = Odjava\nokButton = V redu\ndownloadingTitle = Prenašanje\nnoStreamsWarning = Ta brskalnik morda ne bo zmogel dešifrirati tako velike datoteke.\nnoStreamsOptionCopy = Kopirajte povezavo, da jo odprete v drugem brskalniku\nnoStreamsOptionFirefox = Poskusite z našim najljubšim brskalnikom\nnoStreamsOptionDownload = Nadaljujte s tem brskalnikom\ndownloadFirefoxPromo = { -send-short-brand } vam omogoča čisto novi { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Delite povezavo do datoteke:\nshareLinkButton = Deli povezavo\n# $name is the name of the file\nshareMessage = Prenesite \"{ $name }\" s { -send-brand }om: enostavno in varno deljenje datotek\ntrailheadPromo = Vašo zasebnost lahko zaščitite. Pridružite se Firefoxu.\nlearnMore = Več o tem.\ndownloadFlagged = Ta povezava je bila onemogočena, ker je kršila pogoje storitve.\ndownloadConfirmTitle = Še to\ndownloadConfirmDescription = Bodite prepričani, da zaupate osebi, ki vam je poslala to datoteko, ker ne moremo preveriti, da ne bo škodovala vaši napravi.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Zaupam pošiljatelju te datoteke\n        [two] Zaupam pošiljatelju teh datotek\n        [few] Zaupam pošiljatelju teh datotek\n       *[other] Zaupam pošiljatelju teh datotek\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Prijavi sumljivo datoteko\n        [two] Prijavi sumljivi datoteki\n        [few] Prijavi sumljive datoteke\n       *[other] Prijavi sumljive datoteke\n    }\nreportDescription = Pomagajte nam razumeti, kaj se dogaja. Kaj mislite, da je s temi datotekami narobe?\nreportUnknownDescription = Obiščite naslov povezave, ki jo želite prijaviti, in kliknite »{ reportFile }«.\nreportButton = Prijavi\nreportReasonMalware = Te datoteke vsebujejo zlonamerno programsko opremo ali so del napada lažnega predstavljanja.\nreportReasonPii = Te datoteke vsebujejo osebne podatke o meni.\nreportReasonAbuse = Te datoteke vsebujejo nezakonito ali nasilno vsebino.\nreportReasonCopyright = Za prijavo kršitve avtorskih pravic ali blagovne znamke sledite postopku, opisanem na <a>tej strani</a>.\nreportedTitle = Datoteke prijavljene\nreportedDescription = Hvala. Prejeli smo vašo prijavo teh datotek.\n"
  },
  {
    "path": "public/locales/sn/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Zvirikutaurwa\nimportingFile = Kutora faira\nencryptingFile = Kuinikiriputa\nenableJavascript = Ndinokumbira mubvumidze JavaScript moedza zvekare\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }maawa { $minutes }mineti\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }mineti\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Pasiwedhi haipfuuri mavara:{ $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Pasiwedhi haina kuita\n\n## Send version 2 strings\n\n"
  },
  {
    "path": "public/locales/sq/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Po importohet…\nencryptingFile = Po fshehtëzohet…\ndecryptingFile = Po shfshehtëzohet…\ndownloadCount =\n    { $num ->\n        [one] 1 shkarkimi\n       *[other] { $num } shkarkimesh\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 ore\n       *[other] { $num } orësh\n    }\ncopiedUrl = U kopjua!\nunlockInputPlaceholder = Fjalëkalim\nunlockButtonLabel = Zhbllokoje\ndownloadButtonLabel = Shkarkoje\ndownloadFinish = Shkarkim i Plotësuar\nfileSizeProgress = ({ $partialSize } nga { $totalSize }) gjithsej\nsendYourFilesLink = Provoni Send\nerrorPageHeader = Diç shkoi ters!\nfileTooBig = Kjo kartelë është shumë e madhe për ngarkim. Do të duhej të ishte më pak se { $size }.\nlinkExpiredAlt = Lidhja skadoi\nnotSupportedHeader = Shfletuesi juaj nuk mbulohet.\nnotSupportedLink = Pse nuk mbulohet ky shfletues?\nnotSupportedOutdatedDetail = Mjerisht, ky version i Firefox-it nuk e mbulon teknologjinë web mbi të cilën bazohet Send. Do t’ju duhet të përditësoni shfletuesin tuaj.\nupdateFirefox = Përditësojeni Firefox-in\ndeletePopupCancel = Anuloje\ndeleteButtonHover = Fshije\nfooterLinkLegal = Ligjore\nfooterLinkPrivacy = Privatësi\nfooterLinkCookies = Cookies\npasswordTryAgain = Fjalëkalim i pasaktë. Riprovoni.\njavascriptRequired = Send lyp JavaScript\nwhyJavascript = Ç’i duhet Send-it JavaScript-i?\nenableJavascript = Ju lutemi, aktivizoni JavaScript-in dhe riprovoni.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Gjatësi maksimum fjalëkalimi: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Ky fjalëkalim s’u caktua dot\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Ndarje e thjeshtë, private, kartelash me të tjerët\nintroDescription = { -send-brand } ju lejon të ndani kartela me të tjerët, me fshehtëzim skaj-më-skaj dhe me një lidhje që skadon automatikisht. Kështu mund ta mbani private atë që ndani me të tjerë dhe të garantoni që gjërat tuaja s’do të qëndrojnë në linjë përgjithmonë.\nnotifyUploadEncryptDone = Kartela juaj është fshehtëzuar dhe gati për dërgim\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Skadon pas { $downloadCount } ose { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minutë\n       *[other] { $num } minuta\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 ditë\n       *[other] { $num } ditë\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 javë\n       *[other] { $num } javë\n    }\nfileCount =\n    { $num ->\n        [one] 1 kartelë\n       *[other] { $num } kartela\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Madhësia gjithsej: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopjoni lidhjen për dhënien e kartelës tuaj:\ncopyLinkButton = Kopjoje lidhjen\ndownloadTitle = Shkarkoni kartela\ndownloadDescription = Kjo kartelë u nda me të tjerët përmes { -send-brand }, me fshehtëzim skaj-më-skaj dhe një lidhje që skadon automatikisht.\ntrySendDescription = Provoni { -send-brand }, për ndarje të thjeshtë, të parrezik, kartelash me të tjerët.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Mund të ngarkohet vetëm 1 kartelë në herë.\n       *[other] Mund të ngarkohen vetëm { $count } kartela në herë.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Lejohet vetëm 1 arkiv.\n       *[other] Lejohen vetëm { $count } arkiva.\n    }\nexpiredTitle = Kjo lidhje ka skaduar.\nnotSupportedDescription = { -send-brand } s’do të funksionojë me këtë shfletues. { -send-short-brand } funksionin më mirë me versionin më të ri të { -firefox }, dhe do të funksionojë me versionin e tanishëm të shumicës së shfletuesve.\ndownloadFirefox = Shkarkoni { -firefox }\nlegalTitle = Njoftim Privatësie Për { -send-short-brand }\nlegalDateStamp = Version 1.0, daton 12 mars, 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Përzgjidhni kartela për ngarkim\ntrustWarningMessage = Sigurohuni se i besoni marrësit tuaj, kur ndani me të të dhëna rezervat.\nuploadButton = Ngarkoje\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Tërhiqni dhe lini kartela\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = ose klikoni që të dërgohen deri në { $size }\naddPassword = Mbrojini me fjalëkalim\nemailPlaceholder = Jepni email-in tuaj\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Bëni hyrjen që të dërgoni deri më { $size }\nsignInOnlyButton = Hyni\naccountBenefitTitle = Krijoni një Llogari { -firefox } ose bëni hyrjen në një të tillë\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Ndani me të tjerët kartela deri { $size }\naccountBenefitDownloadCount = Ndani kartela me më tepër persona\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Mbaji aktive lidhjet për deri 1 ditë\n       *[other] Mbaji aktive lidhjet për deri { $count } ditë\n    }\naccountBenefitSync = Administroni nga çfarëdo pajisje kartela të përbashkëta\naccountBenefitMoz = Mësoni më tepër rreth shërbimesh { -mozilla }\nsignOut = Dilni\nokButton = OK\ndownloadingTitle = Shkarkim\nnoStreamsWarning = Ky shfletues mund të mos jetë në gjendje të shfshehtëzojë një kartelë kaq të madhe.\nnoStreamsOptionCopy = Kopjoje lidhjen për ta hapur në një tjetër shfletues\nnoStreamsOptionFirefox = Provoni shfletuesin tonë të parapëlqyer\nnoStreamsOptionDownload = Vazhdo me këtë shfletues\ndownloadFirefoxPromo = { -send-short-brand } ju vjen nga { -firefox }-i i ri fringo.\n# the next line after the colon contains a file name\nshareLinkDescription = Ndani me të tjerët lidhjen për te kartela juaj:\nshareLinkButton = Ndani me të tjerët lidhjen\n# $name is the name of the file\nshareMessage = Shkarkojeni “{ $name }” me { -send-brand }: shkëmbim kartelash dhe thjesht dhe pa rrezik\ntrailheadPromo = Ka një rrugë për të mbrojtur privatësinë tuaj. Bëhuni pjesë e Firefox-it.\nlearnMore = Mësoni më tepër.\ndownloadFlagged = Kjo lidhje është çaktivizuar, ngaqë cenon kushtet e shërbimit.\ndownloadConfirmTitle = Edhe një gjë të fundit\ndownloadConfirmDescription = Sigurohuni se i besoni personit që ju dërgoi këtë kartelë, ngaqë s’mund të verifikojmë se nuk do të vërë në rrezik pajisjen tuaj.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] I besoj personit që dërgoi këtë kartelë\n       *[other] I besoj personit që dërgoi këto kartela\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Raportojeni këtë kartelë si të dyshimtë\n       *[other] Raportojeni këto kartela si të dyshimta\n    }\nreportDescription = Ndihmonani të kuptojmë ç’po ndodh. Çfarë mendoni se është gabim me këto kartela?\nreportUnknownDescription = Ju lutemi, shkoni te url-ja e lidhjes që doni të raportoni dhe klikoni mbi “{ reportFile }”.\nreportButton = Raportoje\nreportReasonMalware = Këto kartela përmbajnë <em>malware</em> ose janë pjesë e një sulmi karremëzimi.\nreportReasonPii = Këto kartela përmbajnë të dhëna personalisht të identifikueshme rreth meje.\nreportReasonAbuse = Këto kartela përmbajnë lëndë të paligjshme ose abuzive.\nreportReasonCopyright = Për të raportuar cenim të drejtash kopjimi ose shenjash tregtare, përdorni procesin e përshkruar në <a>këtë faqe</a>.\nreportedTitle = Kartela të Raportuara\nreportedDescription = Faleminderit. E kemimarrë raportin tuaj rreth këtyre kartelave.\n"
  },
  {
    "path": "public/locales/sr/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Увозим…\nencryptingFile = Шифрујем…\ndecryptingFile = Дешифрујем…\ndownloadCount =\n    { $num ->\n        [one] { $num } преузимања\n        [few] { $num } преузимања\n       *[other] { $num } преузимања\n    }\ntimespanHours =\n    { $num ->\n        [one] { $num } сата\n        [few] { $num } сата\n       *[other] { $num } сати\n    }\ncopiedUrl = Ископирано!\nunlockInputPlaceholder = Лозинка\nunlockButtonLabel = Откључај\ndownloadButtonLabel = Преузми\ndownloadFinish = Преузимање је завршено.\nfileSizeProgress = ({ $partialSize } од { $totalSize })\nsendYourFilesLink = Испробајте Send\nerrorPageHeader = Нешто је пошло наопако!\nfileTooBig = Та датотека је превелика за отпремање. Треба да буде мања од { $size }.\nlinkExpiredAlt = Веза је истекла\nnotSupportedHeader = Ваш прегледач није подржан.\nnotSupportedLink = Зашто мој прегледач није подржан?\nnotSupportedOutdatedDetail = Нажалост, ово издање Firefox-a не подржава веб технологију која омогућава Send. Мораћете да ажурирате ваш прегледач.\nupdateFirefox = Ажурирај Firefox\ndeletePopupCancel = Откажи\ndeleteButtonHover = Обриши\nfooterLinkLegal = Правни подаци\nfooterLinkPrivacy = Приватност\nfooterLinkCookies = Колачићи\npasswordTryAgain = Нетачна лозинка. Пробајте поново.\njavascriptRequired = За Send је потребан JavaScript\nwhyJavascript = Зашто је потребан JavaScript за Send?\nenableJavascript = Омогућите JavaScript и пробајте поново.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }ч { $minutes }м\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }м\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Највећа дужина лозинке: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Не можемо поставити ову лозинку\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Једноставно и приватно дељење датотека\nintroDescription = { -send-brand } вам дозвољава да делите датотеке које су шифроване с краја на крај преко везе која самостално истиче. Тако да можете приватно делити ваше ствари које неће остати на вебу заувек.\nnotifyUploadEncryptDone = Ваша датотека је шифрована и спремна за слање\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Истиче након { $downloadCount } или { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] { $num } минут\n        [few] { $num } минута\n       *[other] { $num } минута\n    }\ntimespanDays =\n    { $num ->\n        [one] { $num } дан\n        [few] { $num } дана\n       *[other] { $num } дана\n    }\ntimespanWeeks =\n    { $num ->\n        [one] { $num } недеља\n        [few] { $num } недеље\n       *[other] { $num } недеља\n    }\nfileCount =\n    { $num ->\n        [one] { $num } датотека\n        [few] { $num } датотеке\n       *[other] { $num } датотека\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Укупна величина: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Копирајте везу да бисте поделили вашу датотеку:\ncopyLinkButton = Копирај везу\ndownloadTitle = Преузми датотеке\ndownloadDescription = Ова датотека је подељена преко услуге { -send-brand } која омогућава шифровање с краја на крај преко везе која самостално истиче.\ntrySendDescription = Пробајте { -send-brand } за једноставно и безбедно дељење датотека.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Можете отпремити само { $count } датотеку истовремено.\n        [few] Можете отпремити само { $count } датотеке истовремено.\n       *[other] Можете отпремити само { $count } датотека истовремено.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Дозвољена је само { $count } архива.\n        [few] Дозвољене су само { $count } архиве.\n       *[other] Дозвољено је само { $count } архива.\n    }\nexpiredTitle = Ова веза је истекла.\nnotSupportedDescription = { -send-brand } неће радити у овом прегледачу. { -send-short-brand } најбоље ради са последњим издањем прегледача { -firefox } и радиће са тренутним издањима већине других прегледача.\ndownloadFirefox = Преузми { -firefox }\nlegalTitle = Политика приватности услуге { -send-short-brand }\nlegalDateStamp = Издање 1.0, датум објављивања 12. март 2019. године\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }д { $hours }ч { $minutes }м\naddFilesButton = Изаберите датотеке за отпремање\ntrustWarningMessage = Будите сигурни да верујете примаоцу пре дељења осетљивих података.\nuploadButton = Отпреми\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Превуците и пустите датотеке\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = или кликните за слање садржаја великог до { $size }\naddPassword = Заштитите лозинком\nemailPlaceholder = Унесите вашу е-адресу\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Пријавите се да пошаљете садржај до { $size }\nsignInOnlyButton = Пријавите се\naccountBenefitTitle = Направите { -firefox } налог или се пријавите\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Поделите датотеке велике до { $size }\naccountBenefitDownloadCount = Поделите датотеке са више особа\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Остави везе активним највише { $count } дан\n        [few] Остави везе активним највише { $count } дана\n       *[other] Остави везе активним највише { $count } дана\n    }\naccountBenefitSync = Управљајте подељеним датотекама са било ког уређаја\naccountBenefitMoz = Сазнајте више о другим { -mozilla }-иним услугама\nsignOut = Одјава\nokButton = У реду\ndownloadingTitle = Преузимам\nnoStreamsWarning = Овај прегледач можда неће моћи да дешифрује оволико велику датотеку.\nnoStreamsOptionCopy = Копирај везу за отварање у другом прегледачу\nnoStreamsOptionFirefox = Пробајте наш омиљени прегледач\nnoStreamsOptionDownload = Наставите у овом прегледачу\ndownloadFirefoxPromo = { -send-short-brand } вам је омогућен захваљући потпуно новом програму { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Поделите везу до датотеке:\nshareLinkButton = Поделите везу\n# $name is the name of the file\nshareMessage = Преузмите „{ $name }“ помоћу програма { -send-brand }:  једноставно и безбедно дељење датотека\ntrailheadPromo = Постоји начин да заштитите вашу приватност. Придружите се Firefox-у.\nlearnMore = Сазнајте више.\ndownloadFlagged = Ова веза је онемогућена због кршења услова услуге.\ndownloadConfirmTitle = Још једна ствар\ndownloadConfirmDescription = Будите сигурни да верујете особи која вам је послала ову датотеку, јер не можемо обећати да неће оштетити ваш уређа.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Верујем особи која је послала ову датотеку\n        [few] Верујем особи која је послала ове датотеке\n       *[other] Верујем особама које су послале ове датотеке\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Пријави ову датотеку као сумњиву\n        [few] Пријави ове датотеке као сумњиве\n       *[other] Пријави ове датотеке као сумњиве\n    }\nreportDescription = Помозите нам да схватимо шта се дешава. Шта мислите да није у реду са овим датотекама?\nreportUnknownDescription = Идите на адресу везе коју желите да пријавите и изаберите “{ reportFile }”.\nreportButton = Пријави\nreportReasonMalware = Ове датотеке садрже злонамеран софтвер или су део напада за крађу идентитета.\nreportReasonPii = Ове датотеке садрже моје личне податке.\nreportReasonAbuse = Ове датотеке садрже илегални или насилни садржај.\nreportReasonCopyright = Да бисте пријавили кршење ауторских права или заштитног знака, следите кораке на <a>овој страници</a>.\nreportedTitle = Датотеке су пријављене\nreportedDescription = Хвала вам. Примили смо вашу пријаву ових датотека.\n"
  },
  {
    "path": "public/locales/su/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Ngimpor...\nencryptingFile = Ngénkripsi...\ndecryptingFile = Ngadékripsi...\ndownloadCount =\n    { $num ->\n       *[other] { $num } undeuran\n    }\ntimespanHours =\n    { $num ->\n       *[other] { $num } jam\n    }\ncopiedUrl = Ditiron!\nunlockInputPlaceholder = Kecap sandi\nunlockButtonLabel = Laan konci\ndownloadButtonLabel = Undeur\ndownloadFinish = Undeuran anggeus\nfileSizeProgress = ({ $partialSize } ti { $totalSize })\nsendYourFilesLink = Pecakan Send\nerrorPageHeader = Aya nu salah!\nfileTooBig = Koropak unjalkeuneun badag teuing. Kudu kurang ti { $size }.\nlinkExpiredAlt = Tutumbu kadaluwarsa\nnotSupportedHeader = Panyungsi anjeun teu dirojong\nnotSupportedLink = Naha panyungsi kuring teu dirojong?\nnotSupportedOutdatedDetail = Hanjakal Firefox vérsi ieu teu ngarojong téhnologi wéb nu ngagerakkeun Send. Anjeun perlu ngapdét panyungsi anjeun.\nupdateFirefox = Apdét Firefox\ndeletePopupCancel = Bolay\ndeleteButtonHover = Pupus\nfooterLinkLegal = Légal\nfooterLinkPrivacy = Privasi\nfooterLinkCookies = Réréméh\npasswordTryAgain = Kecap sandi salah. Pecakan deui.\njavascriptRequired = Send merlukeun JavaScript\nwhyJavascript = Naha Send merlukeun JavaScript?\nenableJavascript = Prak hurungkeun JavaScript sarta pecakan deui.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }j { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Panjang sandi maksimal: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Ieu kecap sandi teu bisa disét\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Simpel, babagi koropak privat\nintroDescription = { -send-brand } migampang anjeun babagi koropak kalawan énkripsi tungtung-ka-tungtung sarta tutumbu nu otomatis kadaluwarsa. Sahingga anjeun bisa ngaraksa naon nu ku anjeun bagi sacara privat jeung mastikeun banda anjeun teu salawasna daring.\nnotifyUploadEncryptDone = Koropak anjeun kaénkripsi sarta siap dikirim.\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Kadaluwarsa sanggeu { $downloadCount } atawa { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] samenit\n       *[other] { $num } menit\n    }\ntimespanDays =\n    { $num ->\n        [one] sapoé\n       *[other] { $num } poé\n    }\ntimespanWeeks =\n    { $num ->\n        [one] saminggu\n       *[other] { $num } minggu\n    }\nfileCount =\n    { $num ->\n        [one] sakoropak\n       *[other] { $num } koropak\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Ukuran total: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Tiron tutumbu pikeun babagi koropak anjeun:\ncopyLinkButton = Tiron tutumbu\ndownloadTitle = Undeur koropak\ndownloadDescription = Ieu koropak geus dibagikeun liwat { -send-brand } kalawan énkripsi tungtung-ka-tungtung sarta tutumbuna otomatis kadaluwarsa.\ntrySendDescription = Pecakan { -send-brand } pikeun simpelna, babagi koropak aman.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Ayeuna kur sakoropak nu bisa diunjal.\n       *[other] Ngan { $count } koropak nu bisa diunjal sakaligus.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Ngan saarsip nu diidinan.\n       *[other] Ngan { $count } arsip nu diidinan.\n    }\nexpiredTitle = Ieu tutumbu geus kadaluwarsa.\nnotSupportedDescription = { -send-brand } moal jalan di ieu panyungsi. { -send-short-brand } jalan naker dina { -firefox } vérsi pamganyarna, sarta bakal jalan di loba panyungsi vérsi kiwari.\ndownloadFirefox = Undeur { -firefox }\nlegalTitle = { -send-short-brand } Wawar Privasi\nlegalDateStamp = Versi 1.0, kaping 12 Maret 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }p { $hours }j { $minutes }m\naddFilesButton = Pilih koropak unjalkeuneun\ntrustWarningMessage = Sing yakin yén anjeun percaya nalika ngabagi data sénsitip ka nu nampa.\nuploadButton = Unjal\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Ésérkeun sarta ésotkeun koropak\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = atawa klik pikeun ngirim nika { $size }\naddPassword = Piningan ku kecap sandi\nemailPlaceholder = Asupkeun surélék anjeun\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Asup sangkan bisa ngirim nika { $size }\nsignInOnlyButton = Asup\naccountBenefitTitle = Jieun akun { -firefox } atawa asup\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Bagikeun koropak nika { $size }\naccountBenefitDownloadCount = Bagikeun koropak ka balaréa\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Aktipkeun tutumbu jang sapoéeun\n       *[other] Aktipkeun tutumbu jang { $count } poé\n    }\naccountBenefitSync = Kokolakeun koropak nu dibagikeun ti parangkat mana wé\naccountBenefitMoz = Tengetan ngeunaan layanan { -mozilla } lianna\nsignOut = Kaluar\nokButton = OKÉH\ndownloadingTitle = Ngundeur\nnoStreamsWarning = Ieu panyungsi kawasna mah teu bisa ngadékrip koropak badag kieu.\nnoStreamsOptionCopy = Tiron tutumbu jang bukaeun di panyungsi séjén\nnoStreamsOptionFirefox = Pecakan panyungsi karesep kami\nnoStreamsOptionDownload = Tuluykeun ku ieu panyungsi\ndownloadFirefoxPromo = { -send-short-brand } téh disanggakeun keur anjeun kalawan { -firefox } sarwa anyar.\n# the next line after the colon contains a file name\nshareLinkDescription = Bagikeun tutumbu ka koropak anjeun:\nshareLinkButton = Bagikeun tutumbu\n# $name is the name of the file\nshareMessage = Undeur \"{ $name }\" ku { -send-brand }: simpel, babagi koropak aman\ntrailheadPromo = Aya cara pikeun ngamankeun privasi anjeun.  Jabung jeung Firefox.\nlearnMore = Lenyepan.\ndownloadFlagged = Ieu tutumbu ditumpurkeun alatan ngarumpak katangtuan layanan.\ndownloadConfirmTitle = Hiji deui\ndownloadConfirmDescription = Sing yakin yén anjeun percaya ka jalma nu ngirim ieu berkas kusabab kami teu bisa mariksa kaamanan ieu berkas.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n       *[other] Kami percaya ka jalma nu ngirim ieu berkas\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n       *[other] Laporkeun ieu berkas salaku picurigaeun\n    }\nreportDescription = Béjakeun ka kami masalahna. Naon anu sakirana salah dina ieu berkas?\nreportUnknownDescription = Mangga buka url tutumbu anu rék dilaporkeun sarta klik “{ reportFile }”.\nreportButton = Laporkeun\nreportReasonMalware = Ieu berkas ngandung malwér atawa bagian ti tarajang pising.\nreportReasonPii = Ieu berkas ngandung émbaran pribadi kami.\nreportReasonAbuse = Ieu berkas ngandung kontén ilégal atawa panyalahgunaan.\nreportReasonCopyright = Pikeun ngalaporkeun rumpakan hak cipta atawa mérk dagang, paké prosés anu diécéskeun <a>di dieu</a>.\nreportedTitle = Berkas Dilaporkeun\nreportedDescription = Nuhun. Laporan anjeun ngeunaan ieu berkas geus katampa.\n"
  },
  {
    "path": "public/locales/sv-SE/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Importerar…\nencryptingFile = Krypterar…\ndecryptingFile = Avkodar…\ndownloadCount =\n    { $num ->\n        [one] 1 nedladdning\n       *[other] { $num } nedladdningar\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 timme\n       *[other] { $num } timmar\n    }\ncopiedUrl = Kopierad!\nunlockInputPlaceholder = Lösenord\nunlockButtonLabel = Lås upp\ndownloadButtonLabel = Ladda ner\ndownloadFinish = Nedladdning klar\nfileSizeProgress = ({ $partialSize } av { $totalSize })\nsendYourFilesLink = Testa Send\nerrorPageHeader = Något gick fel!\nfileTooBig = Den filen är för stor för att ladda upp. Det ska vara mindre än { $size }.\nlinkExpiredAlt = Länk upphörd\nnotSupportedHeader = Din webbläsare stöds inte.\nnotSupportedLink = Varför stöds inte min webbläsare?\nnotSupportedOutdatedDetail = Tyvärr stödjer den här versionen av Firefox inte webbtekniken som driver Send. Du måste uppdatera din webbläsare.\nupdateFirefox = Uppdatera Firefox\ndeletePopupCancel = Avbryt\ndeleteButtonHover = Ta bort\nfooterLinkLegal = Juridisk information\nfooterLinkPrivacy = Sekretess\nfooterLinkCookies = Kakor\npasswordTryAgain = Felaktigt lösenord. Försök igen.\njavascriptRequired = Send kräver JavaScript\nwhyJavascript = Varför kräver Send JavaScript?\nenableJavascript = Aktivera JavaScript och försök igen.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }t { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maximal lösenordslängd: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Det här lösenordet kunde inte ställas in\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Enkel, privat fildelning\nintroDescription = { -send-brand } låter dig dela filer med end-to-end-kryptering och en länk som automatiskt upphör. Så att du kan behålla det du delar privat och se till att dina saker inte stannar online för alltid.\nnotifyUploadEncryptDone = Din fil är krypterad och redo att skickas\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Förfaller efter { $downloadCount } eller { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minut\n       *[other] { $num } minuter\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 dag\n       *[other] { $num } dagar\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 vecka\n       *[other] { $num } veckor\n    }\nfileCount =\n    { $num ->\n        [one] 1 fil\n       *[other] { $num } filer\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = kB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Total storlek: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopiera länken för att dela din fil:\ncopyLinkButton = Kopiera länk\ndownloadTitle = Ladda ner filer\ndownloadDescription = Den här filen delades via { -send-brand } med end-to-end-kryptering och en länk som automatiskt upphör.\ntrySendDescription = Prova { -send-brand } för enkel, säker fildelning.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Endast 1 fil  kan laddas upp i taget.\n       *[other] Endast { $count } filer kan laddas upp i taget.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Endast 1 arkiv är tillåten.\n       *[other] Endast { $count } arkiv är tillåtna.\n    }\nexpiredTitle = Den här länken har upphört.\nnotSupportedDescription = { -send-brand } fungerar inte med den här webbläsaren. { -send-short-brand } fungerar bäst med den senaste versionen av { -firefox } och kommer att fungera med den nuvarande versionen av de flesta webbläsare.\ndownloadFirefox = Hämta { -firefox }\nlegalTitle = { -send-short-brand } sekretesspolicy\nlegalDateStamp = Version 1.0, daterad den 12 mars 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }t { $minutes }m\naddFilesButton = Välj filer som ska laddas upp\ntrustWarningMessage = Se till att du litar på din mottagare när du delar känslig information.\nuploadButton = Ladda upp\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Dra och släpp filer\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = eller klicka för att skicka upp till { $size }\naddPassword = Skydda med lösenord\nemailPlaceholder = Ange din e-postadress\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Logga in för att skicka upp till { $size }\nsignInOnlyButton = Logga in\naccountBenefitTitle = Skapa ett { -firefox }-konto eller logga in\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Dela filer upp till { $size }\naccountBenefitDownloadCount = Dela filer med fler personer\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Håll länk aktiv i upp till 1 dag\n       *[other] Håll länkar aktiva i upp till { $count } dagar\n    }\naccountBenefitSync = Hantera delade filer från vilken enhet som helst\naccountBenefitMoz = Läs om andra { -mozilla }-tjänster\nsignOut = Logga ut\nokButton = OK\ndownloadingTitle = Laddar ner\nnoStreamsWarning = Den här webbläsaren kanske inte kan dekryptera en så stor fil.\nnoStreamsOptionCopy = Kopiera länken för att öppna i en annan webbläsare\nnoStreamsOptionFirefox = Prova vår favoritwebbläsare\nnoStreamsOptionDownload = Fortsätt med den här webbläsaren\ndownloadFirefoxPromo = { -send-short-brand } presenteras för dig av den helt nya { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Dela länken till din fil:\nshareLinkButton = Dela länk\n# $name is the name of the file\nshareMessage = Ladda ner \"{ $name }\" med { -send-brand }: enkel, säker fildelning\ntrailheadPromo = Det finns ett sätt att skydda din integritet. Gå med i Firefox.\nlearnMore = Läs mer.\ndownloadFlagged = Den här länken har inaktiverats pga brott mot användarvillkoren.\ndownloadConfirmTitle = En sak till\ndownloadConfirmDescription = Se till att du litar på personen som skickade dig den här filen eftersom vi inte kan verifiera att den inte skadar din enhet.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Jag litar på personen som skickade denna filen\n       *[other] Jag litar på personen som skickade dessa filer\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Rapportera denna filen som misstänkt\n       *[other] Rapportera dessa filer som misstänkta\n    }\nreportDescription = Hjälp oss att förstå vad som händer. Vad tycker du är fel med dessa filer?\nreportUnknownDescription = Gå till den url till länken du vill rapportera och klicka på \"{ reportFile }\".\nreportButton = Rapportera\nreportReasonMalware = Dessa filer innehåller skadlig kod eller är en del av en nätfiskeattack.\nreportReasonPii = Dessa filer innehåller personlig identifierbar information om mig.\nreportReasonAbuse = Dessa filer innehåller olagligt eller våldsamt innehåll.\nreportReasonCopyright = För att rapportera intrång i upphovsrätt eller varumärke, använd processen som beskrivs på <a>den här sidan</a>.\nreportedTitle = Rapporterade filer\nreportedDescription = Tack. Vi har fått din rapport om dessa filer.\n"
  },
  {
    "path": "public/locales/te/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = దిగుమతవుతోంది...\nencryptingFile = గుప్తీకరిస్తోంది...\ndecryptingFile = వ్యక్తపరుస్తోంది...\ndownloadCount =\n    { $num ->\n        [one] 1 దింపుకోలు\n       *[other] { $num } దింపుకోళ్ళు\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 గంట\n       *[other] { $num } గంటలు\n    }\ncopiedUrl = నకలు చేయబడింది!\nunlockInputPlaceholder = సంకేతపదం\nunlockButtonLabel = తాళం తీయి\ndownloadButtonLabel = దిగుమతి\ndownloadFinish = దిగుమతి పూర్తయింది\nfileSizeProgress = { $totalSize }) యొక్క ({ $partialSize }\nsendYourFilesLink = Firefox sendను ప్రయత్నించండి\nerrorPageHeader = ఏదో తప్పిదం జరిగింది!\nfileTooBig = ఆ ఫైలు ఎక్కించడానికి చాలా పెద్దగా ఉంది. ఫైళ్ళు { $size } కంటే తక్కువ పరిమాణంలో ఉండాలి.\nlinkExpiredAlt = లంకె గడువు ముగిసింది\nnotSupportedHeader = మీ విహారిణికి మద్దతు లేదు.\nnotSupportedLink = నా విహారిణికి ఎందుకు మద్దతు లేదు?\nnotSupportedOutdatedDetail = దురదృష్టవశాత్తు Firefox యొక్క ఈ వెర్షన్ Firefox సాంకేతికతను పంపే వెబ్ సాంకేతికతకు మద్దతు ఇవ్వదు. మీరు మీ బ్రౌజర్ని నవీకరించాలి.\nupdateFirefox = Firefoxను నవీకరించు\ndeletePopupCancel = రద్దుచేయి\ndeleteButtonHover = తొలగించు\nfooterLinkLegal = చట్టపరమైన\nfooterLinkPrivacy = గోప్యత\nfooterLinkCookies = కుకీలు\npasswordTryAgain = సరికాని సంకేతపదం. మళ్ళీ ప్రయత్నించండి.\njavascriptRequired = Sendకి జావాస్క్రిప్టు కావాలి\nwhyJavascript = Sendకి జావాస్క్రిప్టు ఎందుకు కావాలి?\nenableJavascript = జావాస్క్రిప్టు చేతనంచేసి మళ్ళీ ప్రయత్నించండి.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }గం { $minutes }ని\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }ని\n# A short status message shown when the user enters a long password\nmaxPasswordLength = సంకేతపదం గరిష్ఠ పొడవు: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = ఈ సంకేతపదం పెట్టలేకపోయాం\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = పంపించు\n-firefox = Firefox\n-mozilla = Mozilla\nnotifyUploadEncryptDone = మీ ఫైలు గుప్తీకరించబడింది, పంపడానికి సిద్ధంగా ఉంది\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = { $downloadCount } లేదా { $timespan } తర్వాత కాలంచెల్లుతుంది\ntimespanMinutes =\n    { $num ->\n        [one] 1 నిమిషం\n       *[other] { $num } నిమిషాలు\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 రోజు\n       *[other] { $num } రోజులు\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 వారం\n       *[other] { $num } వారాలు\n    }\nfileCount =\n    { $num ->\n        [one] 1 ఫైలు\n       *[other] { $num } ఫైళ్లు\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = మొత్తం పరిమాణం: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = మీ ఫైలును భాగస్వామ్యం చేయడానికి ఈ లంకెను నకలు చేయండి:\ncopyLinkButton = లంకెను నకలుతీయి\ndownloadTitle = ఫైళ్లను దింపుకోండి\nexpiredTitle = ఈ లంకె గడువు ముగిసింది.\ndownloadFirefox = { -firefox } ను దింపుకోండి\nlegalTitle = { -send-short-brand } గోప్యతా నోటీసు\nlegalDateStamp = వెర్షన్ 1.0, మార్చి 12, 2019 నాటిది\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = ఎక్కించడానికి ఫైళ్ళను ఎంచుకోండి\nuploadButton = ఎక్కించు\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = ఫైళ్ళను లాగండి మరియు వదలండి\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = లేదా { $size } వరకు పంపడానికి నొక్కండి\naddPassword = సంకేతపదంతో రక్షించండి\nemailPlaceholder = ఈ ఈమెయిలును ఇవ్వండి\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = { $size } వరకు పంపడానికి ప్రవేశించండి\nsignInOnlyButton = ప్రవేశించండి\naccountBenefitTitle = ఒక { -firefox } ఖాతాని సృష్టించండి లేదా ప్రవేశించండి\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = { $size } పరిమాణం ఫైళ్ళ వరకు పంచుకోండి\naccountBenefitDownloadCount = ఫైళ్లను ఎక్కువ మందితో పంచుకోండి\naccountBenefitTimeLimit =\n    { $count ->\n       *[other] లంకెలను { $count } రోజుల వరకు చేతనంగా ఉంచు\n    }\naccountBenefitSync = ఏదైనా పరికరం నుండి పంచుకున్న ఫైళ్ళను నిర్వహించండి\naccountBenefitMoz = ఇతర { -mozilla } సేవల గురించి తెలుసుకోండి\nsignOut = నిష్క్రమించు\nokButton = సరే\ndownloadingTitle = దింపుకుంటోంది\nnoStreamsWarning = ఈ బ్రౌజర్ ఈ ఫైలును పెద్దగా డీక్రిప్ట్ చేయలేకపోవచ్చు.\nnoStreamsOptionCopy = మరొక బ్రౌజర్‌లో తెరవడానికి లంకెను నకలు చేయండి\nnoStreamsOptionFirefox = మా అభిమాన బ్రౌజర్‌ను ప్రయత్నించండి\nnoStreamsOptionDownload = ఈ బ్రౌజర్‌తో కొనసాగించండి\ndownloadFirefoxPromo = { -send-short-brand } క్రొత్త { -firefox } ద్వారా మీ ముందుకు తీసుకురాబడుతుంది.\n# the next line after the colon contains a file name\nshareLinkDescription = మీ ఫైలుకు లంకెను పంచుకోండి:\nshareLinkButton = లంకెను పంచుకోండి\n# $name is the name of the file\nshareMessage = “{ $name }”‌ని { -send-brand }తో దించుకోండి: తేలికైన, సురక్షితమైన ఫైలు పంచుకోలు సేవ\ntrailheadPromo = మీ అంతరంగికతను కాపాడుకోడానికి ఓ మార్గం ఉంది. Firefoxతో చేరండి.\nlearnMore = ఇంకా తెలుసుకోండి.\n"
  },
  {
    "path": "public/locales/th/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = กำลังนำเข้า…\nencryptingFile = กำลังเข้ารหัส…\ndecryptingFile = กำลังถอดรหัส…\ndownloadCount =\n    { $num ->\n       *[other] { $num } การดาวน์โหลด\n    }\ntimespanHours =\n    { $num ->\n       *[other] { $num } ชั่วโมง\n    }\ncopiedUrl = คัดลอกแล้ว!\nunlockInputPlaceholder = รหัสผ่าน\nunlockButtonLabel = ปลดล็อก\ndownloadButtonLabel = ดาวน์โหลด\ndownloadFinish = การดาวน์โหลดเสร็จสมบูรณ์\nfileSizeProgress = ({ $partialSize } จาก { $totalSize })\nsendYourFilesLink = ลองใช้ Send\nerrorPageHeader = มีบางอย่างผิดพลาด!\nfileTooBig = ไฟล์นั้นใหญ่เกินกว่าจะอัปโหลดได้ ไฟล์ที่จะอัปโหลดควรมีขนาดน้อยกว่า { $size }\nlinkExpiredAlt = ลิงก์หมดอายุแล้ว\nnotSupportedHeader = ไม่รองรับเบราว์เซอร์ของคุณ\nnotSupportedLink = ทำไมจึงไม่รองรับเบราว์เซอร์ของฉัน?\nnotSupportedOutdatedDetail = น่าเสียดายที่ Firefox รุ่นนี้ไม่สนับสนุนเทคโนโลยีเว็บที่ขับเคลื่อน Send คุณจะต้องอัปเดตเบราว์เซอร์ของคุณ\nupdateFirefox = อัปเดต Firefox\ndeletePopupCancel = ยกเลิก\ndeleteButtonHover = ลบ\nfooterLinkLegal = ข้อกฎหมาย\nfooterLinkPrivacy = ความเป็นส่วนตัว\nfooterLinkCookies = คุกกี้\npasswordTryAgain = รหัสผ่านไม่ถูกต้อง ลองอีกครั้ง\njavascriptRequired = Send จำเป็นต้องใช้ JavaScript\nwhyJavascript = ทำไม Send จึงจำเป็นต้องใช้ JavaScript?\nenableJavascript = โปรดเปิดใช้งาน JavaScript แล้วลองอีกครั้ง\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } ชม. { $minutes } นาที\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } นาที\n# A short status message shown when the user enters a long password\nmaxPasswordLength = ความยาวรหัสผ่านสูงสุด: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = ไม่สามารถตั้งรหัสผ่านนี้ได้\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = การแบ่งปันไฟล์ที่ง่ายและเป็นส่วนตัว\nintroDescription = { -send-brand } ให้คุณแบ่งปันไฟล์ด้วยการเข้ารหัสจากต้นทางถึงปลายทางและลิงก์ที่หมดอายุโดยอัตโนมัติ คุณจึงสามารถเก็บสิ่งที่คุณแบ่งปันไว้เป็นส่วนตัวและตรวจสอบให้แน่ใจว่าข้อมูลของคุณจะไม่ออนไลน์ตลอดไป\nnotifyUploadEncryptDone = ไฟล์ของคุณได้รับการเข้ารหัสและพร้อมส่ง\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = หมดอายุหลังจาก { $downloadCount } หรือ { $timespan }\ntimespanMinutes =\n    { $num ->\n       *[other] { $num } นาที\n    }\ntimespanDays =\n    { $num ->\n       *[other] { $num } วัน\n    }\ntimespanWeeks =\n    { $num ->\n       *[other] { $num } สัปดาห์\n    }\nfileCount =\n    { $num ->\n       *[other] { $num } ไฟล์\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = ขนาดรวม: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = คัดลอกลิงก์เพื่อแบ่งปันไฟล์ของคุณ:\ncopyLinkButton = คัดลอกลิงก์\ndownloadTitle = ดาวน์โหลดไฟล์\ndownloadDescription = ไฟล์นี้ถูกแบ่งปันผ่าน { -send-brand } พร้อมการเข้ารหัสจากต้นทางถึงปลายทางและลิงก์ที่หมดอายุโดยอัตโนมัติ\ntrySendDescription = ลองใช้ { -send-brand } สำหรับการแบ่งปันไฟล์ที่ง่ายและปลอดภัย\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n       *[other] สามารถอัปโหลดได้ครั้งละ { $count } ไฟล์เท่านั้น\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n       *[other] สามารถอัปโหลดไฟล์เก็บถาวรได้เพียง { $count } ไฟล์เท่านั้น\n    }\nexpiredTitle = ลิงก์นี้หมดอายุแล้ว\nnotSupportedDescription = { -send-brand } จะไม่ทำงานกับเบราว์เซอร์นี้ { -send-short-brand } จะทำงานได้ดีที่สุดกับ { -firefox } รุ่นล่าสุด และจะทำงานกับเบราว์เซอร์ส่วนใหญ่ที่เป็นรุ่นปัจจุบัน\ndownloadFirefox = ดาวน์โหลด { -firefox }\nlegalTitle = ประกาศความเป็นส่วนตัวของ { -send-short-brand }\nlegalDateStamp = รุ่น 1.0 วันที่ 12 มีนาคม 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } วัน { $hours } ชม. { $minutes } นาที\naddFilesButton = เลือกไฟล์ที่จะอัปโหลด\ntrustWarningMessage = ตรวจสอบให้แน่ใจว่าคุณเชื่อใจผู้รับของคุณขณะที่คุณแบ่งปันข้อมูลที่ละเอียดอ่อน\nuploadButton = อัปโหลด\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = ลากแล้วปล่อยไฟล์\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = หรือคลิกเพื่อส่งได้ถึง { $size }\naddPassword = ปกป้องด้วยรหัสผ่าน\nemailPlaceholder = ป้อนอีเมลของคุณ\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = ลงชื่อเข้าเพื่อส่งได้ถึง { $size }\nsignInOnlyButton = ลงชื่อเข้า\naccountBenefitTitle = สร้างบัญชี { -firefox } หรือลงชื่อเข้า\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = แบ่งปันไฟล์สูงสุดถึง { $size }\naccountBenefitDownloadCount = แบ่งปันไฟล์กับผู้คนมากขึ้น\naccountBenefitTimeLimit =\n    { $count ->\n       *[other] ให้ลิงก์ใช้งานได้นานถึง { $count } วัน\n    }\naccountBenefitSync = จัดการไฟล์ที่แบ่งปันจากอุปกรณ์ใด ๆ\naccountBenefitMoz = เรียนรู้เกี่ยวกับบริการ { -mozilla } อื่น ๆ\nsignOut = ลงชื่อออก\nokButton = ตกลง\ndownloadingTitle = กำลังดาวน์โหลด\nnoStreamsWarning = เบราว์เซอร์นี้อาจไม่สามารถถอดรหัสไฟล์ขนาดใหญ่เท่านี้ได้\nnoStreamsOptionCopy = คัดลอกลิงก์เพื่อเปิดในเบราว์เซอร์อื่น\nnoStreamsOptionFirefox = ลองเบราว์เซอร์โปรดของเรา\nnoStreamsOptionDownload = ดำเนินการต่อด้วยเบราว์เซอร์นี้\ndownloadFirefoxPromo = { -send-short-brand } สนับสนุนโดย { -firefox } โฉมใหม่\n# the next line after the colon contains a file name\nshareLinkDescription = แบ่งปันลิงก์ไปยังไฟล์ของคุณ:\nshareLinkButton = แบ่งปันลิงก์\n# $name is the name of the file\nshareMessage = ดาวน์โหลด “{ $name }” ด้วย { -send-brand }: การแบ่งปันไฟล์ที่ง่ายและเป็นส่วนตัว\ntrailheadPromo = มีวิธีปกป้องความเป็นส่วนตัวของคุณ เข้าร่วม Firefox\nlearnMore = เรียนรู้เพิ่มเติม\ndownloadFlagged = ลิงก์นี้ถูกปิดการใช้งานเนื่องจากละเมิดข้อกำหนดในการให้บริการ\ndownloadConfirmTitle = อีกหนึ่งอย่าง\ndownloadConfirmDescription = ตรวจสอบให้แน่ใจว่าคุณเชื่อถือคนที่ส่งไฟล์นี้ให้คุณ เพราะเราไม่สามารถยืนยันได้ว่าไฟล์นี้จะไม่เป็นอันตรายต่ออุปกรณ์ของคุณ\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n       *[other] ฉันเชื่อใจคนที่ส่งไฟล์เหล่านี้\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n       *[other] รายงานไฟล์เหล่านี้ว่าน่าสงสัย\n    }\nreportDescription = ช่วยให้เราเข้าใจสิ่งที่เกิดขึ้น คุณคิดอย่างไรว่าไฟล์เหล่านี้ผิดปกติ?\nreportUnknownDescription = โปรดไปที่ URL ของลิงก์ที่คุณต้องการรายงานและคลิก “{ reportFile }”\nreportButton = รายงาน\nreportReasonMalware = ไฟล์เหล่านี้มีมัลแวร์หรือเป็นส่วนหนึ่งของการโจมตีแบบฟิชชิ่ง\nreportReasonPii = ไฟล์เหล่านี้มีข้อมูลที่สามารถระบุตัวบุคคลได้เกี่ยวกับฉัน\nreportReasonAbuse = ไฟล์เหล่านี้มีเนื้อหาที่ผิดกฎหมายหรือไม่เหมาะสม\nreportReasonCopyright = หากต้องการรายงานการละเมิดลิขสิทธิ์หรือเครื่องหมายการค้าให้ใช้กระบวนการที่อธิบายไว้ใน <a> หน้านี้ </a>\nreportedTitle = ไฟล์ถูกรายงานแล้ว\nreportedDescription = ขอบคุณ เราได้รับรายงานของคุณเกี่ยวกับไฟล์เหล่านี้แล้ว\n"
  },
  {
    "path": "public/locales/tl/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nsiteFeedback = Feedback\nimportingFile = Importing…\nencryptingFile = Encrypting…\ndecryptingFile = Decrypting…\ndownloadCount =\n    { $num ->\n        [one] 1 pag-download\n       *[other] { $num } na mga pag-download\n    }\ncopiedUrl = Naikopya!\nunlockInputPlaceholder = Password\nunlockButtonLabel = I-unlock\ndownloadButtonLabel = I-download\ndownloadFinish = Kumpleto ang Download\nfileSizeProgress = ({ $partialSize } ng { $totalSize })\nsendYourFilesLink = Subukan ang Firefox Ipadala\nerrorPageHeader = May nagkamali!\nfileTooBig = Ang file na iyon ay masyadong malaki upang mag-upload. Dapat itong mas mababa sa { $size }.\nlinkExpiredAlt = Nag-expire na ang link\nnotSupportedHeader = Ang iyong browser ay hindi suportado.\nnotSupportedLink = Bakit hindi suportado ang aking browser?\nnotSupportedOutdatedDetail = Sa kasamaang palad ang bersyon na ito ng Firefox ay hindi sumusuporta sa teknolohiya ng web na nagpapagana ng Send. Kailangan mong i-update ang iyong browser.\nupdateFirefox = I-update ang Firefox\ndeletePopupCancel = Kanselahin\ndeleteButtonHover = I-delete\nfooterLinkLegal = Legal\nfooterLinkPrivacy = Privacy\nfooterLinkCookies = Mga cookie\npasswordTryAgain = Maling password. Subukan muli.\njavascriptRequired = Nangangailangan ang Send ng JavaScript\nwhyJavascript = Bakit ang Send ay nangangailangan ng JavaScript?\nenableJavascript = Mangyaring paganahin ang JavaScript at subukan muli.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Pinakamataas na haba ng password: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Hindi maitakda ang password na ito\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Firefox send\n-send-short-brand = I-send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Simple, pribadong pagbabahagi ng file\nnotifyUploadEncryptDone = Ang iyong file ay naka-encrypt at handa na i-send\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = mag-e-expire pagkatapos { $downloadCount } o { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minuto\n       *[other] { $num } mga minuto\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 araw\n       *[other] { $num } mga araw\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 linggo\n       *[other] { $num } mga linggo\n    }\nfileCount =\n    { $num ->\n        [one] 1 file\n       *[other] { $num } mga file\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Kabuuang sukat: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Kopyahin ang link upang ibahagi ang iyong file:\ncopyLinkButton = Kopyahin ang link\ndownloadTitle = I-download ang mga file\nexpiredTitle = Ang link na ito ay nag-expire.\ndownloadFirefox = I-download { -firefox }\nlegalTitle = { -send-short-brand } Abiso sa Privacy\nlegalDateStamp = Bersyon 1.0, petsa ng Marso 12, 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }d { $hours }h { $minutes }m\naddFilesButton = Piliin ang mga file na mai-upload\nuploadButton = I-upload\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = I-drag at i-drop ang mga file\naddPassword = Protektahan gamit ang password\nemailPlaceholder = Ipasok ang iyong email\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Mag-sign in upang magpadala ng hanggang sa { $size }\nsignInOnlyButton = Mag sign-in\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Ibahagi ang mga file hanggang sa { $size }\naccountBenefitDownloadCount = Ibahagi ang mga file sa ibang tao\naccountBenefitMoz = Alamin ang tungkol sa iba pang mga serbisyo ng { -mozilla }\nsignOut = Mag sign-out\nokButton = OK\ndownloadingTitle = Pag-download\nnoStreamsWarning = Maaaring hindi mai-decrypt ng browser na ito ang isang file na malaki.\nnoStreamsOptionCopy = Kopyahin ang link upang buksan sa isa pang browser\nnoStreamsOptionFirefox = Subukan ang aming paboritong browser\nnoStreamsOptionDownload = Magpatuloy sa browser na ito\nshareLinkButton = Ibahagi ang link\nlearnMore = Matuto ng higit pa.\n"
  },
  {
    "path": "public/locales/tr/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = İçe aktarılıyor…\nencryptingFile = Şifreleniyor…\ndecryptingFile = Şifre çözülüyor…\ndownloadCount = { $num } indirme\ntimespanHours =\n    { $num ->\n        [one] 1 saat\n       *[other] { $num } saat\n    }\ncopiedUrl = Kopyalandı!\nunlockInputPlaceholder = Parola\nunlockButtonLabel = Kilidi aç\ndownloadButtonLabel = İndir\ndownloadFinish = İndirme tamamlandı\nfileSizeProgress = ({ $partialSize } / { $totalSize })\nsendYourFilesLink = Send’i deneyin\nerrorPageHeader = Bir şeyler ters gitti!\nfileTooBig = Dosyanız çok büyük. En fazla { $size } boyutunda olmalı.\nlinkExpiredAlt = Bağlantı zaman aşımına uğramış\nnotSupportedHeader = Tarayıcınız desteklenmiyor.\nnotSupportedLink = Tarayıcım neden desteklenmiyor?\nnotSupportedOutdatedDetail = Kullandığınız Firefox sürümü Send için gereken web teknolojilerini desteklemiyor. Tarayıcınızı güncellemeniz gerekiyor.\nupdateFirefox = Firefox’u güncelle\ndeletePopupCancel = Vazgeç\ndeleteButtonHover = Sil\nfooterLinkLegal = Yasal Bilgiler\nfooterLinkPrivacy = Gizlilik\nfooterLinkCookies = Çerezler\npasswordTryAgain = Yanlış parola. Yeniden deneyin.\njavascriptRequired = Send için JavaScript gerekir\nwhyJavascript = Send neden JavaScript kullanıyor?\nenableJavascript = Lütfen JavaScript'i etkinleştirip yeniden deneyin.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } sa { $minutes } dk\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } dk\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Maksimum parola uzunluğu: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Parola ayarlanamadı\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Basit ve gizli dosya paylaşımı\nintroDescription = { -send-brand } ile dosyalarınızı uçtan uca şifreleme ve otomatik olarak silinen bir bağlantıyla paylaşın. Böylece özel dosyalarınız güvenle saklanır, bir süre sonra kendi kendine silinir.\nnotifyUploadEncryptDone = Dosyanız şifrelendi ve gönderilmeye hazır\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = { $downloadCount } veya { $timespan } sonra silinecek\ntimespanMinutes =\n    { $num ->\n        [one] 1 dakika\n       *[other] { $num } dakika\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 gün\n       *[other] { $num } gün\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 hafta\n       *[other] { $num } hafta\n    }\nfileCount =\n    { $num ->\n        [one] 1 dosya\n       *[other] { $num } dosya\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Toplam boyut: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Dosyanızı paylaşmak için bağlantıyı kopyalayın:\ncopyLinkButton = Bağlantıyı kopyala\ndownloadTitle = Dosyaları indir\ndownloadDescription = Bu dosya { -send-brand } üzerinden paylaşıldı. Uçtan uca şifreleme ve kendiliğinden silinen bağlantı koruması { -send-brand }’de.\ntrySendDescription = Basit ve güvenli dosya paylaşımı için { -send-brand }’i deneyin.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Bir kerede en fazla 1 dosya yükleyebilirsiniz.\n       *[other] Bir kerede en fazla { $count } dosya yükleyebilirsiniz.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] En fazla 1 arşive izin veriliyor.\n       *[other] En fazla { $count } arşive izin veriliyor.\n    }\nexpiredTitle = Bu bağlantının süresi doldu.\nnotSupportedDescription = { -send-brand } bu tarayıcıyı desteklemiyor. { -send-short-brand } en iyi şekilde { -firefox }’un son sürümüyle ve çoğu tarayıcının güncel sürümüyle çalışır.\ndownloadFirefox = { -firefox }’u indir\nlegalTitle = { -send-short-brand } Gizlilik Bildirimi\nlegalDateStamp = Sürüm 1.0, 12 Mart 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } g { $hours } sa { $minutes } dk\naddFilesButton = Yüklenecek dosyaları seçin\ntrustWarningMessage = Hassas verileri paylaşırken alıcıya güvendiğinizden emin olun.\nuploadButton = Yükle\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Dosyaları sürükleyip bırakarak\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = veya buraya tıklayarak { $size }’ye kadar dosyalarınızı gönderebilirsiniz\naddPassword = Parola koruması ekle\nemailPlaceholder = E-posta adresinizi yazın\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = { $size }’ye kadar dosya göndermek için giriş yapın\nsignInOnlyButton = Giriş yap\naccountBenefitTitle = { -firefox } Hesabı açın veya giriş yapın\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = { $size } boyutlu dosyaları paylaşma\naccountBenefitDownloadCount = Daha fazla kişiyle dosya paylaşma\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Bağlantıları 1 güne kadar aktif tutma\n       *[other] Bağlantıları { $count } güne kadar aktif tutma\n    }\naccountBenefitSync = Paylaştığınız dosyaları başka cihazlardan yönetebilme\naccountBenefitMoz = Diğer { -mozilla } servisleri hakkında bilgi alma\nsignOut = Çıkış yap\nokButton = Tamam\ndownloadingTitle = İndiriliyor\nnoStreamsWarning = Bu tarayıcı bu kadar büyük bir dosyanın şifresini çözemeyebilir.\nnoStreamsOptionCopy = Bağlantıyı başka bir tarayıcıda açmak için kopyala\nnoStreamsOptionFirefox = En sevdiğimiz tarayıcıyı deneyin\nnoStreamsOptionDownload = Bu tarayıcıyla devam edin\ndownloadFirefoxPromo = { -send-short-brand }, yepyeni { -firefox } tarafından sunulmaktadır.\n# the next line after the colon contains a file name\nshareLinkDescription = Dosyanızın bağlantısını paylaşın:\nshareLinkButton = Bağlantıyı paylaş\n# $name is the name of the file\nshareMessage = “{ $name }” dosyasını { -send-brand } ile indirin: basit ve güvenli dosya paylaşımı\ntrailheadPromo = Gizliliğinizi korumanın bir yolu var. Firefox’a katılın.\nlearnMore = Daha fazla bilgi alın.\ndownloadFlagged = Bu bağlantı hizmet koşullarımızı ihlal ettiği için devre dışı bırakıldı.\ndownloadConfirmTitle = Bir şey daha\ndownloadConfirmDescription = Bu dosyayı gönderen kişiye güvendiğinizden emin olun. Dosyanın cihazınıza zarar vermeyeceğini garanti edemeyiz.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Bu dosyayı gönderen kişiye güveniyorum\n       *[other] Bu dosyaları gönderen kişiye güveniyorum\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Bu dosyanın şüpheli olduğunu bildir\n       *[other] Bu dosyaların şüpheli olduğunu bildir\n    }\nreportDescription = Meseleyi anlamamıza yardımcı olun. Bu dosyalardaki sorun nedir?\nreportUnknownDescription = Lütfen rapor etmek istediğiniz bağlantının adresine girip “{ reportFile }” bağlantısına tıklayın.\nreportButton = Şikâyet et\nreportReasonMalware = Bu dosyalar kötü amaçlı yazılım içeriyor veya kimlik avı saldırında kullanılıyor.\nreportReasonPii = Bu dosyalar benim hakkımda kişisel bilgiler içeriyor.\nreportReasonAbuse = Bu dosyalar yasa dışı veya istismar amaçlı içerik içeriyor.\nreportReasonCopyright = Telif hakkı veya ticari marka ihlallerini bildirmek için <a>bu sayfadaki</a> adımları izlemelisiniz.\nreportedTitle = Dosyalar rapor edildi\nreportedDescription = Teşekkür ederiz. Bu dosyalarla ilgili şikâyetinizi aldık.\n"
  },
  {
    "path": "public/locales/trs/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Hìaj a'nïn huan'ānj…\nencryptingFile = Nagi'iaj hùij…\ndecryptingFile = Hìaj nâ'nïn…\ndownloadCount =\n    { $num ->\n        [one] 1 sa nadunin\n       *[other] { $num } nej sa nadunin\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 ôra\n       *[other] { $num } nej ôra\n    }\ncopiedUrl = Ngà gisîj guxunj!\nunlockInputPlaceholder = Da'nga' huìi\nunlockButtonLabel = Na'nïn riñanj\ndownloadButtonLabel = Nadunïnj\ndownloadFinish = Ngà nahui nanïnj\nfileSizeProgress = ({ $partialSize } guendâ { $totalSize })\nsendYourFilesLink = Garahuè dàj 'iaj sun Send\nerrorPageHeader = Huā sa gahui a'nan'!\nfileTooBig = Ûta yachìj hua archibô dan. Da'ui gā li doj ga da' { $size }\nlinkExpiredAlt = Nitāj si ni'ñānj lînk gà'\nnotSupportedHeader = Nitāj si huā hue'ê riña sa nana'uî't.\nnotSupportedLink = Nù huin saj nitāj si huā hue'ê riña sa nana'uí?\nnotSupportedOutdatedDetail = Nu unùkuaj Firefox nan gi'iaj sunj ngà sa 'iaj sun ngà Send. Da'uît nāgi'iaj nakàt riña sa nana'uî't han.\nupdateFirefox = Nagi'iaj nakà Firefox\ndeletePopupCancel = Duyichin'\ndeleteButtonHover = Dure'\nfooterLinkLegal = Nuguan' a'nï'ïn\nfooterLinkPrivacy = Sa hùii\nfooterLinkCookies = Nej kôki\npasswordTryAgain = Sê da'nga' huì dan huin. Ginù huin ñû.\njavascriptRequired = Ni'ñānj Send JavaScript\nwhyJavascript = Nù huin saj ni'ñānj Send JavaScript rà'aj?\nenableJavascript = Gi'iaj sunūj u ga'nïn gi'iaj sun JavaScript nī yakāj da'nga' ñû.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }h { $minutes }m\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Dānaj gā yachìj da'nga huìi: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Na'ue gārayinaj da'nga huìi\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Hìo nī huì ga’ue duyingâ’t archîbo\nintroDescription = { -send-brand } a’nïn duyingâ’t archîbo ngà ‘ngō da’nga’rán hia nī ngà ‘ngō lînk nare’ man‘an. Dànanj nī ‘ngō rïnt ni’in sa duyingâ’t nī si lînk si ginu yitïn riña lînia.\nnotifyUploadEncryptDone = Ngà huā ran si archibôt nī ngà huā yugui da’ ga’nïnjt gan’an\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Narè’ man ne’ rukù { $downloadCount } asi { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 minûtu\n       *[other] { $num } minûtu\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 gui\n       *[other] { $num } gui\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 semâna\n       *[other] { $num } semâna\n    }\nfileCount =\n    { $num ->\n        [one] 1 archîbo\n       *[other] { $num } archîbo\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Dàj nìko yàchi: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Guxūn lînk da' ga'ue duyingâ't archibô:\ncopyLinkButton = Guxûn lînk\ndownloadTitle = Nadunïnj nej archîbo\ndownloadFirefox = Nadunïnj { -firefox }\nlegalTitle = Nuguan huì nikāj { -send-short-brand }\nuploadButton = Nādusîj\naddPassword = Dugumî da’nga’ huìi man\nemailPlaceholder = Gāchrūn si korreot\nsignInOnlyButton = Gāyi'ì sēsiûn\nsignOut = Narun' sesiôn\nokButton = Ga'ue\ndownloadingTitle = Hìaj nadunīnj man\nshareLinkButton = Duguachîn enlâse\nlearnMore = Gāhuin chrūn doj.\n"
  },
  {
    "path": "public/locales/uk/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Імпортуємо...\nencryptingFile = Шифруємо...\ndecryptingFile = Розшифровуємо...\ndownloadCount =\n    { $num ->\n        [one] 1 завантаження\n        [few] { $num } завантаження\n       *[other] { $num } завантажень\n    }\ntimespanHours =\n    { $num ->\n        [one] 1 година\n        [few] { $num } години\n       *[other] { $num } годин\n    }\ncopiedUrl = Скопійовано!\nunlockInputPlaceholder = Пароль\nunlockButtonLabel = Розблокувати\ndownloadButtonLabel = Завантажити\ndownloadFinish = Завантаження завершено\nfileSizeProgress = ({ $partialSize } з { $totalSize })\nsendYourFilesLink = Спробуйте Send\nerrorPageHeader = Щось пішло не так!\nfileTooBig = Цей файл завеликий для вивантаження. Він має бути меншим за { $size }.\nlinkExpiredAlt = Час дії посилання минув\nnotSupportedHeader = Ваш браузер не підтримується.\nnotSupportedLink = Чому мій браузер не підтримується?\nnotSupportedOutdatedDetail = На жаль, ця версія Firefox не підтримує веб-технологію, завдяки якій працює Send. Вам потрібно оновити свій браузер.\nupdateFirefox = Оновити Firefox\ndeletePopupCancel = Скасувати\ndeleteButtonHover = Видалити\nfooterLinkLegal = Права\nfooterLinkPrivacy = Приватність\nfooterLinkCookies = Куки\npasswordTryAgain = Невірний пароль. Спробуйте знову.\njavascriptRequired = Send потребує JavaScript\nwhyJavascript = Чому для Send потрібен JavaScript?\nenableJavascript = Будь ласка, увімкніть JavaScript та спробуйте знову.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } год. { $minutes } хв.\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } хв.\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Найбільша довжина паролю: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Неможливо встановити цей пароль\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Простий, приватний обмін файлами\nintroDescription = { -send-brand } дозволяє обмінюватися файлами з використанням наскрізного шифрування та посиланнями з обмеженим терміном дії. Отже, ви можете бути певними, що ваші дані зберігаються приватно і не залишаться в мережі назавжди.\nnotifyUploadEncryptDone = Ваш файл зашифрований і готовий до надсилання\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Термін зберігання завершується після { $downloadCount } або { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] 1 хвилина\n        [few] { $num } хвилини\n       *[other] { $num } хвилин\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 день\n        [few] { $num } дні\n       *[other] { $num } днів\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 тиждень\n        [few] { $num } тижні\n       *[other] { $num } тижнів\n    }\nfileCount =\n    { $num ->\n        [one] 1 файл\n        [few] { $num } файли\n       *[other] { $num } файлів\n    }\n# byte abbreviation\nbytes = Б\n# kibibyte abbreviation\nkb = КБ\n# mebibyte abbreviation\nmb = МБ\n# gibibyte abbreviation\ngb = ГБ\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Загальний розмір: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Скопіюйте посилання для спільного доступу:\ncopyLinkButton = Копіювати посилання\ndownloadTitle = Завантажити файли\ndownloadDescription = Цей файл було надіслано через { -send-brand } з використанням наскрізного шифрування і посиланням, що має обмежений термін дії.\ntrySendDescription = Спробуйте { -send-brand } для простого, захищеного обміну файлами.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] Лише 1 файл можна вивантажити за один раз.\n        [few] Лише { $count } файли можна вивантажити за один раз.\n       *[other] Лише { $count } файлів можна вивантажити за один раз.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] Дозволяється лише 1 архів.\n        [few] Дозволяється лише { $count } архіви.\n       *[other] Дозволяється лише { $count } архівів.\n    }\nexpiredTitle = Термін дії цього посилання завершився.\nnotSupportedDescription = { -send-brand } не працюватиме з цим браузером. { -send-short-brand } найкраще працює з найновішою версією { -firefox }, а також з більшістю інших браузерів.\ndownloadFirefox = Завантажити { -firefox }\nlegalTitle = Повідомлення про приватність { -send-short-brand }\nlegalDateStamp = Версія 1.0 від 12 березня 2019 року\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }д { $hours }г { $minutes }хв\naddFilesButton = Оберіть файли для вивантаження\ntrustWarningMessage = Переконайтеся, що довіряєте одержувачу коли ділитеся вразливими даними.\nuploadButton = Вивантажити\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Перетягуйте файли\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = або натисніть, щоб надіслати до { $size }\naddPassword = Захист паролем\nemailPlaceholder = Введіть свою електронну пошту\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Увійдіть, щоб надсилати файли розміром до { $size }\nsignInOnlyButton = Увійти\naccountBenefitTitle = Створіть обліковий запис { -firefox } або увійдіть\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Обмінюйтесь файлами розміром до { $size }\naccountBenefitDownloadCount = Обмінюйтесь файлами з більшою кількістю людей\naccountBenefitTimeLimit =\n    { $count ->\n        [one] Термін дії посилання 1 день\n        [few] Термін дії посилання { $count } дні\n       *[many] Термін дії посилання { $count } днів\n    }\naccountBenefitSync = Керуйте спільними файлами з буль-якого пристрою\naccountBenefitMoz = Дізнайтеся про інші сервіси { -mozilla }\nsignOut = Вийти\nokButton = Гаразд\ndownloadingTitle = Завантаження\nnoStreamsWarning = Цьому браузеру може не вдатися розшифрувати такий великий файл.\nnoStreamsOptionCopy = Скопіюйте посилання, щоб відкрити його в іншому браузері\nnoStreamsOptionFirefox = Спробуйте наш улюблений браузер\nnoStreamsOptionDownload = Продовжити в цьому браузері\ndownloadFirefoxPromo = { -send-short-brand } доступний для вас в цілком новому { -firefox }.\n# the next line after the colon contains a file name\nshareLinkDescription = Надішліть посилання на свій файл:\nshareLinkButton = Поділитись посиланням\n# $name is the name of the file\nshareMessage = Завантажте “{ $name }” з { -send-brand }: простий та безпечний обмін файлами\ntrailheadPromo = Існує спосіб захистити вашу приватність. Приєднуйтесь до Firefox.\nlearnMore = Докладніше.\ndownloadFlagged = Це посилання вимкнено через порушення умов надання послуг.\ndownloadConfirmTitle = Ще порада\ndownloadConfirmDescription = Переконайтеся, що довіряєте відправнику цього файлу, оскільки ми не можемо перевірити, чи він не зашкодить вашому пристрою.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] Я довіряю відправнику цього файлу\n        [few] Я довіряю відправнику цих файлів\n       *[many] Я довіряю відправнику цих файлів\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] Повідомити, що цей файл є підозрілим\n        [few] Повідомити, що ці файли є підозрілими\n       *[many] Повідомити, що ці файли є підозрілими\n    }\nreportDescription = Допоможіть нам зрозуміти, що відбувається. Що, на вашу думку, з цими файлами не так?\nreportUnknownDescription = Перейдіть до url-адреси посилання, про яке хочете надіслати звіт, та натисніть “{ reportFile }”.\nreportButton = Надіслати звіт\nreportReasonMalware = Ці файли містять зловмисне програмне забезпечення або є частиною фішинг-атаки.\nreportReasonPii = Ці файли містять мої особисті дані.\nreportReasonAbuse = Ці файли містять незаконний або образливий вміст.\nreportReasonCopyright = Щоб повідомити про порушення авторських прав або торговельних марок, скористайтеся настановами з <a>цієї сторінки</a>.\nreportedTitle = Звіт про файли надіслано\nreportedDescription = Дякуємо. Ми отримали ваш звіт про ці файли.\n"
  },
  {
    "path": "public/locales/vi/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = Đang nhập...\nencryptingFile = Đang mã hóa...\ndecryptingFile = Đang giải mã...\ndownloadCount =\n    { $num ->\n       *[other] { $num } lượt tải\n    }\ntimespanHours =\n    { $num ->\n       *[other] { $num } giờ\n    }\ncopiedUrl = Đã sao chép!\nunlockInputPlaceholder = Mật khẩu\nunlockButtonLabel = Mở khóa\ndownloadButtonLabel = Tải xuống\ndownloadFinish = Tải xuống hoàn tất\nfileSizeProgress = ({ $partialSize } trong { $totalSize })\nsendYourFilesLink = Dùng thử Send\nerrorPageHeader = Có gì đó không ổn!\nfileTooBig = Tập tin này quá lớn để tải lên. Kích thước tập tin phải nhỏ hơn { $size }.\nlinkExpiredAlt = Liên kết đã hết hạn\nnotSupportedHeader = Trình duyệt của bạn không được hỗ trợ.\nnotSupportedLink = Tại sao trình duyệt của tôi không được hỗ trợ?\nnotSupportedOutdatedDetail = Thật không may là phiên bản Firefox này không hỗ trợ công nghệ được sử dụng trong Send. Bạn cần cập nhật trình duyệt của bạn.\nupdateFirefox = Cập nhật Firefox\ndeletePopupCancel = Hủy bỏ\ndeleteButtonHover = Xóa\nfooterLinkLegal = Pháp lý\nfooterLinkPrivacy = Quyền riêng tư\nfooterLinkCookies = Cookie\npasswordTryAgain = Sai mật khẩu. Vui lòng thử lại.\njavascriptRequired = Send cần JavaScript\nwhyJavascript = Tại sao Send cần JavaScript?\nenableJavascript = Vui lòng kích hoạt JavaScript và thử lại.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } giờ { $minutes } phút\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } phút\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Độ dài mật khẩu tối đa: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = Không thể đặt mật khẩu này\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = Chia sẻ tập tin đơn giản, riêng tư\nintroDescription = { -send-brand } cho phép bạn chia sẻ các tập tin với mã hóa đầu cuối và một liên kết tự động hết hạn. Vì vậy, bạn có thể giữ những gì bạn chia sẻ riêng tư và đảm bảo dữ liệu của bạn không trực tuyến vĩnh viễn.\nnotifyUploadEncryptDone = Tập tin của bạn được mã hóa và sẵn sàng để gửi\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = Hết hạn sau { $downloadCount } hoặc { $timespan }\ntimespanMinutes =\n    { $num ->\n       *[other] { $num } phút\n    }\ntimespanDays =\n    { $num ->\n       *[other] { $num } ngày\n    }\ntimespanWeeks =\n    { $num ->\n       *[other] { $num } tuần\n    }\nfileCount =\n    { $num ->\n       *[other] { $num } tập tin\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = Tổng kích thước: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = Sao chép liên kết để chia sẻ tập tin của bạn:\ncopyLinkButton = Sao chép liên kết\ndownloadTitle = Tải xuống tập tin\ndownloadDescription = Tập tin này đã được chia sẻ qua { -send-brand } với mã hóa đầu cuối và liên kết tự động hết hạn.\ntrySendDescription = Hãy thử { -send-brand } để chia sẻ tập tin đơn giản, an toàn.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n       *[other] Chỉ { $count } tập tin có thể tải lên mỗi lần.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n       *[other] Chỉ cho phép { $count } lưu trữ.\n    }\nexpiredTitle = Liên kết này đã hết hạn.\nnotSupportedDescription = { -send-brand } sẽ không hoạt động với trình duyệt này. { -send-short-brand } hoạt động tốt nhất với phiên bản { -firefox } mới nhất và sẽ hoạt động với phiên bản hiện tại của hầu hết các trình duyệt.\ndownloadFirefox = Tải xuống { -firefox }\nlegalTitle = Thông báo bảo mật { -send-short-brand }\nlegalDateStamp = Phiên bản 1.0, ngày 12 tháng 3 năm 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } ngày { $hours } giờ { $minutes } phút\naddFilesButton = Chọn tập tin để tải lên\ntrustWarningMessage = Hãy chắc chắn rằng bạn tin tưởng người nhận khi chia sẻ dữ liệu nhạy cảm.\nuploadButton = Tải lên\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = Kéo và thả tập tin\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = hoặc nhấp để gửi tối đa { $size }\naddPassword = Bảo vệ bằng mật khẩu\nemailPlaceholder = Nhập email của bạn\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = Đăng nhập để gửi tối đa { $size }\nsignInOnlyButton = Đăng nhập\naccountBenefitTitle = Tạo tài khoản { -firefox } hoặc đăng nhập\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = Chia sẻ tập tin lên tới { $size }\naccountBenefitDownloadCount = Chia sẻ tập tin với nhiều người hơn\naccountBenefitTimeLimit =\n    { $count ->\n       *[other] Giữ liên kết hoạt động tối đa { $count } ngày\n    }\naccountBenefitSync = Quản lý tập tin được chia sẻ từ mọi thiết bị\naccountBenefitMoz = Tìm hiểu về các dịch vụ khác của { -mozilla }\nsignOut = Đăng xuất\nokButton = OK\ndownloadingTitle = Đang tải xuống\nnoStreamsWarning = Trình duyệt này có khả năng không thể giải mã một tập tin lớn này.\nnoStreamsOptionCopy = Sao chép liên kết để mở trong một trình duyệt khác\nnoStreamsOptionFirefox = Hãy dùng thử trình duyệt yêu thích của chúng tôi\nnoStreamsOptionDownload = Tiếp tục với trình duyệt này\ndownloadFirefoxPromo = { -send-short-brand } được mang đến cho bạn bởi { -firefox } hoàn toàn mới.\n# the next line after the colon contains a file name\nshareLinkDescription = Chia sẻ liên kết đến tập tin của bạn:\nshareLinkButton = Chia sẻ liên kết\n# $name is the name of the file\nshareMessage = Tải xuống “{ $name }“ với { -send-brand }: chia sẻ tập tin đơn giản, an toàn\ntrailheadPromo = Đây là một cách để bảo vệ sự riêng tư của bạn. Tham gia Firefox.\nlearnMore = Tìm hiểu thêm.\ndownloadFlagged = Liên kết này đã bị vô hiệu hóa do vi phạm các điều khoản dịch vụ.\ndownloadConfirmTitle = Một điều nữa\ndownloadConfirmDescription = Hãy chắc chắn rằng bạn tin tưởng người đã gửi cho bạn tập tin này vì chúng tôi không thể xác minh rằng nó sẽ không gây hại cho thiết bị của bạn.\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n       *[other] Tôi tin tưởng người đã gửi những tập tin này\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n       *[other] Báo cáo các tập tin này là đáng ngờ\n    }\nreportDescription = Hãy giúp chúng tôi hiểu những gì đang diễn ra. Bạn nghĩ gì có gì không đúng với những tập tin này?\nreportUnknownDescription = Vui lòng truy cập url của liên kết bạn muốn báo cáo và nhấp vào “{ reportFile }”.\nreportButton = Báo cáo\nreportReasonMalware = Những tập tin này chứa phần mềm độc hại hoặc là một phần của cuộc tấn công lừa đảo.\nreportReasonPii = Những tập tin này chứa thông tin cá nhân về tôi.\nreportReasonAbuse = Những tập tin này chứa nội dung bất hợp pháp hoặc lạm dụng.\nreportReasonCopyright = Để báo cáo vi phạm bản quyền hoặc nhãn hiệu, hãy sử dụng quy trình được mô tả tại <a>trang này</a>.\nreportedTitle = Đã báo cáo tập tin\nreportedDescription = Cảm ơn bạn. Chúng tôi đã nhận được báo cáo của bạn về các tập tin này.\n"
  },
  {
    "path": "public/locales/yo/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send je oruko ile-ise kan, kò sì ye ki a so di ibile.\nimportingFile = akowọle…\nencryptingFile = Fifi ọrọ ṣiṣẹ…\ndecryptingFile = Ti nkọ nkan…\ndownloadCount =\n    { $num ->\n        [one] ìsíwá kan…\n       *[other] ọ̀pọ̀ ìsíwá…\n    }\ntimespanHours =\n    { $num ->\n        [one] Wákàtí kan\n       *[other] Ọ̀pọ wákàtí\n    }\ncopiedUrl = dakọ\nunlockInputPlaceholder =\n    aṣínà\n    ọ̀rọ̀-aṣínà\n    ọ̀rọ̀-agbaniwọlé\nunlockButtonLabel = ṣí\ndownloadButtonLabel = Ìgbasílẹ̀\ndownloadFinish =\n    Ìsíwá parí\n    Ìgbasílẹ̀ parí\nsendYourFilesLink =\n    Gbìyànjúu Send\n    Gbìyànjú lo Send\n    Dán Send wò\nerrorPageHeader = Nnkan o lo daadaa!\nfileTooBig =\n    Fáìlì yìí tóbijù láti gbà sókè. Ó ní láti kéré sí { $size }\n    Fáìlì yìí tóbijù láti gbà sókè. Ó ní láti kéré ju { $size } lọ\nlinkExpiredAlt =\n    Ojú-òpó ti kásẹ̀ \n    Ojú-òpó ti pajújé \n    Ọ̀nà-òpó ti kásẹ̀ \n    Ọ̀nà-òpó ti pajújé\nnotSupportedHeader =\n    Èrọ-ìfarakọ́ra rẹ ò ní ìbátan\n    Ojú-òpó ìfarakọ́ra rẹ ò ní ìbátan\nnotSupportedLink =\n    Kí ló ṣe tí ẹ̀rọ-ìfarakọ́ra mi ò ní ìbátan?\n    Kí ló ṣe tí ẹ̀rọ-aṣàwárí mi ò ní ìbátan?\n    Kí nìdí tí ẹ̀rọ-ìfarakọ́ra mi ò ní ìbátan?\n    Kí nìdí tí ẹ̀rọ-aṣàwárí mi ò ní ìbátan?\nnotSupportedOutdatedDetail = Ó ṣe, wípé ẹ̀dà Firefox yí ò ní àtìlẹyìn ẹ̀rọ-alátagbà tí ó ń mú Send ṣiṣẹ́. O ní láti ṣe àgbéga èdà ẹ̀rọ-aṣàwárí rẹ kó bágbàmu.\nupdateFirefox = Mú Firefox bágbàmu\ndeletePopupCancel =\n    Nù kúrò\n    Parẹ́\ndeleteButtonHover =\n    Mú kúrò\n    Parẹ́\nfooterLinkLegal =\n    b’ófin mu\n    n’ílànà òfin\nfooterLinkPrivacy =\n    Ibi ìkọ̀kọ̀\n    Ibi ìpamọ́\nfooterLinkCookies =\n    Cookie\n    Àmì-ẹ̀rọ aránṣẹ́-jíṣẹ́\npasswordTryAgain =\n    Ọ̀rọ̀-aṣínà kò tọ́. Gbìyànjú síi\n    Ọ̀rọ̀-aṣíde kò tọ́. Gbìyànjú síi\njavascriptRequired = Send nílòo JavaScript\nwhyJavascript =\n    Kí nìdí tí Firefox fi nílòo JavaScript?\n    Kí nìdí tí Firefox ṣe nílòo JavaScript?\nenableJavascript =\n    Jọ̀wọ́ tán JavaScript sílẹ̀ kí o sì gbìyànjú si.\n    Jọ̀wọ́ ṣí JavaScript sílẹ̀ kí o sì gbìyànjú si.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes =\n    { $hours }w { $minutes }i\n    { $hours }wákàtí { $minutes }iṣẹ́jú\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }i\n# A short status message shown when the user enters a long password\nmaxPasswordLength = Ìdíwọ̀n ọ̀rọ̀-aṣínà: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError =\n    Ọ̀rọ̀-aṣínà yí kò ṣeé gbé kalẹ̀\n    Ọ̀rọ̀-aṣínà yí kò leè fẹsẹ̀ múlẹ̀\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand =\n    Fi ránṣẹ́\n    Firánṣẹ́\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle =\n    Fáìlì pípín níkọ̀kọ̀ tó dẹrùn\n    Fáìlì pípín níkọ̀kọ̀ onírọ̀rùn\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = Kilobaiti\n# mebibyte abbreviation\nmb = Megabaiti\n# gibibyte abbreviation\ngb = Gigabaiti\ndownloadTitle = Se igabisile faili\naddFilesButton = E yan awon faili lati gbasoke\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = E mu awon faili ki ede ju si bi\nemailPlaceholder = E fi imeli si\naccountBenefitDownloadCount = E pin faili pelu awon eyan si\nokButton = O DA\ndownloadingTitle = N se igabsile\nnoStreamsOptionFirefox = E gbiyanju asawakiri to je ayanfe wa\nnoStreamsOptionDownload = Tesiwaju pelu aṣàwákiri yi\ntrailheadPromo = Ona wa lati dabobo ipamo re. Darapo mo Firefox\nlearnMore = Keeko si\n"
  },
  {
    "path": "public/locales/yua/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }m\n\n## Send version 2 strings\n\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n"
  },
  {
    "path": "public/locales/zgh/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = ⴼⴰⵢⵔⴼⵓⴽⵙ ⵙⵉⵏⴷ\nsiteFeedback = ⵜⴰⵙⴷⵎⵉⵔⵜ\nimportingFile = ⴰⵙⴽⵛⵎ...\nencryptingFile = ⴰⵙⵙⵏⵜⵍ...\ndecryptingFile = ⵜⵓⴽⴽⵙⴰ ⵏ ⵓⵙⵙⵏⵜⵍ...\ndownloadCount =\n    { $num ->\n        [one] { $num } ⵜⴰⴳⴰⵎⵜ\n       *[other] { $num } ⵜⴰⴳⴰⵎⵉⵏ\n    }\ntimespanHours =\n    { $num ->\n        [one] { $num } ⵜⵙⵔⴰⴳⵜ\n       *[other] { $num } ⵜⵙⵔⴰⴳⵉⵏ\n    }\ncopiedUrl = ⵉⵏⵖⵍ!\nunlockInputPlaceholder = ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ\nunlockButtonLabel = ⴽⴽⵙ ⴰⵔⴳⴰⵍ\ndownloadButtonLabel = ⴰⴳⵎ\ndownloadFinish = ⵉⵎⴷⴰ ⵡⴰⴳⴰⵎ\nfileSizeProgress = ({ $partialSize } ⵙⴳ { $totalSize })\nsendYourFilesLink = ⴰⵔⵎ ⴼⴰⵢⵔⴼⵓⴽⵙ ⵙⵉⵏⴷ\nerrorPageHeader = ⵜⵙⴰⵔ ⴽⵔⴰ ⵏ ⵜⵣⴳⴰⵍⵜ!\nfileTooBig = ⵉⵎⵇⵇⵓⵔ ⴱⴰⵀⵔⴰ ⵓⴼⴰⵢⵍⵓ ⴰ ⵖⴼ ⵓⵙⵙⴽⵜⵔ. ⵉⵅⵚⵚⴰ ⵜ ⴰⴷ ⵢⵉⵍⵉ ⴷⴷⴰⵡ ⵏ { $size }\nlinkExpiredAlt = ⵉⵎⵎⵓⵜ ⵓⵙⵖⵏ\nnotSupportedHeader = ⵓⵔ ⵉⵜⵜⵡⴰⵏⵏⴰⵍ ⵓⵎⵙⵙⴰⵔⴰ ⵏⵏⵓⵏ.\nnotSupportedLink = ⵎⴰⵖⴼ ⵓⵔ ⵉⵜⵜⵡⴰⵏⵏⴰⵍ ⵓⵎⵙⵙⴰⵔⴰ ⵉⵏⵓ?\nnotSupportedOutdatedDetail = ⵙ ⵜⵎⴳⵕⵥⴰ, ⵜⴰⵍⵇⵇⵎⵜ ⴰ ⵏ ⴼⴰⵢⵔⴼⵓⴽⵙ ⵓⵔ ⴷⴰ ⵜⴻⵜⵜⵏⴰⵍ ⵜⴰⵜⵉⴽⵏⵓⵍⵓⵊⵉⵜ ⵏ ⵓⵡⵉⴱ ⵏⵏⴰ ⵙ ⵉⵙⵡⵓⵔⵓⵢ ⴼⴰⵢⵔⴼⵓⴽⵙ ⵙⵉⵏⴷ. ⵔⴰⴷ ⵜⴰⵙⵔⵎ ⴰⴷ ⵜⵙⴷⵖⵉⵎ ⴰⵎⵙⵙⴰⵔⴰ ⵏⵏⵓⵏ.\nupdateFirefox = ⵙⴷⵖⵉ ⴼⴰⵢⵔⴼⵓⴽⵙ\ndeletePopupCancel = ⵙⵔ\ndeleteButtonHover = ⴽⴽⵙ\nfooterLinkLegal = ⵓⵙⴹⵉⴼ\nfooterLinkPrivacy = ⵜⵉⵏⵏⵓⵜⵍⴰ\nfooterLinkCookies = ⵉⴽⵓⴽⵉⵜⵏ\npasswordTryAgain = ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ ⵓⵔ ⵢⵓⵖⵉⴷⵏ. ⴰⵔⵎ ⴷⴰⵖ.\njavascriptRequired = ⴷⴰ ⵉⵜⵜⴰⵙⵔ ⴼⴰⵢⵔⴼⵓⴽⵙ ⵙⵉⵏⴷ ⵊⴰⴼⴰⵙⴽⵔⵉⴱⵜ\nwhyJavascript = ⵎⴰⵖⴼ ⴷⴰ ⵉⵜⵜⴰⵙⵔ ⴼⴰⵢⵔⴼⵓⴽⵙ ⵙⵉⵏⴷ ⵊⴰⴼⴰⵙⴽⵔⵉⴱⵜ?\nenableJavascript = ⵎⴽ ⵜⵓⴼⴰⵎ, ⵙⵏⵓⵛⵛⴳⴰⵜ ⵊⴰⴼⴰⵙⴽⵔⵉⴱⵜ, ⵜⴰⵔⵎⵎ ⴷⴰⵖ.\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours }ⵙⵔⴳ { $minutes }ⵙⴷ\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes }ⵙⴷ\n# A short status message shown when the user enters a long password\nmaxPasswordLength = ⵜⵉⵖⵣⵉ ⵜⴰⵎⵓⵣⵣⵓⵔⵜ ⵏ ⵜⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = ⵓⵔ ⵜⵣⵎⵉⵔ ⵜⴳⵓⵔⵉ ⴰ ⵏ ⵓⵣⵔⴰⵢ ⴰⴷ ⵜⴻⵜⵜⵓⵙⵖⵍ\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = ⴼⴰⵢⵔⴼⵓⴽⵙ ⵙⵉⵏⴷ\n-send-short-brand = ⵙⵉⵏⴷ\n-firefox = ⴼⴰⵢⵔⴼⵓⴽⵙ\n-mozilla = ⵎⵓⵣⵉⵍⴰ\nintroTitle = ⴰⴱⵟⵟⵓ ⴰⴼⵔⴰⵔ ⴷ ⵡⵓⵙⵍⵉⴳ ⵏ ⵉⴼⵓⵢⵍⴰ\nintroDescription = ⴷⴰ ⴽⵯⵏ ⵉⵜⵜⴰⵊⵊⴰ { -send-brand } ⴰⴷ ⵜⴱⴹⵓⵎ ⵉⴼⵓⵢⵍⴰ ⵙ ⵓⵙⵙⵏⵜⵍ ⵙⴳ ⵜⴰⵎⴰ ⴰⵔ ⵜⴰⵎⴰ ⴷ ⵢⴰⵏ ⵓⵙⵖⵏ ⵏⵏⴰ ⵉⵜⵜⵎⵎⵜⴰⵜⵏ ⵙ ⵓⵡⵔⵎⴰⵏ. ⵙ ⵓⵢⴰ, ⵜⵣⵎⵔⵎ ⴰⴷ ⵜⴰⵊⵊⵎ ⴰⵢⵏⵏⴰ ⵜⴱⵟⵟⵓⵎ ⴷ ⵓⵙⵍⵉⴳ, ⵜⵙⵙⵉⵖⵥⵉⵏⵎ ⵎⴰⵙ ⵓⵔ ⵔⴰⴷ ⴰⴱⴷⴰ ⵉⵇⵇⵉⵎ ⵡⴰⵏⵏⴰⴷ ⵏⵏⵓⵏ ⴳ ⵉⴼⵉⵍⵉ.\nnotifyUploadEncryptDone = ⵉⵏⵜⵍ ⵓⴼⴰⵢⵍⵓ ⵏⵏⵓⵏ, ⵉⵃⵢⵢⵍ ⵉ ⵡⴰⵣⴰⵏ\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = ⴰⴷ ⵉⵎⵎⵜ ⴷⴼⴼⵉⵔ { $downloadCount } ⵏⵉⵖ ⴷ { $timespan }\ntimespanMinutes =\n    { $num ->\n        [one] { $num } ⵜⵓⵙⴷⵉⴷⵜ\n       *[other] { $num } ⵜⵓⵙⴷⵉⴷⵉⵏ\n    }\ntimespanDays =\n    { $num ->\n        [one] { $num } ⵡⴰⵙⵙ\n       *[other] { $num } ⵡⵓⵙⵙⴰⵏ\n    }\ntimespanWeeks =\n    { $num ->\n        [one] { $num } ⵉⵎⴰⵍⴰⵙⵙ\n       *[other] { $num } ⵉⵎⴰⵍⴰⵙⵙⵏ\n    }\nfileCount =\n    { $num ->\n        [one] { $num } ⵓⴼⴰⵢⵍⵓ\n       *[other] { $num } ⵉⴼⵓⵢⵍⴰ\n    }\n# byte abbreviation\nbytes = ⵜ\n# kibibyte abbreviation\nkb = ⴽⵜ\n# mebibyte abbreviation\nmb = ⵎⵜ\n# gibibyte abbreviation\ngb = ⵊⵜ\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = ⵜⵉⴷⴷⵉ ⵉⵎⵎⵓⵜⵜⵔⵏ: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = ⵙⵙⵏⵖⵍⴰⵜ ⴰⵙⵖⵏ ⴰⴼⴰⴷ ⴰⴷ ⵜⴱⴹⵓⵎ ⴰⴼⴰⵢⵍⵓ ⵏⵏⵓⵏ:\ncopyLinkButton = ⵙⵙⵏⵖⵍ ⴰⵙⵖⵏ\ndownloadTitle = ⴰⴳⵎ ⵉⴼⵓⵢⵍⴰ\ndownloadDescription = ⵉⵜⵜⵓⴱⴹⴰ ⵓⴼⴰⵢⵍⵓ ⴰ ⵙⴳ { -send-brand } ⵙ ⵓⵙⵙⵏⵜⵍ ⵙⴳ ⵜⴰⵎⴰ ⴰⵔ ⵜⴰⵎⴰ ⴷ ⵢⴰⵏ ⵓⵙⵖⵏ ⵏⵏⴰ ⵉⵜⵜⵎⵎⵜⴰⵜⵏ ⵙ ⵓⵡⵔⵎⴰⵏ.\ntrySendDescription = ⴰⵔⵎⴰⵜ { -send-brand } ⵉ ⵓⴱⵟⵟⵓ ⴰⴼⵔⴰⵔ ⴷ ⵡⵓⴼⵔⵉⴳ ⵏ ⵉⴼⵓⵢⵍⴰ.\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] ⵖⴰⵙ { $count } ⵓⴼⴰⵢⵍⵓ ⴰⵢ ⵉⵣⵎⵔⵏ ⴰⴷ ⵉⴽⵜⵔ ⴳ ⵢⴰⵜ ⵜⵉⴽⴽⵍⵜ.\n       *[other] ⵖⴰⵙ { $count } ⵉⴼⵓⵢⵍⴰ ⴰⵢ ⵉⵣⵎⵔⵏ ⴰⴷ ⴽⵜⵔⵏ ⴳ ⵢⴰⵜ ⵜⵉⴽⴽⵍⵜ.\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n        [one] ⵖⴰⵙ { $count } ⵜⵎⵃⴹⵉⵜ ⴰⵢ ⵉⵔⵔⴳⵏ.\n       *[other] ⵖⴰⵙ { $count } ⵜⵎⵃⴹⴰⵢ ⴰⵢ ⵉⵔⵔⴳⵏ.\n    }\nexpiredTitle = ⵉⵎⵎⵓⵜ ⵓⵙⵖⵏ ⴰ.\nnotSupportedDescription = ⵓⵔ ⵔⴰⴷ ⵉⵙⵡⵓⵔⵉ { -send-brand } ⵙ ⵓⵎⵙⵙⴰⵔⴰ ⴰ. ⴷⴰ ⵉⵙⵡⵓⵔⵓⵢ { -send-short-brand } ⵎⵍⵉⵃ ⵙ ⵜⵍⵇⵇⵎⵜ ⵜⴰⵎⴳⴳⴰⵔⵓⵜ ⵏ { -firefox }, ⴷ ⵔⴰⴷ ⵉⵙⵡⵓⵔⵉ ⵙ ⵜⵍⵇⵇⵎⵜ ⵜⴰⵎⵉⵔⴰⵏⵜ ⵏ ⵓⵎⴰⵜⴰ ⵏ ⵉⵎⵙⵙⴰⵔⴰⵜⵏ.\ndownloadFirefox = ⴰⴳⵎ { -firefox }\nlegalTitle = ⵜⵓⵙⵎⵉⵔⵜ ⵏ ⵜⵉⵏⵏⵓⵜⵍⴰ ⵏ { -send-short-brand }\nlegalDateStamp = ⵜⴰⵍⵇⵇⵎⵜ 1.0, ⵜⵉⵏ 12 ⵎⴰⵕⵚ 2019\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days }ⵙ { $hours }ⵙⵔⴳ { $minutes }ⵙⴷ\naddFilesButton = ⵙⵜⵢ ⵉⴼⵓⵢⵍⴰ ⵉ ⵓⵙⵙⴽⵜⵔ\nuploadButton = ⵙⵙⴽⵜⵔ\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = ⵙⵓⵛⵛⴹⴰⵜ, ⵜⵙⵔⵙⵎ ⵉⴼⵓⵢⵍⴰ\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = ⵏⵉⵖ ⵜⴽⵍⵉⴽⵉⵎ ⴰⴼⴰⴷ ⴰⴷ ⵜⴰⵣⵏⵎ ⴰⵔ { $size }\naddPassword = ⴰⵔⵢ ⵙ ⵜⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ\nemailPlaceholder = ⵙⵙⴽⵛⵎⴰⵜ ⵉⵎⴰⵢⵍ ⵏⵏⵓⵏ\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = ⴽⵛⵎ ⴰⴼⴰⴷ ⴰⴷ ⵜⴰⵣⵏⴷ ⴰⵔ { $size }\nsignInOnlyButton = ⴽⵛⵎ\naccountBenefitTitle = ⵙⵏⴼⵍⵓⵍ ⴰⵎⵉⴹⴰⵏ ⵏ { -firefox } ⵏⵉⵖ ⵜⵣⵎⵎⴻⵎⴷ\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = ⴱⴹⵓ ⵉⴼⵓⵢⵍⴰ ⴰⵔ { $size }\naccountBenefitDownloadCount = ⴱⴹⵓ ⵉⴼⵓⵢⵍⴰ ⴰⴽⴷ ⵡⵓⴳⴳⴰⵔ ⵏ ⵎⴷⴷⵏ\naccountBenefitTimeLimit =\n    { $count ->\n        [one] ⴰⵊⵊⴰⵜ ⵉⵙⵖⴰⵏ ⴰⴷ ⵜⵜⵏⵓⵛⵛⵓⴳⵏ ⴰⵔ { $count } ⵡⴰⵙⵙ\n       *[other] ⴰⵊⵊⴰⵜ ⵉⵙⵖⴰⵏ ⴰⴷ ⵜⵜⵏⵓⵛⵛⵓⴳⵏ ⴰⵔ { $count } ⵡⵓⵙⵙⴰⵏ\n    }\naccountBenefitSync = ⵙⵡⵓⴷⴷⵡⴰⵜ ⵉⴼⵓⵢⵍⴰ ⵜⵜⵓⴱⴹⴰⵏⵉⵏ ⵙⴳ ⴽⵓ ⴰⵍⵍⴰⵍ\naccountBenefitMoz = ⵍⵎⴷ ⵖⴼ ⵜⵏⵓⴼⴰ ⵢⴰⴹⵏⵉⵏ ⵏ { -mozilla }\nsignOut = ⴼⴼⵖ\nokButton = ⵡⴰⵅⵅⴰ\ndownloadingTitle = ⴰⴳⴰⵎ\nnoStreamsWarning = ⵉⵣⵎⵔ ⵓⵎⵙⵙⴰⵔⴰ ⴰ ⴰⴷ ⵓⵔ ⵉⵖⴰⵢ ⴰⴷ ⵉⴽⴽⵙ ⴰⵙⵙⵏⵜⵍ ⵉ ⵢⴰⵏ ⵓⴼⴰⵢⵍⵓ ⵉⵎⵇⵇⵓⵔⵏ ⵙ ⵡⴰⵏⵛⵜ ⴰ.\nnoStreamsOptionCopy = ⵙⵙⵏⵖⵍⴰⵜ ⴰⵙⵖⵏ ⴰⴼⴰⴷ ⴰⴷ ⵜ ⵜⵕⵥⵎⵎ ⴳ ⴽⵔⴰ ⵏ ⵓⵎⵙⵙⴰⵔⴰ ⵢⴰⴹⵏ\nnoStreamsOptionFirefox = ⴰⵔⵎⴰⵜ ⴰⵎⵙⵙⴰⵔⴰ ⵏⵏⵖ ⴰⵎⵓⴼⴰⵢ\nnoStreamsOptionDownload = ⵙⵎⴷ ⵙ ⵓⵎⵙⵙⴰⵔⴰ ⴰ\ndownloadFirefoxPromo = ⵉⵜⵜⵓⵙⵓⵎⵔ ⴰⵡⵏ { -send-short-brand } ⵙⴳ ⵖⵓⵔ { -firefox } ⴰⵎⴰⵢⵏⵓ ⴰⴽⴽⵯ.\n# the next line after the colon contains a file name\nshareLinkDescription = ⴱⴹⵓⵢⴰⵜ ⴰⵙⵖⵏ ⵖⵔ ⵓⴼⴰⵢⵍⵓ ⵏⵏⵓⵏ:\nshareLinkButton = ⴱⴹⵓ ⴰⵙⵖⵏ\n# $name is the name of the file\nshareMessage = ⴰⴳⵎⴰⵜ \"{ $name }\" ⵙ { -send-brand }: ⴰⴱⵟⵟⵓ ⴰⴼⵔⴰⵔ ⴷ ⵡⵓⵙⵍⵉⴳ ⵏ ⵉⴼⵓⵢⵍⴰ\ntrailheadPromo = ⵜⵍⵍⴰ ⵢⴰⵜ ⵜⵖⴰⵔⴰⵙⵜ ⴰⴼⴰⴷ ⴰⴷ ⵜⴼⵔⴳⵎ ⵜⵉⵏⵏⵓⵜⵍⴰ ⵏⵏⵓⵏ. ⵍⴽⵎⴰⵜ ⴼⴰⵢⵔⴼⵓⴽⵙ.\nlearnMore = ⵙⵙⵏ ⵓⴳⴳⴰⵔ.\n"
  },
  {
    "path": "public/locales/zh-CN/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = 正在导入…\nencryptingFile = 正在加密…\ndecryptingFile = 正在解密…\ndownloadCount =\n    { $num ->\n       *[other] { $num } 次下载\n    }\ntimespanHours =\n    { $num ->\n       *[other] { $num } 小时\n    }\ncopiedUrl = 已复制！\nunlockInputPlaceholder = 密码\nunlockButtonLabel = 解锁\ndownloadButtonLabel = 下载\ndownloadFinish = 下载完成\nfileSizeProgress = ({ $partialSize } / { $totalSize })\nsendYourFilesLink = 试试 Send\nerrorPageHeader = 我们遇到错误。\nfileTooBig = 此文件太大。文件大小上限为 { $size }。\nlinkExpiredAlt = 链接已过期\nnotSupportedHeader = 不支持您的浏览器。\nnotSupportedLink = 为什么不支持我的浏览器？\nnotSupportedOutdatedDetail = 很可惜，此版本的 Firefox 不支持 Send 所使用的 Web 技术。您需要更新浏览器才能使用它。\nupdateFirefox = 更新 Firefox\ndeletePopupCancel = 取消\ndeleteButtonHover = 删除\nfooterLinkLegal = 法律\nfooterLinkPrivacy = 隐私\nfooterLinkCookies = Cookie\npasswordTryAgain = 密码不正确。请重试。\njavascriptRequired = Send 需要 JavaScript\nwhyJavascript = 为什么 Send 需要 JavaScript？\nenableJavascript = 请启用 JavaScript 并重试。\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } 小时 { $minutes } 分钟\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } 分钟\n# A short status message shown when the user enters a long password\nmaxPasswordLength = 最大密码长度：{ $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = 未能设置此密码\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = 简单、私密的文件分享服务\nintroDescription = 使用 { -send-brand } 端到端加密分享文件，链接到期即焚。分享更私密，文件到期真正无痕迹。\nnotifyUploadEncryptDone = 您的文件已加密，现在可以发送\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = { $downloadCount }或 { $timespan }后过期\ntimespanMinutes =\n    { $num ->\n        [one] 1 分钟\n       *[other] { $num } 分钟\n    }\ntimespanDays =\n    { $num ->\n        [one] 1 天\n       *[other] { $num } 天\n    }\ntimespanWeeks =\n    { $num ->\n        [one] 1 周\n       *[other] { $num } 周\n    }\nfileCount =\n    { $num ->\n        [one] 1 个文件\n       *[other] { $num } 个文件\n    }\n# byte abbreviation\nbytes = B\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num }{ $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = 总大小：{ $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = 复制链接以分享文件：\ncopyLinkButton = 复制链接\ndownloadTitle = 下载文件\ndownloadDescription = 此文件通过端到端加密的 { -send-brand } 与您分享，链接到期即焚。\ntrySendDescription = 试试 { -send-brand }，简单、私密的文件分享服务。\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n        [one] 一次只可上传 1 个文件。\n       *[other] 一次只可上传 { $count } 个文件。\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n       *[other] 只可上传 { $count } 个压缩文件。\n    }\nexpiredTitle = 此链接已过期。\nnotSupportedDescription = { -send-brand } 无法在此浏览器上正常工作。{ -send-short-brand } 与最新版本 { -firefox } 配合使用体验最佳，也适用于目前的大多数浏览器。\ndownloadFirefox = 下载 { -firefox }\nlegalTitle = { -send-short-brand } 隐私声明\nlegalDateStamp = 版本 1.0，于 2019年3月12日\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } 天 { $hours } 小时 { $minutes } 分钟\naddFilesButton = 选择要上传的文件\ntrustWarningMessage = 分享敏感数据时，请确保您信任接收人。\nuploadButton = 上传\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = 拖放文件\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = 或点此传送最大 { $size } 的文件\naddPassword = 密码保护\nemailPlaceholder = 请输入您的电子邮件地址\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = 登录以传送最大 { $size } 文件\nsignInOnlyButton = 登录\naccountBenefitTitle = 创建一个 { -firefox } 账户或登录\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = 分享最大 { $size } 文件\naccountBenefitDownloadCount = 可以与更多人分享\naccountBenefitTimeLimit =\n    { $count ->\n        [one] 链接有效期延至 1 天\n       *[other] 链接有效期延至 { $count } 天\n    }\naccountBenefitSync = 任何设备上都能管理分享的文件\naccountBenefitMoz = 了解其他 { -mozilla } 服务\nsignOut = 退出\nokButton = 确定\ndownloadingTitle = 正在下载\nnoStreamsWarning = 此浏览器可能无法解密这么大的文件。\nnoStreamsOptionCopy = 复制链接以在其他浏览器中打开\nnoStreamsOptionFirefox = 试试大家最爱的浏览器\nnoStreamsOptionDownload = 使用此浏览器继续\ndownloadFirefoxPromo = { -send-short-brand } 由焕然一新的 { -firefox } 为您奉上。\n# the next line after the colon contains a file name\nshareLinkDescription = 您的文件链接：\nshareLinkButton = 分享链接\n# $name is the name of the file\nshareMessage = 使用 { -send-brand } 下载“{ $name }”：简单、安全的文件分享服务\ntrailheadPromo = 捍卫隐私不是幻想。加入 Firefox 一同抗争。\nlearnMore = 详细了解。\ndownloadFlagged = 由于违反服务条款，此链接已被禁用。\ndownloadConfirmTitle = 除此之外\ndownloadConfirmDescription = 请确保您信任发送此文件的人，因为我们无法验证该文件是否会损坏您的设备。\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n        [one] 我信任发送此文件的人\n       *[other] 我信任发送这些文件的人\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n        [one] 举报此可疑文件\n       *[other] 举报这些可疑文件\n    }\nreportDescription = 帮助我们了解发生了什么。您认为这些文件存在什么问题？\nreportUnknownDescription = 请转至您要举报的链接 URL，然后点击 “{ reportFile }”。\nreportButton = 举报\nreportReasonMalware = 这些文件包含恶意软件或是网络钓鱼攻击的一环。\nreportReasonPii = 这些文件包含我的个人身份信息。\nreportReasonAbuse = 这些文件包含非法或滥用内容。\nreportReasonCopyright = 要举报版权或商标侵权，请按照<a>此页面</a>中所述步骤。\nreportedTitle = 文件已举报\nreportedDescription = 感谢，我们已收到您关于这些文件的举报。\n"
  },
  {
    "path": "public/locales/zh-TW/send.ftl",
    "content": "# Send is a brand name and should not be localized.\ntitle = Send\nimportingFile = 匯入中…\nencryptingFile = 加密中…\ndecryptingFile = 解密中…\ndownloadCount =\n    { $num ->\n       *[other] { $num } 次下載\n    }\ntimespanHours =\n    { $num ->\n       *[other] { $num } 小時\n    }\ncopiedUrl = 已複製！\nunlockInputPlaceholder = 密碼\nunlockButtonLabel = 解鎖\ndownloadButtonLabel = 下載\ndownloadFinish = 下載完成\nfileSizeProgress = （{ $partialSize }，共 { $totalSize }）\nsendYourFilesLink = 試用 Send\nerrorPageHeader = 有些東西不對勁！\nfileTooBig = 檔案太大無法上傳。檔案大小限制為 { $size }。\nlinkExpiredAlt = 鏈結已過期\nnotSupportedHeader = 不支援您的瀏覽器。\nnotSupportedLink = 為什麼我的瀏覽器不支援？\nnotSupportedOutdatedDetail = 很可惜，此版本的 Firefox 不支援 Send 所需的 Web 技術。請更新瀏覽器後再使用。\nupdateFirefox = 更新 Firefox\ndeletePopupCancel = 取消\ndeleteButtonHover = 刪除\nfooterLinkLegal = 法律資訊\nfooterLinkPrivacy = 隱私權\nfooterLinkCookies = Cookie\npasswordTryAgain = 密碼不正確，請再試一次。\njavascriptRequired = Send 需要開啟 JavaScript 功能\nwhyJavascript = 為什麼 Send 需要 JavaScript 才能使用？\nenableJavascript = 請開啟 JavaScript 功能後再試一次。\n# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example \"13h 47m\"\nexpiresHoursMinutes = { $hours } 時 { $minutes } 分\n# A short representation of a countdown timer containing the number of minutes remaining as digits, example \"56m\"\nexpiresMinutes = { $minutes } 分鐘\n# A short status message shown when the user enters a long password\nmaxPasswordLength = 最大密碼長度: { $length }\n# A short status message shown when there was an error setting the password\npasswordSetError = 無法設定此密碼\n\n## Send version 2 strings\n\n# Send, Send, Firefox, Mozilla are proper names and should not be localized\n-send-brand = Send\n-send-short-brand = Send\n-firefox = Firefox\n-mozilla = Mozilla\nintroTitle = 簡單而私密的檔案共享服務\nintroDescription = { -send-brand } 讓您可透過點對點加密的方式來分享檔案，並提供會自動失效的鏈結。這樣一來就可以保留分享時的隱私，也確保檔案不會永久保存於網路上。\nnotifyUploadEncryptDone = 已加密您的檔案，可以傳送\n# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'\narchiveExpiryInfo = { $downloadCount } 或 { $timespan } 後失效\ntimespanMinutes =\n    { $num ->\n       *[other] { $num } 分鐘\n    }\ntimespanDays =\n    { $num ->\n       *[other] { $num } 天\n    }\ntimespanWeeks =\n    { $num ->\n       *[other] { $num } 週\n    }\nfileCount =\n    { $num ->\n       *[other] { $num } 個檔案\n    }\n# byte abbreviation\nbytes = 位元組\n# kibibyte abbreviation\nkb = KB\n# mebibyte abbreviation\nmb = MB\n# gibibyte abbreviation\ngb = GB\n# localized number and byte abbreviation. example \"2.5MB\"\nfileSize = { $num } { $units }\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\ntotalSize = 總大小: { $size }\n# the next line after the colon contains a file name\ncopyLinkDescription = 複製鏈結即可分享您的檔案:\ncopyLinkButton = 複製鏈結\ndownloadTitle = 下載檔案\ndownloadDescription = 此檔案是透過 { -send-brand } 進行分享，以點對點加密的方式來分享檔案，並提供會自動失效的鏈結。\ntrySendDescription = 快試試 { -send-brand }，簡單安全的檔案分享機制。\n# count will always be > 10\ntooManyFiles =\n    { $count ->\n       *[other] 一次僅能上傳 { $count } 個檔案。\n    }\n# count will always be > 10\ntooManyArchives =\n    { $count ->\n       *[other] 僅允許 { $count } 個壓縮檔。\n    }\nexpiredTitle = 此鏈結已經失效。\nnotSupportedDescription = 無法於此瀏覽器使用 { -send-brand }。在最新版的 { -firefox } 中使用 { -send-short-brand } 會有最佳效果，也可在大部分瀏覽器的最新版本當中使用。\ndownloadFirefox = 下載 { -firefox }\nlegalTitle = { -send-short-brand } 隱私權公告\nlegalDateStamp = 1.0 版，2019 年 3 月 12 日生效\n# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example \"2d 11h 56m\"\nexpiresDaysHoursMinutes = { $days } 天 { $hours } 小時 { $minutes } 分鐘\naddFilesButton = 選擇要上傳的檔案\ntrustWarningMessage = 分享敏感資料時，請務必確認收件者是可信任的人。\nuploadButton = 上傳\n# the first part of the string 'Drag and drop files or click to send up to 1GB'\ndragAndDropFiles = 拖放檔案到此處\n# the second part of the string 'Drag and drop files or click to send up to 1GB'\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\norClickWithSize = 或點擊即可傳送最大 { $size } 的檔案\naddPassword = 使用密碼保護\nemailPlaceholder = 輸入您的電子郵件地址\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\nsignInSizeBump = 登入後即可傳送最大 { $size } 的檔案\nsignInOnlyButton = 登入\naccountBenefitTitle = 註冊 { -firefox } 帳號或登入\n# $size is the size of the file, displayed using the fileSize message as format (e.g. \"2.5MB\")\naccountBenefitLargeFiles = 分享最大 { $size } 的檔案\naccountBenefitDownloadCount = 分享檔案給更多人\naccountBenefitTimeLimit =\n    { $count ->\n       *[other] 將檔案鏈結保留 { $count } 天有效\n    }\naccountBenefitSync = 從任何裝置管理分享的檔案\naccountBenefitMoz = 了解其他 { -mozilla } 服務的更多資訊\nsignOut = 登出\nokButton = 確定\ndownloadingTitle = 下載中\nnoStreamsWarning = 此瀏覽器無法解密這麼大的檔案。\nnoStreamsOptionCopy = 複製鏈結，用其他瀏覽器開啟\nnoStreamsOptionFirefox = 試試我們最愛的瀏覽器\nnoStreamsOptionDownload = 繼續使用目前的瀏覽器\ndownloadFirefoxPromo = { -send-short-brand } 是由全新的 { -firefox } 提供。\n# the next line after the colon contains a file name\nshareLinkDescription = 您的檔案鏈結:\nshareLinkButton = 分享鏈結\n# $name is the name of the file\nshareMessage = 使用 { -send-brand } 下載「{ $name }」: 簡單安全的檔案分享機制\ntrailheadPromo = 有種方法可以保護您的隱私，加入 Firefox。\nlearnMore = 了解更多。\ndownloadFlagged = 由於違反了服務條款，已停用此鏈結。\ndownloadConfirmTitle = 還有一件事\ndownloadConfirmDescription = 因為我們無法檢查此檔案是否會傷害您的裝置，請務必確認發送者是否可受信任。\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\ndownloadTrustCheckbox =\n    { $count ->\n       *[other] 我信任傳送檔案給我的人\n    }\n# This string has a special case for '1' and [other] (default). If necessary for\n# your language, you can add {$count} to your translations and use the\n# standard CLDR forms, or only use the form for [other] if both strings should\n# be identical.\nreportFile =\n    { $count ->\n       *[other] 回報檔案為可疑檔案\n    }\nreportDescription = 請幫助我們釐清發生了什麼事。您覺得這些檔案有什麼問題？\nreportUnknownDescription = 請到想要回報的鏈結網址點擊「{ reportFile }」。\nreportButton = 回報\nreportReasonMalware = 這些檔案包含惡意軟體，或是釣魚攻擊的一部分。\nreportReasonPii = 這些檔案包含我的個人資訊。\nreportReasonAbuse = 這些檔案包含非法或濫用內容。\nreportReasonCopyright = 若檔案內容侵犯了著作權或商標，請根據<a>此頁面</a>當中描述的方式進行回報。\nreportedTitle = 已回報檔案問題\nreportedDescription = 感謝您。我們已經收到您對這些檔案的問題回報。\n"
  },
  {
    "path": "scripts/.eslintrc.yml",
    "content": "rules:\n  node/shebang: off\n  security/detect-child-process: off\n\n  no-console: off\n  no-process-exit: off\n"
  },
  {
    "path": "scripts/bin/run-integration-test-circleci.sh",
    "content": "#!/bin/bash\nset -ex\n\nGECKODRIVER_URL=$(\n  curl -s 'https://api.github.com/repos/mozilla/geckodriver/releases/latest' |\n  python -c \"import sys, json; r = json.load(sys.stdin); print([a for a in r['assets'] if 'linux64' in a['name']][0]['browser_download_url']);\"\n);\n\n\ncurl -L -o geckodriver.tar.gz $GECKODRIVER_URL\ngunzip -c geckodriver.tar.gz | tar xopf -\nchmod +x geckodriver\nsudo mv geckodriver /bin\ngeckodriver --version\n# Install pip\nsudo apt-get install python-pip\nsudo pip install --upgrade pip\n\nsudo pip install mozdownload mozinstall==1.15\n\nmkdir -p ~/project/firefox-downloads/\nfind  ~/project/firefox-downloads/ -type f -mtime +90 -delete\nmozdownload --version latest --type daily --destination ~/project/firefox-downloads/firefox_nightly/\n\nexport PATH=~/project/firefox:$PATH\nmozinstall $(ls -t firefox-downloads/firefox_nightly/*.tar.bz2 | head -1)\nfirefox --version\n npm run circleci-test-integration"
  },
  {
    "path": "scripts/get-prod-locales.js",
    "content": "#!/usr/bin/env node\n\nconst cp = require('child_process');\nconst { promisify } = require('util');\nconst fs = require('fs');\nconst pkg = require('../package.json');\n\nconst availableLanguages = pkg.availableLanguages.sort();\nconst exec = promisify(cp.exec);\n\nconst arrayDiff = (current, package) =>\n  current.filter(locale => !package.includes(locale));\n\nconst cmd = 'compare-locales l10n.toml . `ls public/locales` --data=json';\n\nexec(cmd)\n  .then(({ stdout }) => JSON.parse(stdout))\n  .then(({ summary }) => {\n    const locales = Object.keys(summary)\n      .filter(locale => {\n        const loc = summary[locale];\n        const hasMissing = Object.prototype.hasOwnProperty.call(loc, 'missing');\n        const hasErrors = Object.prototype.hasOwnProperty.call(loc, 'errors');\n        return !hasMissing && !hasErrors;\n      })\n      .sort();\n\n    if (locales.join(',') !== availableLanguages.join(',')) {\n      const missingLanguages = arrayDiff(locales, availableLanguages);\n\n      console.log('current 100%:', JSON.stringify(locales));\n      console.log('package.json:', JSON.stringify(availableLanguages));\n      console.log('missing prod:', JSON.stringify(missingLanguages));\n\n      if (process.argv.includes('--write')) {\n        const pkgPath = require.resolve('../package.json');\n        pkg.availableLanguages = locales;\n        const str = JSON.stringify(pkg, null, 2) + '\\n';\n        console.log('Updating /package.json availableLanguages');\n        fs.writeFileSync(pkgPath, str, 'utf-8');\n      }\n    } else {\n      console.log('Production locales are up to date!');\n    }\n  })\n  .catch(err => {\n    console.error(err);\n    process.exit(1);\n  });\n"
  },
  {
    "path": "scripts/lint-locales.js",
    "content": "#!/usr/bin/env node\n\nconst cp = require('child_process');\nconst { promisify } = require('util');\nconst pkg = require('../package.json');\nconst conf = require('../server/config');\n\nconst exec = promisify(cp.exec);\nconst cmd = `compare-locales l10n.toml . ${getLocales()} --data=json`;\n\nconsole.log(cmd);\n\nexec(cmd)\n  .then(({ stdout }) => JSON.parse(stdout))\n  .then(({ details }) => filterErrors(details))\n  .then(results => {\n    if (results.length) {\n      results.forEach(({ locale, data }) => {\n        console.log(locale);\n        data.forEach(msg => console.log(`- ${msg}`));\n        console.log('');\n      });\n      process.exit(2);\n    }\n  })\n  .catch(err => {\n    console.error(err);\n    process.exit(1);\n  });\n\nfunction filterErrors(details) {\n  return Object.keys(details)\n    .sort()\n    .map(locale => {\n      const data = details[locale]\n        .filter(item => Object.prototype.hasOwnProperty.call(item, 'error'))\n        .map(({ error }) => error);\n      return { locale, data };\n    })\n    .filter(({ data }) => data.length);\n}\n\nfunction getLocales() {\n  // If we're in a \"production\" env (or passed the `--production` flag), only\n  // check the locales from the package.json file's `availableLanguages` array.\n  if (conf.env === 'production' || process.argv.includes('--production')) {\n    return pkg.availableLanguages.sort().join(' ');\n  }\n  // Lint all the locales.\n  return '`ls public/locales`';\n}\n"
  },
  {
    "path": "scripts/sync-npm-dependencies.sh",
    "content": "#!/bin/bash\n\necho \"checking package-lock.json for changes\"\nIFS=' '\nread -ra G_PARAMS <<< \"$HUSKY_GIT_PARAMS\"\nPREV=${G_PARAMS[0]}\nNEXT=${G_PARAMS[1]}\nif [ \"$PREV\" != \"$NEXT\" ]; then\n  DIFF=$(git diff $PREV $NEXT package-lock.json)\n  if [ \"$DIFF\" != \"\" ]; then\n    npm install\n  fi\nfi"
  },
  {
    "path": "server/amplitude.js",
    "content": "const crypto = require('crypto');\nconst fetch = require('node-fetch');\nconst config = require('./config');\nconst pkg = require('../package.json');\n\nconst HOUR = 1000 * 60 * 60;\n\nfunction truncateToHour(timestamp) {\n  return Math.floor(timestamp / HOUR) * HOUR;\n}\n\nfunction orderOfMagnitude(n) {\n  return Math.floor(Math.log10(n));\n}\n\nfunction userId(fileId, ownerId) {\n  const hash = crypto.createHash('sha256');\n  hash.update(fileId);\n  hash.update(ownerId);\n  return hash.digest('hex').substring(32);\n}\n\nfunction statUploadEvent(data) {\n  const event = {\n    session_id: -1,\n    country: data.country,\n    region: data.state,\n    user_id: userId(data.id, data.owner),\n    app_version: pkg.version,\n    time: truncateToHour(Date.now()),\n    event_type: 'server_upload',\n    user_properties: {\n      download_limit: data.dlimit,\n      time_limit: data.timeLimit,\n      size: orderOfMagnitude(data.size),\n      anonymous: data.anonymous\n    },\n    event_properties: {\n      agent: data.agent\n    },\n    event_id: 0\n  };\n  return sendBatch([event]);\n}\n\nfunction statDownloadEvent(data) {\n  const event = {\n    session_id: -1,\n    country: data.country,\n    region: data.state,\n    user_id: userId(data.id, data.owner),\n    app_version: pkg.version,\n    time: truncateToHour(Date.now()),\n    event_type: 'server_download',\n    event_properties: {\n      agent: data.agent,\n      download_count: data.download_count,\n      ttl: data.ttl\n    },\n    event_id: data.download_count\n  };\n  return sendBatch([event]);\n}\n\nfunction statDeleteEvent(data) {\n  const event = {\n    session_id: -1,\n    country: data.country,\n    region: data.state,\n    user_id: userId(data.id, data.owner),\n    app_version: pkg.version,\n    time: truncateToHour(Date.now()),\n    event_type: 'server_delete',\n    event_properties: {\n      agent: data.agent,\n      download_count: data.download_count,\n      ttl: data.ttl\n    },\n    event_id: data.download_count + 1\n  };\n  return sendBatch([event]);\n}\n\nfunction statReportEvent(data) {\n  const event = {\n    session_id: -1,\n    country: data.country,\n    region: data.state,\n    user_id: userId(data.id, data.owner),\n    app_version: pkg.version,\n    time: truncateToHour(Date.now()),\n    event_type: 'server_report',\n    event_properties: {\n      reason: data.reason,\n      agent: data.agent,\n      download_limit: data.dlimit,\n      download_count: data.download_count,\n      ttl: data.ttl\n    },\n    event_id: data.download_count + 1\n  };\n  return sendBatch([event]);\n}\n\nfunction clientEvent(\n  event,\n  ua,\n  language,\n  session_id,\n  deltaT,\n  platform,\n  country,\n  state\n) {\n  const ep = event.event_properties || {};\n  const up = event.user_properties || {};\n  const event_properties = {\n    browser: ua.browser.name,\n    browser_version: ua.browser.version,\n    status: ep.status,\n\n    age: ep.age,\n    downloaded: ep.downloaded,\n    download_limit: ep.download_limit,\n    duration: ep.duration,\n    entrypoint: ep.entrypoint,\n    file_count: ep.file_count,\n    password_protected: ep.password_protected,\n    referrer: ep.referrer,\n    size: ep.size,\n    time_limit: ep.time_limit,\n    trigger: ep.trigger,\n    ttl: ep.ttl,\n    utm_campaign: ep.utm_campaign,\n    utm_content: ep.utm_content,\n    utm_medium: ep.utm_medium,\n    utm_source: ep.utm_source,\n    utm_term: ep.utm_term,\n    experiment: ep.experiment,\n    variant: ep.variant\n  };\n  const user_properties = {\n    active_count: up.active_count,\n    anonymous: up.anonymous,\n    experiments: up.experiments,\n    first_action: up.first_action\n  };\n  return {\n    app_version: pkg.version,\n    country: country,\n    device_id: event.device_id,\n    event_properties,\n    event_type: event.event_type,\n    language,\n    os_name: ua.os.name,\n    os_version: ua.os.version,\n    platform,\n    region: state,\n    session_id,\n    time: event.time + deltaT,\n    user_id: event.user_id,\n    user_properties\n  };\n}\n\nasync function sendBatch(events, timeout = 1000) {\n  if (!config.amplitude_id) {\n    return 200;\n  }\n  try {\n    const result = await fetch('https://api.amplitude.com/batch', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({\n        api_key: config.amplitude_id,\n        events\n      }),\n      timeout\n    });\n    return result.status;\n  } catch (e) {\n    return 500;\n  }\n}\n\nmodule.exports = {\n  statUploadEvent,\n  statDownloadEvent,\n  statDeleteEvent,\n  statReportEvent,\n  clientEvent,\n  sendBatch\n};\n"
  },
  {
    "path": "server/bin/dev.js",
    "content": "const assets = require('../../common/assets');\nconst routes = require('../routes');\nconst pages = require('../routes/pages');\nconst tests = require('../../test/frontend/routes');\nconst express = require('express');\nconst expressWs = require('@dannycoates/express-ws');\nconst morgan = require('morgan');\nconst config = require('../config');\n\nconst ID_REGEX = '([0-9a-fA-F]{10, 16})';\n\nmodule.exports = function(app, devServer) {\n  const wsapp = express();\n  expressWs(wsapp, null, { perMessageDeflate: false });\n  routes(wsapp);\n  wsapp.ws('/api/ws', require('../routes/ws'));\n  wsapp.listen(1338, config.listen_address);\n\n  assets.setMiddleware(devServer.middleware);\n  app.use(morgan('dev', { stream: process.stderr }));\n  function android(req, res) {\n    const index = devServer.middleware.fileSystem\n      .readFileSync(devServer.middleware.getFilenameFromUrl('/android.html'))\n      .toString()\n      .replace(\n        '<base href=\"file:///android_asset/\" />',\n        '<base href=\"http://localhost:8080/\" />'\n      );\n    res.set('Content-Type', 'text/html');\n    res.send(index);\n  }\n  if (process.env.ANDROID) {\n    // map all html routes to the android index.html\n    app.get('/', android);\n    app.get(`/share/:id${ID_REGEX}`, android);\n    app.get('/completed', android);\n    app.get('/preferences', android);\n    app.get('/options', android);\n    app.get('/oauth', android);\n  }\n  routes(app);\n  tests(app);\n  // webpack-dev-server routes haven't been added yet\n  // so wait for next tick to add 404 handler\n  process.nextTick(() => app.use(pages.notfound));\n};\n"
  },
  {
    "path": "server/bin/prod.js",
    "content": "const express = require('express');\nconst path = require('path');\nconst Sentry = require('@sentry/node');\nconst config = require('../config');\nconst routes = require('../routes');\nconst pages = require('../routes/pages');\nconst expressWs = require('@dannycoates/express-ws');\n\nif (config.sentry_dsn) {\n  Sentry.init({ dsn: config.sentry_dsn });\n}\n\nconst app = express();\n\nexpressWs(app, null, { perMessageDeflate: false });\nroutes(app);\napp.ws('/api/ws', require('../routes/ws'));\n\napp.use(\n  express.static(path.resolve(__dirname, '../../dist/'), {\n    setHeaders: function(res, path) {\n      if (!/serviceWorker\\.js$/.test(path)) {\n        res.set('Cache-Control', 'public, max-age=31536000, immutable');\n      }\n      res.removeHeader('Pragma');\n    }\n  })\n);\n\napp.use(pages.notfound);\n\napp.listen(config.listen_port, config.listen_address);\n"
  },
  {
    "path": "server/bin/test.js",
    "content": "const assets = require('../../common/assets');\nconst routes = require('../routes');\nconst pages = require('../routes/pages');\nconst tests = require('../../test/frontend/routes');\nconst expressWs = require('@dannycoates/express-ws');\n\nmodule.exports = function(app, devServer) {\n  assets.setMiddleware(devServer.middleware);\n  expressWs(app, null, { perMessageDeflate: false });\n  routes(app);\n  app.ws('/api/ws', require('../routes/ws'));\n  tests(app);\n  // webpack-dev-server routes haven't been added yet\n  // so wait for next tick to add 404 handler\n  process.nextTick(() => app.use(pages.notfound));\n};\n"
  },
  {
    "path": "server/clientConstants.js",
    "content": "const config = require('./config');\n\nmodule.exports = {\n  LIMITS: {\n    ANON: {\n      MAX_FILE_SIZE: config.anon_max_file_size,\n      MAX_DOWNLOADS: config.anon_max_downloads,\n      MAX_EXPIRE_SECONDS: config.anon_max_expire_seconds\n    },\n    MAX_FILE_SIZE: config.max_file_size,\n    MAX_DOWNLOADS: config.max_downloads,\n    MAX_EXPIRE_SECONDS: config.max_expire_seconds,\n    MAX_FILES_PER_ARCHIVE: config.max_files_per_archive,\n    MAX_ARCHIVES_PER_USER: config.max_archives_per_user\n  },\n  DEFAULTS: {\n    DOWNLOAD_COUNTS: config.download_counts,\n    EXPIRE_TIMES_SECONDS: config.expire_times_seconds,\n    EXPIRE_SECONDS: config.default_expire_seconds\n  }\n};\n"
  },
  {
    "path": "server/config.js",
    "content": "const convict = require('convict');\nconst { tmpdir } = require('os');\nconst path = require('path');\nconst { randomBytes } = require('crypto');\n\nconst conf = convict({\n  s3_bucket: {\n    format: String,\n    default: '',\n    env: 'S3_BUCKET'\n  },\n  s3_endpoint: {\n    format: String,\n    default: '',\n    env: 'S3_ENDPOINT'\n  },\n  s3_use_path_style_endpoint: {\n    format: Boolean,\n    default: false,\n    env: 'S3_USE_PATH_STYLE_ENDPOINT'\n  },\n  gcs_bucket: {\n    format: String,\n    default: '',\n    env: 'GCS_BUCKET'\n  },\n  expire_times_seconds: {\n    format: Array,\n    default: [300, 3600, 86400, 604800],\n    env: 'EXPIRE_TIMES_SECONDS'\n  },\n  default_expire_seconds: {\n    format: Number,\n    default: 86400,\n    env: 'DEFAULT_EXPIRE_SECONDS'\n  },\n  max_expire_seconds: {\n    format: Number,\n    default: 86400 * 7,\n    env: 'MAX_EXPIRE_SECONDS'\n  },\n  anon_max_expire_seconds: {\n    format: Number,\n    default: 86400,\n    env: 'ANON_MAX_EXPIRE_SECONDS'\n  },\n  download_counts: {\n    format: Array,\n    default: [1, 2, 3, 4, 5, 20, 50, 100],\n    env: 'DOWNLOAD_COUNTS'\n  },\n  max_downloads: {\n    format: Number,\n    default: 100,\n    env: 'MAX_DOWNLOADS'\n  },\n  anon_max_downloads: {\n    format: Number,\n    default: 5,\n    env: 'ANON_MAX_DOWNLOADS'\n  },\n  max_files_per_archive: {\n    format: Number,\n    default: 64,\n    env: 'MAX_FILES_PER_ARCHIVE'\n  },\n  max_archives_per_user: {\n    format: Number,\n    default: 16,\n    env: 'MAX_ARCHIVES_PER_USER'\n  },\n  redis_host: {\n    format: String,\n    default: 'mock',\n    env: 'REDIS_HOST'\n  },\n  redis_event_expire: {\n    format: Boolean,\n    default: false,\n    env: 'REDIS_EVENT_EXPIRE'\n  },\n  redis_retry_time: {\n    format: Number,\n    default: 10000,\n    env: 'REDIS_RETRY_TIME'\n  },\n  redis_retry_delay: {\n    format: Number,\n    default: 500,\n    env: 'REDIS_RETRY_DELAY'\n  },\n  listen_address: {\n    format: 'ipaddress',\n    default: '0.0.0.0',\n    env: 'IP_ADDRESS'\n  },\n  listen_port: {\n    format: 'port',\n    default: 1443,\n    arg: 'port',\n    env: 'PORT'\n  },\n  amplitude_id: {\n    format: String,\n    default: '',\n    env: 'AMPLITUDE_ID'\n  },\n  analytics_id: {\n    format: String,\n    default: '',\n    env: 'GOOGLE_ANALYTICS_ID'\n  },\n  sentry_id: {\n    format: String,\n    default: '',\n    env: 'SENTRY_CLIENT'\n  },\n  sentry_dsn: {\n    format: String,\n    default: '',\n    env: 'SENTRY_DSN'\n  },\n  sentry_host: {\n    format: String,\n    default: 'https://sentry.prod.mozaws.net',\n    env: 'SENTRY_HOST'\n  },\n  env: {\n    format: ['production', 'development', 'test'],\n    default: 'development',\n    env: 'NODE_ENV'\n  },\n  max_file_size: {\n    format: Number,\n    default: 1024 * 1024 * 1024 * 2.5,\n    env: 'MAX_FILE_SIZE'\n  },\n  anon_max_file_size: {\n    format: Number,\n    default: 1024 * 1024 * 1024,\n    env: 'ANON_MAX_FILE_SIZE'\n  },\n  l10n_dev: {\n    format: Boolean,\n    default: false,\n    env: 'L10N_DEV'\n  },\n  base_url: {\n    format: 'url',\n    default: 'https://send.firefox.com',\n    env: 'BASE_URL'\n  },\n  file_dir: {\n    format: 'String',\n    default: `${tmpdir()}${path.sep}send-${randomBytes(4).toString('hex')}`,\n    env: 'FILE_DIR'\n  },\n  fxa_required: {\n    format: Boolean,\n    default: false,\n    env: 'FXA_REQUIRED'\n  },\n  fxa_url: {\n    format: 'url',\n    default: 'http://localhost:3030',\n    env: 'FXA_URL'\n  },\n  fxa_client_id: {\n    format: String,\n    default: '', // disabled\n    env: 'FXA_CLIENT_ID'\n  },\n  fxa_key_scope: {\n    format: String,\n    default: 'https://identity.mozilla.com/apps/send',\n    env: 'FXA_KEY_SCOPE'\n  },\n  fxa_csp_oauth_url: {\n    format: String,\n    default: '',\n    env: 'FXA_CSP_OAUTH_URL'\n  },\n  fxa_csp_content_url: {\n    format: String,\n    default: '',\n    env: 'FXA_CSP_CONTENT_URL'\n  },\n  fxa_csp_profile_url: {\n    format: String,\n    default: '',\n    env: 'FXA_CSP_PROFILE_URL'\n  },\n  fxa_csp_profileimage_url: {\n    format: String,\n    default: '',\n    env: 'FXA_CSP_PROFILEIMAGE_URL'\n  },\n  survey_url: {\n    format: String,\n    default: '',\n    env: 'SURVEY_URL'\n  },\n  ip_db: {\n    format: String,\n    default: '',\n    env: 'IP_DB'\n  }\n});\n\n// Perform validation\nconf.validate({ allowed: 'strict' });\n\nconst props = conf.getProperties();\nmodule.exports = props;\n"
  },
  {
    "path": "server/fxa.js",
    "content": "const fetch = require('node-fetch');\nconst config = require('./config');\n\nconst KEY_SCOPE = config.fxa_key_scope;\nlet fxaConfig = null;\nlet lastConfigRefresh = 0;\n\nasync function getFxaConfig() {\n  if (fxaConfig && Date.now() - lastConfigRefresh < 1000 * 60 * 5) {\n    return fxaConfig;\n  }\n  try {\n    const res = await fetch(\n      `${config.fxa_url}/.well-known/openid-configuration`,\n      { timeout: 3000 }\n    );\n    fxaConfig = await res.json();\n    fxaConfig.key_scope = KEY_SCOPE;\n    lastConfigRefresh = Date.now();\n  } catch (e) {\n    // continue with previous fxaConfig\n  }\n  return fxaConfig;\n}\n\nmodule.exports = {\n  getFxaConfig,\n  verify: async function(token) {\n    if (!token) {\n      return null;\n    }\n\n    const c = await getFxaConfig();\n    try {\n      const verifyUrl = c.jwks_uri.replace('jwks', 'verify'); //HACK\n      const result = await fetch(verifyUrl, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ token })\n      });\n      const info = await result.json();\n      if (\n        info.scope &&\n        Array.isArray(info.scope) &&\n        info.scope.includes(KEY_SCOPE)\n      ) {\n        return info.user;\n      }\n    } catch (e) {\n      // gulp\n    }\n    return null;\n  }\n};\n"
  },
  {
    "path": "server/initScript.js",
    "content": "const html = require('choo/html');\nconst raw = require('choo/html/raw');\nconst config = require('./config');\nconst clientConstants = require('./clientConstants');\n\nlet sentry = '';\nif (config.sentry_id) {\n  //eslint-disable-next-line node/no-missing-require\n  const version = require('../dist/version.json');\n  sentry = `\nvar SENTRY_CONFIG = {\n  dsn: '${config.sentry_id}',\n  release: '${version.version}',\n  beforeSend: function (data) {\n    var hash = window.location.hash;\n    if (hash) {\n      return JSON.parse(JSON.stringify(data).replace(new RegExp(hash.slice(1), 'g'), ''));\n    }\n    return data;\n  }\n}\n`;\n}\n\nmodule.exports = function(state) {\n  const authConfig = state.authConfig\n    ? `var AUTH_CONFIG = ${JSON.stringify(state.authConfig)};`\n    : '';\n\n  /* eslint-disable no-useless-escape */\n  const jsconfig = `\n  var isIE = /trident\\\\\\/7\\.|msie/i.test(navigator.userAgent);\n  var isUnsupportedPage = /\\\\\\/unsupported/.test(location.pathname);\n  if (isIE && !isUnsupportedPage) {\n    window.location.assign('/unsupported/ie');\n  }\n  if (\n    // Firefox < 50\n    /firefox/i.test(navigator.userAgent) &&\n    parseInt(navigator.userAgent.match(/firefox\\\\/*([^\\\\n\\\\r]*)\\./i)[1], 10) < 50\n  ) {\n    window.location.assign('/unsupported/outdated');\n  }\n\n  var LIMITS = ${JSON.stringify(clientConstants.LIMITS)};\n  var DEFAULTS = ${JSON.stringify(clientConstants.DEFAULTS)};\n  var PREFS = ${JSON.stringify(state.prefs)};\n  var downloadMetadata = ${\n    state.downloadMetadata ? raw(JSON.stringify(state.downloadMetadata)) : '{}'\n  };\n  ${authConfig};\n  ${sentry}\n  `;\n  return state.cspNonce\n    ? html`\n        <script nonce=\"${state.cspNonce}\">\n          ${raw(jsconfig)};\n        </script>\n      `\n    : '';\n};\n"
  },
  {
    "path": "server/keychain.js",
    "content": "const { Crypto } = require('@peculiar/webcrypto');\nconst crypto = new Crypto();\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\nmodule.exports = class Keychain {\n  constructor(secretKeyB64) {\n    if (secretKeyB64) {\n      this.rawSecret = new Uint8Array(Buffer.from(secretKeyB64, 'base64'));\n    } else {\n      throw new Error('key is required');\n    }\n    this.secretKeyPromise = crypto.subtle.importKey(\n      'raw',\n      this.rawSecret,\n      'HKDF',\n      false,\n      ['deriveKey']\n    );\n    this.metaKeyPromise = this.secretKeyPromise.then(function(secretKey) {\n      return crypto.subtle.deriveKey(\n        {\n          name: 'HKDF',\n          salt: new Uint8Array(),\n          info: encoder.encode('metadata'),\n          hash: 'SHA-256'\n        },\n        secretKey,\n        {\n          name: 'AES-GCM',\n          length: 128\n        },\n        false,\n        ['decrypt']\n      );\n    });\n  }\n\n  async decryptMetadata(ciphertext) {\n    const metaKey = await this.metaKeyPromise;\n    const plaintext = await crypto.subtle.decrypt(\n      {\n        name: 'AES-GCM',\n        iv: new Uint8Array(12),\n        tagLength: 128\n      },\n      metaKey,\n      ciphertext\n    );\n    return JSON.parse(decoder.decode(plaintext));\n  }\n};\n"
  },
  {
    "path": "server/layout.js",
    "content": "const html = require('choo/html');\nconst assets = require('../common/assets');\nconst initScript = require('./initScript');\n\nmodule.exports = function(state, body = '') {\n  return html`\n    <!DOCTYPE html>\n    <html lang=\"${state.locale}\">\n      <head>\n        <title>${state.title}</title>\n        <base href=\"/\" />\n        <meta name=\"robots\" content=\"${state.robots},noarchive\" />\n        <meta name=\"google\" content=\"nositelinkssearchbox\" />\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n        <meta charset=\"utf-8\" />\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n        <meta name=\"theme-color\" content=\"#220033\" />\n        <meta name=\"msapplication-TileColor\" content=\"#220033\" />\n\n        <link rel=\"manifest\" href=\"/app.webmanifest\" />\n        <link rel=\"stylesheet\" type=\"text/css\" href=\"/inter.css\" />\n        <link\n          rel=\"stylesheet\"\n          type=\"text/css\"\n          href=\"${assets.get('app.css')}\"\n        />\n        <link\n          rel=\"apple-touch-icon\"\n          sizes=\"180x180\"\n          href=\"${assets.get('apple-touch-icon.png')}\"\n        />\n        <link\n          rel=\"icon\"\n          type=\"image/png\"\n          sizes=\"32x32\"\n          href=\"${assets.get('favicon-32x32.png')}\"\n        />\n        <link\n          rel=\"icon\"\n          type=\"image/png\"\n          sizes=\"16x16\"\n          href=\"${assets.get('favicon-16x16.png')}\"\n        />\n        <link\n          rel=\"mask-icon\"\n          href=\"${assets.get('safari-pinned-tab.svg')}\"\n          color=\"#838383\"\n        />\n        <script defer src=\"${assets.get('app.js')}\"></script>\n      </head>\n      <noscript>\n        <div class=\"noscript\">\n          <h2>${state.translate('javascriptRequired')}</h2>\n          <p>\n            <a\n              class=\"link\"\n              href=\"https://github.com/mozilla/send/blob/master/docs/faq.md#why-does-firefox-send-require-javascript\"\n            >\n              ${state.translate('whyJavascript')}\n            </a>\n          </p>\n          <p>${state.translate('enableJavascript')}</p>\n        </div>\n      </noscript>\n      ${body} ${initScript(state)}\n    </html>\n  `;\n};\n"
  },
  {
    "path": "server/limiter.js",
    "content": "const { Transform } = require('stream');\n\nclass Limiter extends Transform {\n  constructor(limit) {\n    super();\n    this.limit = limit;\n    this.length = 0;\n  }\n\n  _transform(chunk, encoding, callback) {\n    this.length += chunk.length;\n    this.push(chunk);\n    if (this.length > this.limit) {\n      console.error('LIMIT', this.length, this.limit);\n      return callback(new Error('limit'));\n    }\n    callback();\n  }\n}\n\nmodule.exports = Limiter;\n"
  },
  {
    "path": "server/locale.js",
    "content": "const fs = require('fs');\nconst path = require('path');\nconst { FluentBundle } = require('@fluent/bundle');\nconst localesPath = path.resolve(__dirname, '../public/locales');\nconst locales = fs.readdirSync(localesPath);\n\nfunction makeBundle(locale) {\n  const bundle = new FluentBundle(locale, { useIsolating: false });\n  bundle.addMessages(\n    fs.readFileSync(path.resolve(localesPath, locale, 'send.ftl'), 'utf8')\n  );\n  return [locale, bundle];\n}\n\nconst bundles = new Map(locales.map(makeBundle));\n\nmodule.exports = function getTranslator(locale) {\n  const defaultBundle = bundles.get('en-US');\n  const bundle = bundles.get(locale) || defaultBundle;\n  return function(id, data) {\n    if (bundle.hasMessage(id)) {\n      return bundle.format(bundle.getMessage(id), data);\n    }\n    return defaultBundle.format(defaultBundle.getMessage(id), data);\n  };\n};\n"
  },
  {
    "path": "server/log.js",
    "content": "const conf = require('./config');\n\nconst isProduction = conf.env === 'production';\n\nconst mozlog = require('mozlog')({\n  app: 'FirefoxSend',\n  level: isProduction ? 'INFO' : 'verbose',\n  fmt: isProduction ? 'heka' : 'pretty',\n  debug: !isProduction\n});\n\nmodule.exports = mozlog;\n"
  },
  {
    "path": "server/metadata.js",
    "content": "const crypto = require('crypto');\n\nfunction makeToken(secret, counter) {\n  const hmac = crypto.createHmac('sha256', secret);\n  hmac.update(String(counter));\n  return hmac.digest('hex');\n}\n\nclass Metadata {\n  constructor(obj, storage) {\n    this.id = obj.id;\n    this.dl = +obj.dl || 0;\n    this.dlToken = +obj.dlToken || 0;\n    this.dlimit = +obj.dlimit || 1;\n    this.pwd = !!+obj.pwd;\n    this.owner = obj.owner;\n    this.metadata = obj.metadata;\n    this.auth = obj.auth;\n    this.nonce = obj.nonce;\n    this.flagged = !!obj.flagged;\n    this.dead = !!obj.dead;\n    this.fxa = !!+obj.fxa;\n    this.storage = storage;\n  }\n\n  async getDownloadToken() {\n    if (this.dlToken >= this.dlimit) {\n      throw new Error('limit');\n    }\n    this.dlToken = await this.storage.incrementField(this.id, 'dlToken');\n    // another request could have also incremented\n    if (this.dlToken > this.dlimit) {\n      throw new Error('limit');\n    }\n    return makeToken(this.owner, this.dlToken);\n  }\n\n  async verifyDownloadToken(token) {\n    const validTokens = Array.from({ length: this.dlToken }, (_, i) =>\n      makeToken(this.owner, i + 1)\n    );\n    return validTokens.includes(token);\n  }\n}\n\nmodule.exports = Metadata;\n"
  },
  {
    "path": "server/middleware/auth.js",
    "content": "const assert = require('assert');\nconst crypto = require('crypto');\nconst storage = require('../storage');\nconst fxa = require('../fxa');\n\nmodule.exports = {\n  hmac: async function(req, res, next) {\n    const id = req.params.id;\n    const authHeader = req.header('Authorization');\n    if (id && authHeader) {\n      try {\n        const auth = req.header('Authorization').split(' ')[1];\n        const meta = await storage.metadata(id);\n        if (!meta) {\n          return res.sendStatus(404);\n        }\n        const hmac = crypto.createHmac(\n          'sha256',\n          Buffer.from(meta.auth, 'base64')\n        );\n        hmac.update(Buffer.from(meta.nonce, 'base64'));\n        const verifyHash = hmac.digest();\n        if (crypto.timingSafeEqual(verifyHash, Buffer.from(auth, 'base64'))) {\n          req.nonce = crypto.randomBytes(16).toString('base64');\n          storage.setField(id, 'nonce', req.nonce);\n          res.set('WWW-Authenticate', `send-v1 ${req.nonce}`);\n          req.authorized = true;\n          req.meta = meta;\n        } else {\n          res.set('WWW-Authenticate', `send-v1 ${meta.nonce}`);\n          req.authorized = false;\n        }\n      } catch (e) {\n        req.authorized = false;\n      }\n    }\n    if (req.authorized) {\n      next();\n    } else {\n      res.sendStatus(401);\n    }\n  },\n  owner: async function(req, res, next) {\n    const id = req.params.id;\n    const ownerToken = req.body.owner_token;\n    if (id && ownerToken) {\n      try {\n        req.meta = await storage.metadata(id);\n        if (!req.meta || req.meta.dead) {\n          return res.sendStatus(404);\n        }\n        const metaOwner = Buffer.from(req.meta.owner, 'utf8');\n        const owner = Buffer.from(ownerToken, 'utf8');\n        assert(metaOwner.length > 0);\n        assert(metaOwner.length === owner.length);\n        req.authorized = crypto.timingSafeEqual(metaOwner, owner);\n      } catch (e) {\n        req.authorized = false;\n      }\n    }\n    if (req.authorized) {\n      next();\n    } else {\n      res.sendStatus(401);\n    }\n  },\n  fxa: async function(req, res, next) {\n    const authHeader = req.header('Authorization');\n    if (authHeader && /^Bearer\\s/i.test(authHeader)) {\n      const token = authHeader.split(' ')[1];\n      req.user = await fxa.verify(token);\n    }\n    if (req.user) {\n      next();\n    } else {\n      res.sendStatus(401);\n    }\n  },\n  dlToken: async function(req, res, next) {\n    const authHeader = req.header('Authorization');\n    if (authHeader && /^Bearer\\s/i.test(authHeader)) {\n      const token = authHeader.split(' ')[1];\n      const id = req.params.id;\n      req.meta = await storage.metadata(id);\n      if (!req.meta || req.meta.dead) {\n        return res.sendStatus(404);\n      }\n      req.authorized = await req.meta.verifyDownloadToken(token);\n    }\n    if (req.authorized) {\n      next();\n    } else {\n      res.sendStatus(401);\n    }\n  }\n};\n"
  },
  {
    "path": "server/middleware/language.js",
    "content": "const { availableLanguages } = require('../../package.json');\nconst config = require('../config');\nconst fs = require('fs');\nconst path = require('path');\nconst { negotiateLanguages } = require('@fluent/langneg');\nconst langData = require('cldr-core/supplemental/likelySubtags.json');\n\n// We return early in the middleware if the lang header is long.\n// If that ever changes we should re-evaluate this regex.\n// eslint-disable-next-line security/detect-unsafe-regex\nconst acceptLanguages = /(([a-zA-Z]+(-[a-zA-Z0-9]+){0,2})|\\*)(;q=[0-1](\\.[0-9]+)?)?/g;\n\nfunction allLangs() {\n  return fs.readdirSync(path.join(__dirname, '..', '..', 'public', 'locales'));\n}\n\nconst languages = config.l10n_dev ? allLangs() : availableLanguages;\n\nmodule.exports = function(req, res, next) {\n  const header = req.headers['accept-language'] || 'en-US';\n  if (header.length > 255) {\n    req.language = 'en-US';\n    return next();\n  }\n  const langs = header.replace(/\\s/g, '').match(acceptLanguages) || ['en-US'];\n  const preferred = langs\n    .map(l => {\n      const parts = l.split(';');\n      return {\n        locale: parts[0],\n        q: parts[1] ? parseFloat(parts[1].split('=')[1]) : 1\n      };\n    })\n    .sort((a, b) => b.q - a.q)\n    .map(x => x.locale);\n  req.language = negotiateLanguages(preferred, languages, {\n    strategy: 'lookup',\n    likelySubtags: langData.supplemental.likelySubtags,\n    defaultLocale: 'en-US'\n  })[0];\n  next();\n};\n"
  },
  {
    "path": "server/readme.md",
    "content": "# Server Code\n\nThe server provides the API, serves static assets, and renders the pages for Send. The production entrypoint is [prod.js](./bin/prod.js) and the development entrypoint is [dev.js](./bin/dev.js) via `webpack-dev-server`.\n\n## Server configuration\n\n[config.js](./config.js) contains the schema for our configuration options. Environment variables are the preferred method for setting configuration.\n\n## Middleware\n\nContains authentication and localization middleware.\n\n## Routes\n\nContains all the server routes and handlers for the API and pages\n\n## Storage\n\nContains implementations of possible storage engines for the files and metadata\n"
  },
  {
    "path": "server/routes/delete.js",
    "content": "const storage = require('../storage');\nconst { statDeleteEvent } = require('../amplitude');\n\nmodule.exports = async function(req, res) {\n  try {\n    const id = req.params.id;\n    const meta = req.meta;\n    const ttl = await storage.ttl(id);\n    await storage.kill(id);\n    res.sendStatus(200);\n    statDeleteEvent({\n      id,\n      ip: req.ip,\n      country: req.geo.country,\n      state: req.geo.state,\n      owner: meta.owner,\n      download_count: meta.dl,\n      ttl,\n      agent: req.ua.browser.name || req.ua.ua.substring(0, 6)\n    });\n  } catch (e) {\n    res.sendStatus(404);\n  }\n};\n"
  },
  {
    "path": "server/routes/done.js",
    "content": "const storage = require('../storage');\nconst { statDownloadEvent } = require('../amplitude');\n\nmodule.exports = async function(req, res) {\n  try {\n    const id = req.params.id;\n    const meta = req.meta;\n    const ttl = await storage.ttl(id);\n    statDownloadEvent({\n      id,\n      ip: req.ip,\n      owner: meta.owner,\n      download_count: meta.dl,\n      ttl,\n      agent: req.ua.browser.name || req.ua.ua.substring(0, 6)\n    });\n    await storage.incrementField(id, 'dl');\n    if (meta.dl + 1 >= meta.dlimit) {\n      // Only dlimit number of tokens will be issued\n      // after which /download/token will return 403\n      // however the protocol doesn't prevent one token\n      // from making all the downloads and assumes\n      // clients are well behaved. If this becomes\n      // a problem we can keep track of used tokens.\n      await storage.kill(id);\n    }\n    res.sendStatus(200);\n  } catch (e) {\n    res.sendStatus(404);\n  }\n};\n"
  },
  {
    "path": "server/routes/download.js",
    "content": "const storage = require('../storage');\n\nmodule.exports = async function(req, res) {\n  const id = req.params.id;\n  try {\n    const { length, stream } = await storage.get(id);\n    res.writeHead(200, {\n      'Content-Type': 'application/octet-stream',\n      'Content-Length': length\n    });\n    stream.pipe(res);\n  } catch (e) {\n    res.sendStatus(404);\n  }\n};\n"
  },
  {
    "path": "server/routes/exists.js",
    "content": "const storage = require('../storage');\n\nmodule.exports = async (req, res) => {\n  try {\n    const meta = await storage.metadata(req.params.id);\n    if (!meta || meta.dead) {\n      return res.sendStatus(404);\n    }\n    res.set('WWW-Authenticate', `send-v1 ${meta.nonce}`);\n    res.send({\n      requiresPassword: meta.pwd\n    });\n  } catch (e) {\n    res.sendStatus(404);\n  }\n};\n"
  },
  {
    "path": "server/routes/filelist.js",
    "content": "const crypto = require('crypto');\nconst config = require('../config');\nconst storage = require('../storage');\nconst Limiter = require('../limiter');\n\nfunction id(user, kid) {\n  const sha = crypto.createHash('sha256');\n  sha.update(user);\n  sha.update(kid);\n  const hash = sha.digest('hex');\n  return `filelist-${hash}`;\n}\n\nmodule.exports = {\n  async get(req, res) {\n    const kid = req.params.id;\n    try {\n      const fileId = id(req.user, kid);\n      const { length, stream } = await storage.get(fileId);\n      res.writeHead(200, {\n        'Content-Type': 'application/octet-stream',\n        'Content-Length': length\n      });\n      stream.pipe(res);\n    } catch (e) {\n      res.sendStatus(404);\n    }\n  },\n\n  async post(req, res) {\n    const kid = req.params.id;\n    try {\n      const limiter = new Limiter(1024 * 1024 * 10);\n      const fileStream = req.pipe(limiter);\n      await storage.set(\n        id(req.user, kid),\n        fileStream,\n        null,\n        config.max_expire_seconds\n      );\n      res.sendStatus(200);\n    } catch (e) {\n      if (e.message === 'limit') {\n        return res.sendStatus(413);\n      }\n      res.sendStatus(500);\n    }\n  }\n};\n"
  },
  {
    "path": "server/routes/index.js",
    "content": "const crypto = require('crypto');\nconst bodyParser = require('body-parser');\nconst helmet = require('helmet');\nconst uaparser = require('ua-parser-js');\nconst storage = require('../storage');\nconst config = require('../config');\nconst auth = require('../middleware/auth');\nconst language = require('../middleware/language');\nconst pages = require('./pages');\nconst filelist = require('./filelist');\nconst clientConstants = require('../clientConstants');\n\nconst IS_DEV = config.env === 'development';\nconst ID_REGEX = '([0-9a-fA-F]{10,16})';\n\nmodule.exports = function(app) {\n  app.set('trust proxy', true);\n  app.use(helmet());\n  app.use(\n    helmet.hsts({\n      maxAge: 31536000,\n      force: !IS_DEV\n    })\n  );\n  app.use(function(req, res, next) {\n    req.ua = uaparser(req.header('user-agent'));\n    next();\n  });\n  app.use(function(req, res, next) {\n    req.cspNonce = crypto.randomBytes(16).toString('hex');\n    next();\n  });\n  if (!IS_DEV) {\n    let csp = {\n      directives: {\n        defaultSrc: [\"'self'\"],\n        connectSrc: [\n          \"'self'\",\n          config.base_url.replace(/^https:\\/\\//, 'wss://')\n        ],\n        imgSrc: [\"'self'\"],\n        scriptSrc: [\n          \"'self'\",\n          function(req) {\n            return `'nonce-${req.cspNonce}'`;\n          }\n        ],\n        formAction: [\"'none'\"],\n        frameAncestors: [\"'none'\"],\n        objectSrc: [\"'none'\"],\n        reportUri: '/__cspreport__'\n      }\n    };\n    if (config.fxa_client_id) {\n      csp.directives.connectSrc.push('https://accounts.firefox.com');\n      csp.directives.connectSrc.push('https://*.accounts.firefox.com');\n      csp.directives.imgSrc.push('https://firefoxusercontent.com');\n      csp.directives.imgSrc.push('https://secure.gravatar.com');\n    }\n    if (config.sentry_id) {\n      csp.directives.connectSrc.push(config.sentry_host);\n    }\n    if (\n      /^https:\\/\\/.*\\.dev\\.lcip\\.org$/.test(config.base_url) ||\n      /^https:\\/\\/.*\\.send\\.nonprod\\.cloudops\\.mozgcp\\.net$/.test(\n        config.base_url\n      )\n    ) {\n      csp.directives.connectSrc.push('https://*.dev.lcip.org');\n      csp.directives.imgSrc.push('https://*.dev.lcip.org');\n    }\n    if (config.fxa_csp_oauth_url != '') {\n      csp.directives.connectSrc.push(config.fxa_csp_oauth_url);\n    }\n    if (config.fxa_csp_content_url != '') {\n      csp.directives.connectSrc.push(config.fxa_csp_content_url);\n    }\n    if (config.fxa_csp_profile_url != '') {\n      csp.directives.connectSrc.push(config.fxa_csp_profile_url);\n    }\n    if (config.fxa_csp_profileimage_url != '') {\n      csp.directives.imgSrc.push(config.fxa_csp_profileimage_url);\n    }\n\n    app.use(helmet.contentSecurityPolicy(csp));\n  }\n\n  app.use(function(req, res, next) {\n    res.set('Pragma', 'no-cache');\n    res.set(\n      'Cache-Control',\n      'private, no-cache, no-store, must-revalidate, max-age=0'\n    );\n    next();\n  });\n  app.use(function(req, res, next) {\n    try {\n      // set by the load balancer\n      const [country, state] = req.header('X-Client-Geo-Location').split(',');\n      req.geo = {\n        country,\n        state\n      };\n    } catch (e) {\n      req.geo = {};\n    }\n    next();\n  });\n  app.use(bodyParser.json());\n  app.use(bodyParser.text());\n  app.get('/', language, pages.index);\n  app.get('/config', function(req, res) {\n    res.json(clientConstants);\n  });\n  app.get('/error', language, pages.blank);\n  app.get('/oauth', language, pages.blank);\n  app.get('/login', language, pages.index);\n  app.get('/report', language, pages.blank);\n  app.get('/app.webmanifest', language, require('./webmanifest'));\n  app.get(`/download/:id${ID_REGEX}`, language, pages.download);\n  app.get('/unsupported/:reason', language, pages.unsupported);\n  app.get(`/api/download/token/:id${ID_REGEX}`, auth.hmac, require('./token'));\n  app.get(`/api/download/:id${ID_REGEX}`, auth.dlToken, require('./download'));\n  app.get(\n    `/api/download/blob/:id${ID_REGEX}`,\n    auth.dlToken,\n    require('./download')\n  );\n  app.post(\n    `/api/download/done/:id${ID_REGEX}`,\n    auth.dlToken,\n    require('./done.js')\n  );\n  app.get(`/api/exists/:id${ID_REGEX}`, require('./exists'));\n  app.get(`/api/metadata/:id${ID_REGEX}`, auth.hmac, require('./metadata'));\n  app.get('/api/filelist/:id([\\\\w-]{16})', auth.fxa, filelist.get);\n  app.post('/api/filelist/:id([\\\\w-]{16})', auth.fxa, filelist.post);\n  // app.post('/api/upload', auth.fxa, require('./upload'));\n  app.post(`/api/delete/:id${ID_REGEX}`, auth.owner, require('./delete'));\n  app.post(`/api/password/:id${ID_REGEX}`, auth.owner, require('./password'));\n  app.post(`/api/params/:id${ID_REGEX}`, auth.owner, require('./params'));\n  app.post(`/api/info/:id${ID_REGEX}`, auth.owner, require('./info'));\n  app.post(`/api/report/:id${ID_REGEX}`, auth.hmac, require('./report'));\n  app.post('/api/metrics', require('./metrics'));\n  app.get('/__version__', function(req, res) {\n    // eslint-disable-next-line node/no-missing-require\n    res.sendFile(require.resolve('../../dist/version.json'));\n  });\n\n  app.get('/__lbheartbeat__', function(req, res) {\n    res.sendStatus(200);\n  });\n\n  app.get('/__heartbeat__', async (req, res) => {\n    try {\n      await storage.ping();\n      res.sendStatus(200);\n    } catch (e) {\n      res.sendStatus(500);\n    }\n  });\n};\n"
  },
  {
    "path": "server/routes/info.js",
    "content": "const storage = require('../storage');\n\nmodule.exports = async function(req, res) {\n  try {\n    const ttl = await storage.ttl(req.params.id);\n    return res.send({\n      dlimit: +req.meta.dlimit,\n      dtotal: +req.meta.dl,\n      ttl\n    });\n  } catch (e) {\n    res.sendStatus(404);\n  }\n};\n"
  },
  {
    "path": "server/routes/metadata.js",
    "content": "const storage = require('../storage');\n\nmodule.exports = async function(req, res) {\n  const id = req.params.id;\n  const meta = req.meta;\n  try {\n    if (meta.dead && !meta.flagged) {\n      return res.sendStatus(404);\n    }\n    const ttl = await storage.ttl(id);\n    res.send({\n      metadata: meta.metadata,\n      flagged: !!meta.flagged,\n      finalDownload: meta.dlToken + 1 === meta.dlimit,\n      ttl\n    });\n  } catch (e) {\n    res.sendStatus(404);\n  }\n};\n"
  },
  {
    "path": "server/routes/metrics.js",
    "content": "const { sendBatch, clientEvent } = require('../amplitude');\n\nmodule.exports = async function(req, res) {\n  try {\n    const data = JSON.parse(req.body); // see http://crbug.com/490015\n    const deltaT = Date.now() - data.now;\n    const events = data.events.map(e =>\n      clientEvent(\n        e,\n        req.ua,\n        data.lang,\n        data.session_id + deltaT,\n        deltaT,\n        data.platform,\n        req.geo.country,\n        req.geo.state\n      )\n    );\n    const status = await sendBatch(events);\n    res.sendStatus(status);\n  } catch (e) {\n    res.sendStatus(500);\n  }\n};\n"
  },
  {
    "path": "server/routes/pages.js",
    "content": "const routes = require('../../app/routes');\nconst storage = require('../storage');\nconst state = require('../state');\n\nfunction stripEvents(str) {\n  // For CSP we need to remove all the event handler placeholders.\n  // It's ok, app.js will add them when it attaches to the DOM.\n  return str.replace(/\\son\\w+=\"\"/g, '');\n}\n\nmodule.exports = {\n  index: async function(req, res) {\n    const appState = await state(req);\n    res.send(stripEvents(routes().toString('/blank', appState)));\n  },\n\n  blank: async function(req, res) {\n    const appState = await state(req);\n    res.send(stripEvents(routes().toString('/blank', appState)));\n  },\n\n  download: async function(req, res, next) {\n    const id = req.params.id;\n    const appState = await state(req);\n    try {\n      const { nonce, pwd, dead, flagged } = await storage.metadata(id);\n      if (dead && !flagged) {\n        return next();\n      }\n      res.set('WWW-Authenticate', `send-v1 ${nonce}`);\n      res.send(\n        stripEvents(\n          routes().toString(\n            `/download/${id}`,\n            Object.assign(appState, {\n              downloadMetadata: { nonce, pwd, flagged }\n            })\n          )\n        )\n      );\n    } catch (e) {\n      next();\n    }\n  },\n\n  unsupported: async function(req, res) {\n    const appState = await state(req);\n    res.send(\n      stripEvents(\n        routes().toString(`/unsupported/${req.params.reason}`, appState)\n      )\n    );\n  },\n\n  notfound: async function(req, res) {\n    const appState = await state(req);\n    res\n      .status(404)\n      .send(\n        stripEvents(\n          routes().toString(\n            '/404',\n            Object.assign(appState, { downloadMetadata: { status: 404 } })\n          )\n        )\n      );\n  }\n};\n"
  },
  {
    "path": "server/routes/params.js",
    "content": "const config = require('../config');\nconst storage = require('../storage');\n\nmodule.exports = function(req, res) {\n  const max = req.meta.fxa ? config.max_downloads : config.anon_max_downloads;\n  const dlimit = req.body.dlimit;\n  if (!dlimit || dlimit > max) {\n    return res.sendStatus(400);\n  }\n\n  try {\n    storage.setField(req.params.id, 'dlimit', dlimit);\n    res.sendStatus(200);\n  } catch (e) {\n    res.sendStatus(404);\n  }\n};\n"
  },
  {
    "path": "server/routes/password.js",
    "content": "const storage = require('../storage');\n\nmodule.exports = function(req, res) {\n  const id = req.params.id;\n  const auth = req.body.auth;\n  if (!auth) {\n    return res.sendStatus(400);\n  }\n\n  try {\n    storage.setField(id, 'auth', auth);\n    storage.setField(id, 'pwd', 1);\n    res.sendStatus(200);\n  } catch (e) {\n    return res.sendStatus(404);\n  }\n};\n"
  },
  {
    "path": "server/routes/report.js",
    "content": "const storage = require('../storage');\nconst { statReportEvent } = require('../amplitude');\n\nmodule.exports = async function(req, res) {\n  try {\n    const id = req.params.id;\n    const meta = await storage.metadata(id);\n    storage.flag(id);\n    statReportEvent({\n      id,\n      ip: req.ip,\n      country: req.geo.country,\n      state: req.geo.state,\n      owner: meta.owner,\n      reason: req.body.reason,\n      download_limit: meta.dlimit,\n      download_count: meta.dl,\n      agent: req.ua.browser.name || req.ua.ua.substring(0, 6)\n    });\n    res.sendStatus(200);\n  } catch (e) {\n    res.sendStatus(404);\n  }\n};\n"
  },
  {
    "path": "server/routes/token.js",
    "content": "module.exports = async function(req, res) {\n  const meta = req.meta;\n  try {\n    if (meta.dead || meta.flagged) {\n      return res.sendStatus(404);\n    }\n    const token = await meta.getDownloadToken();\n    res.send({\n      token\n    });\n  } catch (e) {\n    if (e.message === 'limit') {\n      return res.sendStatus(403);\n    }\n    res.sendStatus(404);\n  }\n};\n"
  },
  {
    "path": "server/routes/upload.js",
    "content": "const crypto = require('crypto');\nconst storage = require('../storage');\nconst config = require('../config');\nconst mozlog = require('../log');\nconst Limiter = require('../limiter');\nconst { encryptedSize } = require('../../app/utils');\n\nconst log = mozlog('send.upload');\n\nmodule.exports = async function(req, res) {\n  const newId = crypto.randomBytes(8).toString('hex');\n  const metadata = req.header('X-File-Metadata');\n  const auth = req.header('Authorization');\n  if (!metadata || !auth) {\n    return res.sendStatus(400);\n  }\n  const owner = crypto.randomBytes(10).toString('hex');\n  const meta = {\n    owner,\n    metadata,\n    auth: auth.split(' ')[1],\n    nonce: crypto.randomBytes(16).toString('base64')\n  };\n\n  try {\n    const limiter = new Limiter(encryptedSize(config.max_file_size));\n    const fileStream = req.pipe(limiter);\n    //this hasn't been updated to expiration time setting yet\n    //if you want to fallback to this code add this\n    await storage.set(newId, fileStream, meta, config.default_expire_seconds);\n    const protocol = config.env === 'production' ? 'https' : req.protocol;\n    const url = `${protocol}://${req.get('host')}/download/${newId}/`;\n    res.set('WWW-Authenticate', `send-v1 ${meta.nonce}`);\n    res.json({\n      url,\n      owner: meta.owner,\n      id: newId\n    });\n  } catch (e) {\n    if (e.message === 'limit') {\n      return res.sendStatus(413);\n    }\n    log.error('upload', e);\n    res.sendStatus(500);\n  }\n};\n"
  },
  {
    "path": "server/routes/webmanifest.js",
    "content": "const assets = require('../../common/assets');\n\nmodule.exports = function(req, res) {\n  const manifest = {\n    name: 'Firefox Send',\n    short_name: 'Send',\n    lang: req.language,\n    icons: [\n      {\n        src: assets.get('android-chrome-192x192.png'),\n        type: 'image/png',\n        sizes: '192x192'\n      },\n      {\n        src: assets.get('android-chrome-512x512.png'),\n        type: 'image/png',\n        sizes: '512x512'\n      }\n    ],\n    start_url: '/',\n    display: 'standalone',\n    orientation: 'portrait',\n    theme_color: '#220033',\n    background_color: 'white'\n  };\n  res.set('Content-Type', 'application/manifest+json');\n  res.json(manifest);\n};\n"
  },
  {
    "path": "server/routes/ws.js",
    "content": "const crypto = require('crypto');\nconst storage = require('../storage');\nconst config = require('../config');\nconst mozlog = require('../log');\nconst Limiter = require('../limiter');\nconst fxa = require('../fxa');\nconst { statUploadEvent } = require('../amplitude');\nconst { encryptedSize } = require('../../app/utils');\n\nconst { Transform } = require('stream');\n\nconst log = mozlog('send.upload');\n\nmodule.exports = function(ws, req) {\n  let fileStream;\n\n  ws.on('close', e => {\n    if (e !== 1000 && fileStream !== undefined) {\n      fileStream.destroy();\n    }\n  });\n\n  ws.once('message', async function(message) {\n    try {\n      const newId = crypto.randomBytes(8).toString('hex');\n      const owner = crypto.randomBytes(10).toString('hex');\n\n      const fileInfo = JSON.parse(message);\n      const timeLimit = fileInfo.timeLimit || config.default_expire_seconds;\n      const dlimit = fileInfo.dlimit || 1;\n      const metadata = fileInfo.fileMetadata;\n      const auth = fileInfo.authorization;\n      const user = await fxa.verify(fileInfo.bearer);\n      const maxFileSize = user\n        ? config.max_file_size\n        : config.anon_max_file_size;\n      const maxExpireSeconds = user\n        ? config.max_expire_seconds\n        : config.anon_max_expire_seconds;\n      const maxDownloads = user\n        ? config.max_downloads\n        : config.anon_max_downloads;\n\n      if (config.fxa_required && !user) {\n        ws.send(\n          JSON.stringify({\n            error: 401\n          })\n        );\n        return ws.close();\n      }\n      if (\n        !metadata ||\n        !auth ||\n        timeLimit <= 0 ||\n        timeLimit > maxExpireSeconds ||\n        dlimit > maxDownloads\n      ) {\n        ws.send(\n          JSON.stringify({\n            error: 400\n          })\n        );\n        return ws.close();\n      }\n\n      const meta = {\n        owner,\n        fxa: user ? 1 : 0,\n        metadata,\n        dlimit,\n        auth: auth.split(' ')[1],\n        nonce: crypto.randomBytes(16).toString('base64')\n      };\n\n      const protocol = config.env === 'production' ? 'https' : req.protocol;\n      const url = `${protocol}://${req.get('host')}/download/${newId}/`;\n\n      ws.send(\n        JSON.stringify({\n          url,\n          ownerToken: meta.owner,\n          id: newId\n        })\n      );\n      const limiter = new Limiter(encryptedSize(maxFileSize));\n      const eof = new Transform({\n        transform: function(chunk, encoding, callback) {\n          if (chunk.length === 1 && chunk[0] === 0) {\n            this.push(null);\n          } else {\n            this.push(chunk);\n          }\n          callback();\n        }\n      });\n      const wsStream = ws.constructor.createWebSocketStream(ws);\n\n      fileStream = wsStream.pipe(eof).pipe(limiter); // limiter needs to be the last in the chain\n\n      await storage.set(newId, fileStream, meta, timeLimit);\n\n      if (ws.readyState === 1) {\n        // if the socket is closed by a cancelled upload the stream\n        // ends without an error so we need to check the state\n        // before sending a reply.\n\n        // TODO: we should handle cancelled uploads differently\n        // in order to avoid having to check socket state and clean\n        // up storage, possibly with an exception that we can catch.\n        ws.send(JSON.stringify({ ok: true }));\n        statUploadEvent({\n          id: newId,\n          ip: req.ip,\n          country: req.geo.country,\n          state: req.geo.state,\n          owner,\n          dlimit,\n          timeLimit,\n          anonymous: !user,\n          size: limiter.length,\n          agent: req.ua.browser.name || req.ua.ua.substring(0, 6)\n        });\n      }\n    } catch (e) {\n      log.error('upload', e);\n      if (ws.readyState === 1) {\n        ws.send(\n          JSON.stringify({\n            error: e === 'limit' ? 413 : 500\n          })\n        );\n      }\n    }\n    ws.close();\n  });\n};\n"
  },
  {
    "path": "server/state.js",
    "content": "const config = require('./config');\nconst layout = require('./layout');\nconst assets = require('../common/assets');\nconst getTranslator = require('./locale');\nconst { getFxaConfig } = require('./fxa');\n\nmodule.exports = async function(req) {\n  const locale = req.language || 'en-US';\n  let authConfig = null;\n  let robots = 'none';\n  if (req.route && req.route.path === '/') {\n    robots = 'all';\n  }\n  if (config.fxa_client_id) {\n    try {\n      authConfig = await getFxaConfig();\n      authConfig.client_id = config.fxa_client_id;\n      authConfig.fxa_required = config.fxa_required;\n    } catch (e) {\n      if (config.auth_required) {\n        throw new Error('fxa_required is set but no config was found');\n      }\n      // continue without accounts\n    }\n  }\n  const prefs = {};\n  if (config.survey_url) {\n    prefs.surveyUrl = config.survey_url;\n  }\n  return {\n    archive: {\n      numFiles: 0\n    },\n    locale,\n    capabilities: { account: false },\n    translate: getTranslator(locale),\n    title: 'Firefox Send',\n    description:\n      'Encrypt and send files with a link that automatically expires to ensure your important documents don’t stay online forever.',\n    baseUrl: config.base_url,\n    ui: {},\n    storage: {\n      files: []\n    },\n    fileInfo: {},\n    cspNonce: req.cspNonce,\n    user: { avatar: assets.get('user.svg'), loggedIn: false },\n    robots,\n    authConfig,\n    prefs,\n    layout\n  };\n};\n"
  },
  {
    "path": "server/storage/fs.js",
    "content": "const fss = require('fs');\nconst fs = fss.promises;\nconst path = require('path');\nconst mkdirp = require('mkdirp');\n\nclass FSStorage {\n  constructor(config, log) {\n    this.log = log;\n    this.dir = config.file_dir;\n    mkdirp.sync(this.dir);\n  }\n\n  async length(id) {\n    const result = await fs.stat(path.join(this.dir, id));\n    return result.size;\n  }\n\n  getStream(id) {\n    return fss.createReadStream(path.join(this.dir, id));\n  }\n\n  set(id, file) {\n    return new Promise((resolve, reject) => {\n      const filepath = path.join(this.dir, id);\n      const fstream = fss.createWriteStream(filepath);\n      file.pipe(fstream);\n      file.on('error', err => {\n        fstream.destroy(err);\n      });\n      fstream.on('error', err => {\n        this.del(id);\n        reject(err);\n      });\n      fstream.on('finish', resolve);\n    });\n  }\n\n  async del(id) {\n    try {\n      await fs.unlink(path.join(this.dir, id));\n    } catch (e) {\n      // ignore local fs issues\n    }\n  }\n\n  ping() {\n    return Promise.resolve();\n  }\n}\n\nmodule.exports = FSStorage;\n"
  },
  {
    "path": "server/storage/gcs.js",
    "content": "const { Storage } = require('@google-cloud/storage');\nconst storage = new Storage();\n\nclass GCSStorage {\n  constructor(config, log) {\n    this.bucket = storage.bucket(config.gcs_bucket);\n    this.log = log;\n  }\n\n  async length(id) {\n    const data = await this.bucket.file(id).getMetadata();\n    return data[0].size;\n  }\n\n  getStream(id) {\n    return this.bucket.file(id).createReadStream({ validation: false });\n  }\n\n  set(id, file) {\n    return new Promise((resolve, reject) => {\n      file\n        .pipe(\n          this.bucket.file(id).createWriteStream({\n            validation: false,\n            resumable: true\n          })\n        )\n        .on('error', reject)\n        .on('finish', resolve);\n    });\n  }\n\n  del(id) {\n    return this.bucket.file(id).delete();\n  }\n\n  ping() {\n    return this.bucket.exists();\n  }\n}\n\nmodule.exports = GCSStorage;\n"
  },
  {
    "path": "server/storage/index.js",
    "content": "const config = require('../config');\nconst Metadata = require('../metadata');\nconst mozlog = require('../log');\nconst createRedisClient = require('./redis');\n\nfunction getPrefix(seconds) {\n  return Math.max(Math.floor(seconds / 86400), 1);\n}\n\nclass DB {\n  constructor(config) {\n    let Storage = null;\n    if (config.s3_bucket) {\n      Storage = require('./s3');\n    } else if (config.gcs_bucket) {\n      Storage = require('./gcs');\n    } else {\n      Storage = require('./fs');\n    }\n    this.log = mozlog('send.storage');\n\n    this.storage = new Storage(config, this.log);\n\n    this.redis = createRedisClient(config);\n    this.redis.on('error', err => {\n      this.log.error('Redis:', err);\n    });\n  }\n\n  async ttl(id) {\n    const result = await this.redis.ttlAsync(id);\n    return Math.ceil(result) * 1000;\n  }\n\n  async getPrefixedInfo(id) {\n    const [prefix, dead, flagged] = await this.redis.hmgetAsync(\n      id,\n      'prefix',\n      'dead',\n      'flagged'\n    );\n    return {\n      filePath: `${prefix}-${id}`,\n      flagged,\n      dead\n    };\n  }\n\n  async length(id) {\n    const { filePath } = await this.getPrefixedInfo(id);\n    return this.storage.length(filePath);\n  }\n\n  async get(id) {\n    const info = await this.getPrefixedInfo(id);\n    if (info.dead || info.flagged) {\n      throw new Error(info.flagged ? 'flagged' : 'dead');\n    }\n    const length = await this.storage.length(info.filePath);\n    return { length, stream: this.storage.getStream(info.filePath) };\n  }\n\n  async set(id, file, meta, expireSeconds = config.default_expire_seconds) {\n    const prefix = getPrefix(expireSeconds);\n    const filePath = `${prefix}-${id}`;\n    await this.storage.set(filePath, file);\n    if (meta) {\n      this.redis.hmset(id, { prefix, ...meta });\n    } else {\n      this.redis.hset(id, 'prefix', prefix);\n    }\n    this.redis.expire(id, expireSeconds);\n  }\n\n  setField(id, key, value) {\n    this.redis.hset(id, key, value);\n  }\n\n  async incrementField(id, key, increment = 1) {\n    return await this.redis.hincrbyAsync(id, key, increment);\n  }\n\n  async kill(id) {\n    const { filePath, dead } = await this.getPrefixedInfo(id);\n    if (!dead) {\n      this.redis.hset(id, 'dead', 1);\n      this.storage.del(filePath);\n    }\n  }\n\n  async flag(id) {\n    await this.kill(id);\n    this.redis.hset(id, 'flagged', 1);\n  }\n\n  async del(id) {\n    const { filePath } = await this.getPrefixedInfo(id);\n    this.redis.del(id);\n    this.storage.del(filePath);\n  }\n\n  async ping() {\n    await this.redis.pingAsync();\n    await this.storage.ping();\n  }\n\n  async metadata(id) {\n    const result = await this.redis.hgetallAsync(id);\n    return result && new Metadata({ id, ...result }, this);\n  }\n}\n\nmodule.exports = new DB(config);\n"
  },
  {
    "path": "server/storage/redis.js",
    "content": "const promisify = require('util').promisify;\n\nmodule.exports = function(config) {\n  const redis_lib =\n    config.env === 'development' && config.redis_host === 'mock'\n      ? 'redis-mock'\n      : 'redis';\n\n  //eslint-disable-next-line security/detect-non-literal-require\n  const redis = require(redis_lib);\n  const client = redis.createClient({\n    host: config.redis_host,\n    retry_strategy: options => {\n      if (options.total_retry_time > config.redis_retry_time) {\n        client.emit('error', 'Retry time exhausted');\n        return new Error('Retry time exhausted');\n      }\n\n      return config.redis_retry_delay;\n    }\n  });\n\n  client.ttlAsync = promisify(client.ttl);\n  client.hgetallAsync = promisify(client.hgetall);\n  client.hgetAsync = promisify(client.hget);\n  client.hincrbyAsync = promisify(client.hincrby);\n  client.hmgetAsync = promisify(client.hmget);\n  client.pingAsync = promisify(client.ping);\n  client.existsAsync = promisify(client.exists);\n  return client;\n};\n"
  },
  {
    "path": "server/storage/s3.js",
    "content": "const AWS = require('aws-sdk');\n\nclass S3Storage {\n  constructor(config, log) {\n    this.bucket = config.s3_bucket;\n    this.log = log;\n    const cfg = {};\n    if (config.s3_endpoint != '') {\n        cfg['endpoint'] = config.s3_endpoint;\n    }\n    cfg['s3ForcePathStyle'] = config.s3_use_path_style_endpoint\n    AWS.config.update(cfg);\n    this.s3 = new AWS.S3();\n  }\n\n  async length(id) {\n    const result = await this.s3\n      .headObject({ Bucket: this.bucket, Key: id })\n      .promise();\n    return Number(result.ContentLength);\n  }\n\n  getStream(id) {\n    return this.s3.getObject({ Bucket: this.bucket, Key: id }).createReadStream();\n  }\n\n  set(id, file) {\n    const upload = this.s3.upload({\n      Bucket: this.bucket,\n      Key: id,\n      Body: file\n    });\n    file.on('error', () => upload.abort());\n    return upload.promise();\n  }\n\n  del(id) {\n    return this.s3.deleteObject({ Bucket: this.bucket, Key: id }).promise();\n  }\n\n  ping() {\n    return this.s3.headBucket({ Bucket: this.bucket }).promise();\n  }\n}\n\nmodule.exports = S3Storage;\n"
  },
  {
    "path": "tailwind.config.js",
    "content": "const colors = {\n  transparent: 'transparent',\n\n  black: '#000000',\n  'grey-90': '#0c0c0d',\n  'grey-80': '#2a2a2e',\n  'grey-70': '#38383d',\n  'grey-60': '#4a4a4f',\n  'grey-50': '#737373',\n  grey: '#b1b1b3',\n  'grey-40': '#b1b1b3',\n  'grey-30': '#d7d7db',\n  'grey-banner': '#f0f0f4',\n  'grey-transparent': 'hsla(250, 13%, 9%, .2)',\n  'grey-20': '#ededf0',\n  'grey-10': '#f9f9fa',\n  white: '#ffffff',\n\n  'red-90': '#3e0200',\n  'red-80': '#5a0002',\n  'red-70': '#a4000f',\n  'red-60': '#d70022',\n  red: '#d70022',\n  'red-50': '#ff0039',\n  // unspec\n  'red-40': '#ff3363',\n  'red-30': '#ff99aa',\n\n  'orange-90': '#3e1300',\n  'orange-80': '#712b00',\n  'orange-70': '#a44900',\n  'orange-60': '#d76e00',\n  'orange-50': '#ff9400',\n  // unspec\n  'orange-40': '#ffb24c',\n  'orange-30': '#ffd399',\n\n  'yellow-90': '#3e2800',\n  'yellow-80': '#715100',\n  'yellow-70': '#a47f00',\n  'yellow-60': '#d7b600',\n  yellow: '#d7b600',\n  'yellow-50': '#ffe900',\n  'yellow-40': '#ffed4c',\n  'yellow-30': '#fff599',\n\n  // 'green-darkest': '#003706',\n  // 'green-darker': '#006504',\n  // 'green-dark': '#058b00',\n  // green: '#12bc00',\n  // 'green-light': '#51d88a',\n  // 'green-lighter': '#a2f5bf',\n  // 'green-lightest': '#e3fcec',\n\n  // 'teal-darkest': '#0d3331',\n  // 'teal-darker': '#20504f',\n  // 'teal-dark': '#38a89d',\n  // teal: '#4dc0b5',\n  // 'teal-light': '#64d5ca',\n  // 'teal-lighter': '#a0f0ed',\n  // 'teal-lightest': '#e8fffe',\n\n  'blue-90': '#000f40',\n  'blue-80': '#002275',\n  'blue-70': '#003eaa',\n  'blue-60': '#0060df',\n  'blue-50': '#0a84ff',\n  blue: '#0a84ff',\n  'blue-40': '#45a1ff',\n  'blue-30': '#99ccff',\n  'blue-20': '#cce6ff',\n\n  'ink-90': '#0f1126',\n  'ink-80': '#202340',\n  'ink-70': '#363959',\n\n  // 'indigo-darkest': '#191e38',\n  // 'indigo-darker': '#2f365f',\n  // 'indigo-dark': '#5661b3',\n  // indigo: '#6574cd',\n  // 'indigo-light': '#7886d7',\n  // 'indigo-lighter': '#b2b7ff',\n  // 'indigo-lightest': '#e6e8ff',\n\n  'purple-90': '#25003e',\n  'purple-80': '#440071',\n  'purple-70': '#6200a4',\n  'purple-60': '#8000d7',\n  'purple-50': '#9400ff',\n  'purple-40': '#ad3bff',\n  'purple-30': '#c069ff',\n  'purple-20': '#d7a3ff',\n\n  // 'pink-darkest': '#451225',\n  // 'pink-darker': '#6f213f',\n  // 'pink-dark': '#eb5286',\n  // pink: '#f66d9b',\n  // 'pink-light': '#fa7ea8',\n  // 'pink-lighter': '#ffbbca',\n  // 'pink-lightest': '#ffebef',\n  cloud: 'rgba(255, 255, 255, 0.8)',\n  violet: 'hsl(258, 57%, 35%)'\n};\n\nmodule.exports = {\n  theme: {\n    colors: colors,\n    screens: {\n      sm: '576px',\n      md: '768px',\n      lg: '992px',\n      xl: '1200px',\n      dark: { raw: '(prefers-color-scheme: dark)' }\n    },\n    fontFamily: {\n      sans: [\n        'Inter',\n        'system-ui',\n        'BlinkMacSystemFont',\n        '-apple-system',\n        'Segoe UI',\n        'Roboto',\n        'Oxygen',\n        'Ubuntu',\n        'Cantarell',\n        'Fira Sans',\n        'Droid Sans',\n        'Helvetica Neue',\n        'sans-serif'\n      ],\n      serif: [\n        'Constantia',\n        'Lucida Bright',\n        'Lucidabright',\n        'Lucida Serif',\n        'Lucida',\n        'DejaVu Serif',\n        'Bitstream Vera Serif',\n        'Liberation Serif',\n        'Georgia',\n        'serif'\n      ],\n      mono: [\n        'Menlo',\n        'Monaco',\n        'Consolas',\n        'Liberation Mono',\n        'Courier New',\n        'monospace'\n      ]\n    },\n    fontSize: {\n      xs: '.75rem', // 12px\n      sm: '.875rem', // 14px\n      base: '1rem', // 16px\n      lg: '1.125rem', // 18px\n      xl: '1.25rem', // 20px\n      '2xl': '1.5rem', // 24px\n      '3xl': '2rem', // 32px\n      '4xl': '2.25rem', // 36px\n      '5xl': '3rem' // 48px\n    },\n    fontWeight: {\n      hairline: 100,\n      thin: 200,\n      light: 300,\n      normal: 400,\n      medium: 500,\n      semibold: 600,\n      bold: 700,\n      extrabold: 800,\n      black: 900\n    },\n    lineHeight: {\n      none: 1,\n      tight: 1.25,\n      normal: 1.5,\n      loose: 1.75\n    },\n    letterSpacing: {\n      tight: '-0.05em',\n      normal: '0',\n      wide: '0.05em'\n    },\n    textColor: colors,\n    backgroundColor: colors,\n    backgroundSize: {\n      auto: 'auto',\n      cover: 'cover',\n      contain: 'contain'\n    },\n    borderWidth: {\n      default: '1px',\n      '0': '0',\n      '2': '2px',\n      '4': '4px',\n      '8': '8px'\n    },\n    borderColor: global.Object.assign({ default: colors['grey-30'] }, colors),\n    borderRadius: {\n      none: '0',\n      sm: '.125rem',\n      default: '.25rem',\n      lg: '.5rem',\n      xl: '1rem',\n      full: '9999px'\n    },\n    width: {\n      auto: 'auto',\n      px: '1px',\n      '0': '0',\n      '1': '0.25rem',\n      '2': '0.5rem',\n      '3': '0.75rem',\n      '4': '1rem',\n      '5': '1.25rem',\n      '6': '1.5rem',\n      '8': '2rem',\n      '10': '2.5rem',\n      '12': '3rem',\n      '16': '4rem',\n      '24': '6rem',\n      '32': '8rem',\n      '48': '12rem',\n      '64': '16rem',\n      '128': '32rem',\n      '1/2': '50%',\n      '1/3': '33.33333%',\n      '2/3': '66.66667%',\n      '1/4': '25%',\n      '3/4': '75%',\n      '1/5': '20%',\n      '2/5': '40%',\n      '3/5': '60%',\n      '4/5': '80%',\n      '1/6': '16.66667%',\n      '5/6': '83.33333%',\n      full: '100%',\n      screen: '100vw'\n    },\n    height: {\n      auto: 'auto',\n      px: '1px',\n      '0': '0',\n      '1': '0.25rem',\n      '2': '0.5rem',\n      '3': '0.75rem',\n      '4': '1rem',\n      '5': '1.25rem',\n      '6': '1.5rem',\n      '8': '2rem',\n      '10': '2.5rem',\n      '12': '3rem',\n      '16': '4rem',\n      '24': '6rem',\n      '32': '8rem',\n      '48': '12rem',\n      '64': '16rem',\n      full: '100%',\n      screen: '100vh'\n    },\n    flex: {\n      '1': '1 1 0%',\n      auto: '1 1 auto',\n      initial: '0 1 auto',\n      none: 'none',\n      half: '0 0 50%',\n      full: '0 0 100%'\n    },\n    minWidth: {\n      '0': '0',\n      full: '100%'\n    },\n    minHeight: {\n      '0': '0',\n      full: '100%',\n      screen: '100vh'\n    },\n    maxWidth: {\n      xs: '20rem',\n      sm: '30rem',\n      md: '40rem',\n      lg: '50rem',\n      xl: '60rem',\n      '2xl': '70rem',\n      '3xl': '80rem',\n      '4xl': '90rem',\n      '5xl': '100rem',\n      full: '100%'\n    },\n    maxHeight: {\n      full: '100%',\n      'half-screen': '50vh',\n      screen: '100vh'\n    },\n    padding: {\n      px: '1px',\n      '0': '0',\n      '1': '0.25rem',\n      '2': '0.5rem',\n      '3': '0.75rem',\n      '4': '1rem',\n      '5': '1.25rem',\n      '6': '1.5rem',\n      '8': '2rem',\n      '10': '2.5rem',\n      '12': '3rem',\n      '16': '4rem',\n      '20': '5rem',\n      '24': '6rem',\n      '32': '8rem'\n    },\n    margin: {\n      auto: 'auto',\n      px: '1px',\n      '0': '0',\n      '1': '0.25rem',\n      '2': '0.5rem',\n      '3': '0.75rem',\n      '4': '1rem',\n      '5': '1.25rem',\n      '6': '1.5rem',\n      '8': '2rem',\n      '10': '2.5rem',\n      '12': '3rem',\n      '16': '4rem',\n      '20': '5rem',\n      '24': '6rem',\n      '32': '8rem',\n      '-px': '-1px',\n      '-1': '-0.25rem',\n      '-2': '-0.5rem',\n      '-3': '-0.75rem',\n      '-4': '-1rem',\n      '-5': '-1.25rem',\n      '-6': '-1.5rem',\n      '-8': '-2rem',\n      '-10': '-2.5rem',\n      '-12': '-3rem',\n      '-16': '-4rem',\n      '-20': '-5rem',\n      '-24': '-6rem',\n      '-32': '-8rem'\n    },\n    boxShadow: {\n      default: '0 2px 4px 0 rgba(0,0,0,0.10)',\n      md: '0 4px 8px 0 rgba(0,0,0,0.12), 0 2px 4px 0 rgba(0,0,0,0.08)',\n      lg: '0 15px 30px 0 rgba(0,0,0,0.11), 0 5px 15px 0 rgba(0,0,0,0.08)',\n      inner: 'inset 0 2px 4px 0 rgba(0,0,0,0.06)',\n      outline: '0 0 0 3px rgba(52,144,220,0.5)',\n      none: 'none',\n      cloud: '0 0 5rem 5rem white',\n      btn:\n        'inset 0 -6px 12px 0 rgba(0,70,144,0.25), 0 4px 6px 0 rgba(34,0,51,0.04), 0 1px 10px 0 rgba(7,48,114,0.12), 0 2px 8px -1px rgba(14,13,26,0.08)'\n    },\n    opacity: {\n      '0': '0',\n      '25': '.25',\n      '50': '.5',\n      '75': '.75',\n      '100': '1'\n    },\n    fill: {\n      current: 'currentColor'\n    },\n    stroke: {\n      current: 'currentColor'\n    },\n\n    zIndex: {\n      auto: 'auto',\n      '0': 0,\n      '10': 10,\n      '20': 20,\n      '30': 30,\n      '40': 40,\n      '50': 50\n    }\n  },\n\n  variants: {\n    appearance: ['responsive'],\n    backgroundAttachment: ['responsive'],\n    backgroundColor: ['responsive', 'hover', 'focus'],\n    backgroundPosition: ['responsive'],\n    backgroundRepeat: ['responsive'],\n    backgroundSize: ['responsive'],\n    borderCollapse: [],\n    borderColor: ['responsive', 'hover', 'focus'],\n    borderRadius: ['responsive'],\n    borderStyle: ['responsive'],\n    borderWidth: ['responsive'],\n    cursor: ['responsive'],\n    display: ['responsive'],\n    flexDirection: ['responsive'],\n    flexWrap: ['responsive'],\n    alignItems: ['responsive'],\n    alignSelf: ['responsive'],\n    alignContent: ['responsive'],\n    justifyContent: ['responsive'],\n    flex: ['responsive'],\n    flexGrow: ['responsive'],\n    flexShrink: ['responsive'],\n    float: ['responsive'],\n    fontFamily: ['responsive'],\n    fontWeight: ['responsive', 'hover', 'focus'],\n    height: ['responsive'],\n    lineHeight: ['responsive'],\n    listStylePosition: ['responsive'],\n    listStyleType: ['responsive'],\n    margin: ['responsive'],\n    maxHeight: ['responsive'],\n    maxWidth: ['responsive'],\n    minHeight: ['responsive'],\n    minWidth: ['responsive'],\n    negativeMargin: ['responsive'],\n    opacity: ['responsive', 'hover'],\n    outline: ['focus'],\n    overflow: ['responsive'],\n    padding: ['responsive'],\n    pointerEvents: ['responsive'],\n    position: ['responsive'],\n    inset: ['responsive'],\n    resize: ['responsive'],\n    boxShadow: ['responsive', 'hover', 'focus'],\n    fill: [],\n    stroke: [],\n    tableLayout: ['responsive'],\n    textAlign: ['responsive'],\n    textColor: ['responsive', 'hover', 'focus'],\n    fontSize: ['responsive'],\n    fontStyle: ['responsive', 'hover', 'focus'],\n    fontSmoothing: ['responsive', 'hover', 'focus'],\n    textDecoration: ['responsive', 'hover', 'focus'],\n    textTransform: ['responsive', 'hover', 'focus'],\n    letterSpacing: ['responsive'],\n    userSelect: ['responsive'],\n    verticalAlign: ['responsive'],\n    visibility: ['responsive'],\n    whitespace: ['responsive'],\n    wordBreak: ['responsive'],\n    width: ['responsive'],\n    zIndex: ['responsive']\n  },\n  corePlugins: {\n    container: false\n  },\n  plugins: []\n};\n"
  },
  {
    "path": "test/.eslintrc.yml",
    "content": "env:\n  mocha: true\n\nextends:\n  - plugin:mocha/recommended\n\nplugins:\n  - mocha\n  - node\n\nrules:\n  node/no-unpublished-require: off\n\n  mocha/handle-done-callback: error\n  mocha/no-exclusive-tests: error\n  mocha/no-identical-title: warn\n  mocha/no-mocha-arrows: error\n  mocha/no-nested-tests: error\n  mocha/no-pending-tests: error\n  mocha/no-return-and-callback: warn\n  mocha/no-skipped-tests: error\n  mocha/no-setup-in-describe: off\n  mocha/no-hooks-for-single-case: off\n\n  no-console: off # ¯\\_(ツ)_/¯\n"
  },
  {
    "path": "test/backend/auth-tests.js",
    "content": "const assert = require('assert');\nconst sinon = require('sinon');\nconst proxyquire = require('proxyquire').noCallThru();\n\nconst storage = {\n  metadata: sinon.stub(),\n  setField: sinon.stub()\n};\n\nfunction request(id, auth) {\n  return {\n    params: { id },\n    header: sinon.stub().returns(auth)\n  };\n}\n\nfunction response() {\n  return {\n    sendStatus: sinon.stub(),\n    set: sinon.stub()\n  };\n}\n\nconst next = sinon.stub();\n\nconst storedMeta = {\n  auth:\n    'r9uFxEs9GEVaQR9CJJ0uTKFGhFSOTRjOY2FCLFlCIZ0Cr-VGTVpMGlXDbNR8RMT55trMpSrzWtBVKq1LffOT2g',\n  nonce: 'FL4oxA7IE1PW8shwFN9qZw=='\n};\n\nconst authMiddleware = proxyquire('../../server/middleware/auth', {\n  '../storage': storage\n}).hmac;\n\ndescribe('Owner Middleware', function() {\n  afterEach(function() {\n    storage.metadata.reset();\n    storage.setField.reset();\n    next.reset();\n  });\n\n  it('sends a 401 when no auth header is set', async function() {\n    const req = request('x');\n    const res = response();\n    await authMiddleware(req, res, next);\n    sinon.assert.calledWith(res.sendStatus, 401);\n    sinon.assert.notCalled(next);\n  });\n\n  it('sends a 404 when metadata is not found', async function() {\n    const req = request('x', 'y');\n    const res = response();\n    await authMiddleware(req, res, next);\n    sinon.assert.calledWith(res.sendStatus, 404);\n    sinon.assert.notCalled(next);\n  });\n\n  it('sends a 401 when the auth header is invalid base64', async function() {\n    storage.metadata.returns(Promise.resolve(storedMeta));\n    const req = request('x', '1');\n    const res = response();\n    await authMiddleware(req, res, next);\n    sinon.assert.calledWith(res.sendStatus, 401);\n    sinon.assert.notCalled(next);\n  });\n\n  it('authenticates when the hashes match', async function() {\n    storage.metadata.returns(Promise.resolve(storedMeta));\n    const req = request(\n      'x',\n      'send-v1 R7nZk14qJqZXtxpnAtw2uDIRQTRnO1qSO1Q0PiwcNA8'\n    );\n    const res = response();\n    await authMiddleware(req, res, next);\n    sinon.assert.calledOnce(next);\n    sinon.assert.calledWith(storage.setField, 'x', 'nonce', req.nonce);\n    sinon.assert.calledWith(\n      res.set,\n      'WWW-Authenticate',\n      `send-v1 ${req.nonce}`\n    );\n    sinon.assert.notCalled(res.sendStatus);\n    assert.equal(req.authorized, true);\n    assert.equal(req.meta, storedMeta);\n    assert.notEqual(req.nonce, storedMeta.nonce);\n  });\n\n  it('sends a 401 when the hashes do not match', async function() {\n    storage.metadata.returns(Promise.resolve(storedMeta));\n    const req = request(\n      'x',\n      'send-v1 R8nZk14qJqZXtxpnAtw2uDIRQTRnO1qSO1Q0PiwcNA8'\n    );\n    const res = response();\n    await authMiddleware(req, res, next);\n    sinon.assert.calledWith(res.sendStatus, 401);\n    sinon.assert.calledWith(\n      res.set,\n      'WWW-Authenticate',\n      `send-v1 ${storedMeta.nonce}`\n    );\n    sinon.assert.notCalled(next);\n  });\n});\n"
  },
  {
    "path": "test/backend/delete-tests.js",
    "content": "const sinon = require('sinon');\nconst proxyquire = require('proxyquire').noCallThru();\n\nconst storage = {\n  kill: sinon.stub(),\n  ttl: sinon.stub()\n};\n\nfunction request(id) {\n  return {\n    params: { id }\n  };\n}\n\nfunction response() {\n  return {\n    sendStatus: sinon.stub()\n  };\n}\n\nconst delRoute = proxyquire('../../server/routes/delete', {\n  '../storage': storage\n});\n\ndescribe('/api/delete', function() {\n  afterEach(function() {\n    storage.kill.reset();\n  });\n\n  it('calls storage.kill with the id parameter', async function() {\n    const req = request('x');\n    const res = response();\n    await delRoute(req, res);\n    sinon.assert.calledWith(storage.kill, 'x');\n    sinon.assert.calledWith(res.sendStatus, 200);\n  });\n\n  it('sends a 404 on failure', async function() {\n    storage.kill.returns(Promise.reject(new Error()));\n    const res = response();\n    await delRoute(request('x'), res);\n    sinon.assert.calledWith(res.sendStatus, 404);\n  });\n});\n"
  },
  {
    "path": "test/backend/info-tests.js",
    "content": "const sinon = require('sinon');\nconst proxyquire = require('proxyquire').noCallThru();\n\nconst storage = {\n  ttl: sinon.stub()\n};\n\nfunction request(id, meta) {\n  return {\n    params: { id },\n    meta\n  };\n}\n\nfunction response() {\n  return {\n    sendStatus: sinon.stub(),\n    send: sinon.stub()\n  };\n}\n\nconst infoRoute = proxyquire('../../server/routes/info', {\n  '../storage': storage\n});\n\ndescribe('/api/info', function() {\n  afterEach(function() {\n    storage.ttl.reset();\n  });\n\n  it('calls storage.ttl with the id parameter', async function() {\n    const req = request('x');\n    const res = response();\n    await infoRoute(req, res);\n    sinon.assert.calledWith(storage.ttl, 'x');\n  });\n\n  it('sends a 404 on failure', async function() {\n    storage.ttl.returns(Promise.reject(new Error()));\n    const res = response();\n    await infoRoute(request('x'), res);\n    sinon.assert.calledWith(res.sendStatus, 404);\n  });\n\n  it('returns a json object', async function() {\n    storage.ttl.returns(Promise.resolve(123));\n    const meta = {\n      dlimit: '1',\n      dl: '0'\n    };\n    const res = response();\n    await infoRoute(request('x', meta), res);\n    sinon.assert.calledWithMatch(res.send, {\n      dlimit: 1,\n      dtotal: 0,\n      ttl: 123\n    });\n  });\n});\n"
  },
  {
    "path": "test/backend/language-tests.js",
    "content": "const assert = require('assert');\nconst sinon = require('sinon');\nconst proxyquire = require('proxyquire').noCallThru();\n\nconst config = {\n  l10n_dev: false // prod configuration\n};\nconst pkg = {\n  availableLanguages: ['en-US', 'fr', 'it', 'es-ES']\n};\n\nfunction request(acceptLang) {\n  return {\n    headers: {\n      'accept-language': acceptLang\n    }\n  };\n}\n\nconst langMiddleware = proxyquire('../../server/middleware/language', {\n  '../config': config,\n  '../../package.json': pkg\n});\n\ndescribe('Language Middleware', function() {\n  it('defaults to en-US when no header is present', function() {\n    const req = request();\n    const next = sinon.stub();\n    langMiddleware(req, null, next);\n    assert.equal(req.language, 'en-US');\n    sinon.assert.calledOnce(next);\n  });\n\n  it('sets req.language to en-US when accept-language > 255 chars', function() {\n    const accept = Array(257).join('a');\n    assert.equal(accept.length, 256);\n    const req = request(accept);\n    const next = sinon.stub();\n    langMiddleware(req, null, next);\n    assert.equal(req.language, 'en-US');\n    sinon.assert.calledOnce(next);\n  });\n\n  it('defaults to en-US when no accept-language is available', function() {\n    const req = request('fa,cs,ja');\n    const next = sinon.stub();\n    langMiddleware(req, null, next);\n    assert.equal(req.language, 'en-US');\n    sinon.assert.calledOnce(next);\n  });\n\n  it('prefers higher q values', function() {\n    const req = request('fa;q=0.5, it;q=0.9');\n    const next = sinon.stub();\n    langMiddleware(req, null, next);\n    assert.equal(req.language, 'it');\n    sinon.assert.calledOnce(next);\n  });\n\n  it('uses likely subtags', function() {\n    const req = request('es-MX');\n    const next = sinon.stub();\n    langMiddleware(req, null, next);\n    assert.equal(req.language, 'es-ES');\n    sinon.assert.calledOn(next);\n  });\n});\n"
  },
  {
    "path": "test/backend/metadata-tests.js",
    "content": "const sinon = require('sinon');\nconst proxyquire = require('proxyquire').noCallThru();\n\nconst storage = {\n  ttl: sinon.stub(),\n  length: sinon.stub()\n};\n\nfunction request(id, meta = {}) {\n  return {\n    params: { id },\n    meta\n  };\n}\n\nfunction response() {\n  return {\n    sendStatus: sinon.stub(),\n    send: sinon.stub()\n  };\n}\n\nconst metadataRoute = proxyquire('../../server/routes/metadata', {\n  '../storage': storage\n});\n\ndescribe('/api/metadata', function() {\n  afterEach(function() {\n    storage.ttl.reset();\n    storage.length.reset();\n  });\n\n  it('calls storage.ttl with the id parameter', async function() {\n    const req = request('x');\n    const res = response();\n    await metadataRoute(req, res);\n    sinon.assert.calledWith(storage.ttl, 'x');\n  });\n\n  it('sends a 404 on failure', async function() {\n    storage.ttl.returns(Promise.reject(new Error()));\n    const res = response();\n    await metadataRoute(request('x'), res);\n    sinon.assert.calledWith(res.sendStatus, 404);\n  });\n\n  it('returns a json object', async function() {\n    storage.ttl.returns(Promise.resolve(123));\n    const meta = {\n      dlimit: 1,\n      dlToken: 0,\n      metadata: 'foo'\n    };\n    const res = response();\n    await metadataRoute(request('x', meta), res);\n    sinon.assert.calledWithMatch(res.send, {\n      metadata: 'foo',\n      finalDownload: true,\n      ttl: 123\n    });\n  });\n});\n"
  },
  {
    "path": "test/backend/owner-tests.js",
    "content": "const assert = require('assert');\nconst sinon = require('sinon');\nconst proxyquire = require('proxyquire').noCallThru();\n\nconst storage = {\n  metadata: sinon.stub()\n};\n\nfunction request(id, owner_token) {\n  return {\n    params: { id },\n    body: { owner_token }\n  };\n}\n\nfunction response() {\n  return {\n    sendStatus: sinon.stub()\n  };\n}\n\nconst ownerMiddleware = proxyquire('../../server/middleware/auth', {\n  '../storage': storage\n}).owner;\n\ndescribe('Owner Middleware', function() {\n  afterEach(function() {\n    storage.metadata.reset();\n  });\n\n  it('sends a 404 when the id is not found', async function() {\n    const next = sinon.stub();\n    storage.metadata.returns(Promise.resolve(null));\n    const res = response();\n    await ownerMiddleware(request('a', 'y'), res, next);\n    sinon.assert.notCalled(next);\n    sinon.assert.calledWith(res.sendStatus, 404);\n  });\n\n  it('sends a 401 when the owner_token is missing', async function() {\n    const next = sinon.stub();\n    const meta = { owner: 'y' };\n    storage.metadata.returns(Promise.resolve(meta));\n    const res = response();\n    await ownerMiddleware(request('b', null), res, next);\n    sinon.assert.notCalled(next);\n    sinon.assert.calledWith(res.sendStatus, 401);\n  });\n\n  it('sends a 401 when the owner_token does not match', async function() {\n    const next = sinon.stub();\n    const meta = { owner: 'y' };\n    storage.metadata.returns(Promise.resolve(meta));\n    const res = response();\n    await ownerMiddleware(request('c', 'z'), res, next);\n    sinon.assert.notCalled(next);\n    sinon.assert.calledWith(res.sendStatus, 401);\n  });\n\n  it('sends a 401 if the metadata call fails', async function() {\n    const next = sinon.stub();\n    storage.metadata.returns(Promise.reject(new Error()));\n    const res = response();\n    await ownerMiddleware(request('d', 'y'), res, next);\n    sinon.assert.notCalled(next);\n    sinon.assert.calledWith(res.sendStatus, 401);\n  });\n\n  it('sets req.meta and req.authorized on successful auth', async function() {\n    const next = sinon.stub();\n    const meta = { owner: 'y' };\n    storage.metadata.returns(Promise.resolve(meta));\n    const req = request('e', 'y');\n    const res = response();\n    await ownerMiddleware(req, res, next);\n    assert.equal(req.meta, meta);\n    assert.equal(req.authorized, true);\n    sinon.assert.notCalled(res.sendStatus);\n    sinon.assert.calledOnce(next);\n  });\n});\n"
  },
  {
    "path": "test/backend/params-tests.js",
    "content": "const sinon = require('sinon');\nconst proxyquire = require('proxyquire').noCallThru();\n\nconst storage = {\n  setField: sinon.stub()\n};\n\nfunction request(id) {\n  return {\n    params: { id },\n    meta: { fxa: false },\n    body: {}\n  };\n}\n\nfunction response() {\n  return {\n    sendStatus: sinon.stub()\n  };\n}\n\nconst paramsRoute = proxyquire('../../server/routes/params', {\n  '../storage': storage\n});\n\ndescribe('/api/params', function() {\n  afterEach(function() {\n    storage.setField.reset();\n  });\n\n  it('calls storage.setField with the correct parameter', function() {\n    const req = request('x');\n    const dlimit = 2;\n    req.body.dlimit = dlimit;\n    const res = response();\n    paramsRoute(req, res);\n    sinon.assert.calledWith(storage.setField, 'x', 'dlimit', dlimit);\n    sinon.assert.calledWith(res.sendStatus, 200);\n  });\n\n  it('sends a 400 if dlimit is too large', function() {\n    const req = request('x');\n    const res = response();\n    req.body.dlimit = 201;\n    paramsRoute(req, res);\n    sinon.assert.calledWith(res.sendStatus, 400);\n  });\n\n  it('sends a 404 on failure', function() {\n    storage.setField.throws(new Error());\n    const req = request('x');\n    const res = response();\n    req.body.dlimit = 2;\n    paramsRoute(req, res);\n    sinon.assert.calledWith(res.sendStatus, 404);\n  });\n});\n"
  },
  {
    "path": "test/backend/password-tests.js",
    "content": "const sinon = require('sinon');\nconst proxyquire = require('proxyquire').noCallThru();\n\nconst storage = {\n  setField: sinon.stub()\n};\n\nfunction request(id, body) {\n  return {\n    params: { id },\n    body\n  };\n}\n\nfunction response() {\n  return {\n    sendStatus: sinon.stub()\n  };\n}\n\nconst passwordRoute = proxyquire('../../server/routes/password', {\n  '../storage': storage\n});\n\ndescribe('/api/password', function() {\n  afterEach(function() {\n    storage.setField.reset();\n  });\n\n  it('calls storage.setField with the correct parameter', function() {\n    const req = request('x', { auth: 'z' });\n    const res = response();\n    passwordRoute(req, res);\n    sinon.assert.calledWith(storage.setField, 'x', 'auth', 'z');\n    sinon.assert.calledWith(storage.setField, 'x', 'pwd', 1);\n    sinon.assert.calledWith(res.sendStatus, 200);\n  });\n\n  it('sends a 400 if auth is missing', function() {\n    const req = request('x', {});\n    const res = response();\n    passwordRoute(req, res);\n    sinon.assert.calledWith(res.sendStatus, 400);\n  });\n\n  it('sends a 404 on failure', function() {\n    storage.setField.throws(new Error());\n    const req = request('x', { auth: 'z' });\n    const res = response();\n    passwordRoute(req, res);\n    sinon.assert.calledWith(res.sendStatus, 404);\n  });\n});\n"
  },
  {
    "path": "test/backend/s3-tests.js",
    "content": "const assert = require('assert');\nconst sinon = require('sinon');\nconst proxyquire = require('proxyquire').noCallThru();\n\nfunction resolvedPromise(val) {\n  return {\n    promise: () => Promise.resolve(val)\n  };\n}\n\nfunction rejectedPromise(err) {\n  return {\n    promise: () => Promise.reject(err)\n  };\n}\n\nconst s3Stub = {\n  headObject: sinon.stub(),\n  getObject: sinon.stub(),\n  upload: sinon.stub(),\n  deleteObject: sinon.stub()\n};\n\nconst awsStub = {\n  config: {\n    update: sinon.stub()\n  },\n  S3: function() {\n    return s3Stub;\n  }\n};\n\nconst S3Storage = proxyquire('../../server/storage/s3', {\n  'aws-sdk': awsStub\n});\n\ndescribe('S3Storage', function() {\n  it('uses config.s3_bucket', function() {\n    const s = new S3Storage({ s3_bucket: 'foo' });\n    assert.equal(s.bucket, 'foo');\n  });\n\n  describe('length', function() {\n    it('returns the ContentLength', async function() {\n      s3Stub.headObject = sinon\n        .stub()\n        .returns(resolvedPromise({ ContentLength: 123 }));\n      const s = new S3Storage({ s3_bucket: 'foo' });\n      const len = await s.length('x');\n      assert.equal(len, 123);\n      sinon.assert.calledWithMatch(s3Stub.headObject, {\n        Bucket: 'foo',\n        Key: 'x'\n      });\n    });\n\n    it('throws when id not found', async function() {\n      const err = new Error();\n      s3Stub.headObject = sinon.stub().returns(rejectedPromise(err));\n      const s = new S3Storage({ s3_bucket: 'foo' });\n      try {\n        await s.length('x');\n        assert.fail();\n      } catch (e) {\n        assert.equal(e, err);\n      }\n    });\n  });\n\n  describe('getStream', function() {\n    it('returns a Stream object', function() {\n      const stream = {};\n      s3Stub.getObject = sinon\n        .stub()\n        .returns({ createReadStream: () => stream });\n      const s = new S3Storage({ s3_bucket: 'foo' });\n      const result = s.getStream('x');\n      assert.equal(result, stream);\n      sinon.assert.calledWithMatch(s3Stub.getObject, {\n        Bucket: 'foo',\n        Key: 'x'\n      });\n    });\n  });\n\n  describe('set', function() {\n    it('calls s3.upload', async function() {\n      const file = { on: sinon.stub() };\n      s3Stub.upload = sinon.stub().returns(resolvedPromise());\n      const s = new S3Storage({ s3_bucket: 'foo' });\n      await s.set('x', file);\n      sinon.assert.calledWithMatch(s3Stub.upload, {\n        Bucket: 'foo',\n        Key: 'x',\n        Body: file\n      });\n    });\n\n    it('aborts upload if limit is hit', async function() {\n      const file = {\n        on: (ev, fn) => fn()\n      };\n      const abort = sinon.stub();\n      const err = new Error('limit');\n      s3Stub.upload = sinon.stub().returns({\n        promise: () => Promise.reject(err),\n        abort\n      });\n      const s = new S3Storage({ s3_bucket: 'foo' });\n      try {\n        await s.set('x', file);\n        assert.fail();\n      } catch (e) {\n        assert.equal(e.message, 'limit');\n        sinon.assert.calledOnce(abort);\n      }\n    });\n\n    it('throws when s3.upload fails', async function() {\n      const file = {\n        on: sinon.stub()\n      };\n      const err = new Error();\n      s3Stub.upload = sinon.stub().returns(rejectedPromise(err));\n      const s = new S3Storage({ s3_bucket: 'foo' });\n      try {\n        await s.set('x', file);\n        assert.fail();\n      } catch (e) {\n        assert.equal(e, err);\n      }\n    });\n  });\n\n  describe('del', function() {\n    it('calls s3.deleteObject', async function() {\n      s3Stub.deleteObject = sinon.stub().returns(resolvedPromise(true));\n      const s = new S3Storage({ s3_bucket: 'foo' });\n      const result = await s.del('x');\n      assert.equal(result, true);\n      sinon.assert.calledWithMatch(s3Stub.deleteObject, {\n        Bucket: 'foo',\n        Key: 'x'\n      });\n    });\n  });\n\n  describe('ping', function() {\n    it('calls s3.headBucket', async function() {\n      s3Stub.headBucket = sinon.stub().returns(resolvedPromise(true));\n      const s = new S3Storage({ s3_bucket: 'foo' });\n      const result = await s.ping();\n      assert.equal(result, true);\n      sinon.assert.calledWithMatch(s3Stub.headBucket, { Bucket: 'foo' });\n    });\n  });\n});\n"
  },
  {
    "path": "test/backend/storage-tests.js",
    "content": "const assert = require('assert');\nconst proxyquire = require('proxyquire').noCallThru();\n\nconst stream = {};\nclass MockStorage {\n  length() {\n    return Promise.resolve(12);\n  }\n  getStream() {\n    return stream;\n  }\n  set() {\n    return Promise.resolve();\n  }\n  del() {\n    return Promise.resolve();\n  }\n  ping() {\n    return Promise.resolve();\n  }\n}\n\nconst config = {\n  s3_bucket: 'foo',\n  default_expire_seconds: 20,\n  expire_times_seconds: [10, 20, 30],\n  env: 'development',\n  redis_host: 'mock'\n};\n\nconst storage = proxyquire('../../server/storage', {\n  '../config': config,\n  '../log': () => {},\n  './s3': MockStorage\n});\n\ndescribe('Storage', function() {\n  describe('ttl', function() {\n    it('returns milliseconds remaining', async function() {\n      const time = 40;\n      await storage.set('x', null, { foo: 'bar' }, time);\n      const ms = await storage.ttl('x');\n      await storage.del('x');\n      assert.equal(ms, time * 1000);\n    });\n  });\n\n  describe('length', function() {\n    it('returns the file size', async function() {\n      const len = await storage.length('x');\n      assert.equal(len, 12);\n    });\n  });\n\n  describe('get', function() {\n    it('returns a stream', async function() {\n      const { stream: s } = await storage.get('x');\n      assert.equal(s, stream);\n    });\n  });\n\n  describe('set', function() {\n    it('sets expiration to expire time', async function() {\n      const seconds = 100;\n      await storage.set('x', null, { foo: 'bar' }, seconds);\n      const s = await storage.redis.ttlAsync('x');\n      await storage.del('x');\n      assert.equal(Math.ceil(s), seconds);\n    });\n\n    it('adds right prefix based on expire time', async function() {\n      await storage.set('x', null, { foo: 'bar' }, 300);\n      const { filePath: path_x } = await storage.getPrefixedInfo('x');\n      assert.equal(path_x, '1-x');\n      await storage.del('x');\n\n      await storage.set('y', null, { foo: 'bar' }, 86400);\n      const { filePath: path_y } = await storage.getPrefixedInfo('y');\n      assert.equal(path_y, '1-y');\n      await storage.del('y');\n\n      await storage.set('z', null, { foo: 'bar' }, 86400 * 7);\n      const { filePath: path_z } = await storage.getPrefixedInfo('z');\n      assert.equal(path_z, '7-z');\n      await storage.del('z');\n    });\n\n    it('sets metadata', async function() {\n      const m = { foo: 'bar' };\n      await storage.set('x', null, m);\n      const meta = await storage.redis.hgetallAsync('x');\n      delete meta.prefix;\n      await storage.del('x');\n      assert.deepEqual(meta, m);\n    });\n  });\n\n  describe('setField', function() {\n    it('works', async function() {\n      await storage.set('x', null);\n      storage.setField('x', 'y', 'z');\n      const z = await storage.redis.hgetAsync('x', 'y');\n      assert.equal(z, 'z');\n      await storage.del('x');\n    });\n  });\n\n  describe('del', function() {\n    it('works', async function() {\n      await storage.set('x', null, { foo: 'bar' });\n      await storage.del('x');\n      const meta = await storage.metadata('x');\n      assert.equal(meta, null);\n    });\n  });\n\n  describe('ping', function() {\n    it('works', async function() {\n      await storage.ping();\n    });\n  });\n\n  describe('metadata', function() {\n    it('returns all metadata fields', async function() {\n      const m = {\n        id: 'a1',\n        pwd: 0,\n        dl: 1,\n        dlimit: 1,\n        fxa: 1,\n        auth: 'foo',\n        metadata: 'bar',\n        nonce: 'baz',\n        owner: 'bmo'\n      };\n      await storage.set('x', null, m);\n      const meta = await storage.metadata('x');\n      assert.deepEqual(\n        { ...meta, storage: 'excluded' },\n        {\n          ...m,\n          dead: false,\n          flagged: false,\n          dlToken: 0,\n          fxa: true,\n          pwd: false,\n          storage: 'excluded'\n        }\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/frontend/.eslintrc.yml",
    "content": "env:\n  browser: true\n\nparserOptions:\n  sourceType: module\n\nrules:\n  node/no-unsupported-features: off"
  },
  {
    "path": "test/frontend/index.js",
    "content": "const fs = require('fs');\nconst path = require('path');\n\nfunction kv(f) {\n  return `require('./tests/${f}')`;\n}\n\nmodule.exports = function() {\n  const files = fs\n    .readdirSync(path.join(__dirname, 'tests'))\n    .filter(p => /\\.js$/.test(p));\n  const code = \"require('fast-text-encoding');\\n\" + files.map(kv).join(';\\n');\n  return {\n    code,\n    dependencies: files.map(f => require.resolve('./tests/' + f)),\n    cacheable: true\n  };\n};\n"
  },
  {
    "path": "test/frontend/routes.js",
    "content": "const html = require('choo/html');\nconst assets = require('../../common/assets');\nconst initScript = require('../../server/initScript');\n\nmodule.exports = function(app) {\n  app.get('/mocha.css', function(req, res) {\n    res.sendFile(require.resolve('mocha/mocha.css'));\n  });\n  app.get('/mocha.js', function(req, res) {\n    res.sendFile(require.resolve('mocha/mocha.js'));\n  });\n  app.get('/test', function(req, res) {\n    res.send(\n      html`\n        <!DOCTYPE html>\n        <html>\n          <head>\n            <link rel=\"stylesheet\" type=\"text/css\" href=\"/mocha.css\" />\n            <script src=\"/mocha.js\"></script>\n            <script>\n              const reporters = mocha.constructor.reporters;\n              function Combo(runner) {\n                reporters.HTML.call(this, runner);\n                reporters.JSON.call(this, runner);\n              }\n              Object.setPrototypeOf(Combo.prototype, reporters.HTML.prototype);\n              mocha.setup({\n                ui: 'bdd',\n                reporter: Combo,\n                timeout: 5000\n              });\n            </script>\n            ${initScript({\n              cspNonce: 'test',\n              locale: 'en-US'\n            })}\n            <script src=\"${assets.get('tests.js')}\"></script>\n          </head>\n          <body>\n            <div id=\"mocha\"></div>\n            <script>\n              window.runner = mocha.run();\n            </script>\n          </body>\n        </html>\n      `.toString()\n    );\n  });\n};\n"
  },
  {
    "path": "test/frontend/runner.js",
    "content": "/* eslint-disable no-undef, no-process-exit */\nconst fs = require('fs');\nconst path = require('path');\nconst mkdirp = require('mkdirp');\nconst puppeteer = require('puppeteer');\nconst webpack = require('webpack');\nconst config = require('../../webpack.config');\nconst middleware = require('webpack-dev-middleware');\nconst express = require('express');\nconst devRoutes = require('../../server/bin/test');\nconst app = express();\n\nconst wpm = middleware(webpack(config(null, { mode: 'development' })), {\n  logLevel: 'silent'\n});\napp.use(wpm);\ndevRoutes(app, { middleware: wpm });\n\n// eslint-disable-next-line no-unused-vars\nfunction onConsole(msg) {\n  // uncomment to debug\n  // console.error(msg.text());\n}\n\nconst server = app.listen(async function() {\n  let exitCode = -1;\n  const browser = await puppeteer.launch({\n    args: [\n      // puppeteer >= 1.10.0 crashes on Circle CI without this flag set\n      '--no-sandbox'\n    ]\n  });\n  try {\n    const page = await browser.newPage();\n    page.on('console', onConsole);\n    page.on('pageerror', console.log.bind(console));\n    await page.goto(`http://127.0.0.1:${server.address().port}/test`);\n    await page.waitFor(() => typeof runner.testResults !== 'undefined', {\n      polling: 1000,\n      timeout: 15000\n    });\n    const results = await page.evaluate(() => runner.testResults);\n    const coverage = await page.evaluate(() => __coverage__);\n    if (coverage) {\n      const dir = path.resolve(__dirname, '../../.nyc_output');\n      mkdirp.sync(dir);\n      fs.writeFileSync(\n        path.resolve(dir, 'frontend.json'),\n        JSON.stringify(coverage)\n      );\n    }\n    const stats = results.stats;\n    exitCode = stats.failures;\n    console.log(`${stats.passes} passing (${stats.duration}ms)\\n`);\n    if (stats.failures) {\n      console.log('Failures:\\n');\n      for (const f of results.failures) {\n        console.log(`${f.fullTitle}`);\n        console.log(` ${f.err.stack}\\n`);\n      }\n    }\n  } catch (e) {\n    console.log(e);\n  } finally {\n    browser.close();\n    server.close(() => {\n      process.exit(exitCode);\n    });\n  }\n});\n"
  },
  {
    "path": "test/frontend/tests/api-tests.js",
    "content": "/* global DEFAULTS */\nimport assert from 'assert';\nimport Archive from '../../../app/archive';\nimport * as api from '../../../app/api';\nimport Keychain from '../../../app/keychain';\n\nconst encoder = new TextEncoder();\nconst plaintext = new Archive([new Blob([encoder.encode('hello world!')])]);\nconst metadata = {\n  name: 'test.txt',\n  type: 'text/plain'\n};\n\ndescribe('API', function() {\n  describe('websocket upload', function() {\n    it('returns file info on success', async function() {\n      const keychain = new Keychain();\n      const enc = await keychain.encryptStream(plaintext.stream);\n      const meta = await keychain.encryptMetadata(metadata);\n      const verifierB64 = await keychain.authKeyB64();\n      const p = function() {};\n      const up = api.uploadWs(\n        enc,\n        meta,\n        verifierB64,\n        DEFAULTS.EXPIRE_SECONDS,\n        1,\n        null,\n        p\n      );\n\n      const result = await up.result;\n      assert.ok(result.url);\n      assert.ok(result.id);\n      assert.ok(result.ownerToken);\n    });\n\n    it('can be cancelled', async function() {\n      const keychain = new Keychain();\n      const enc = await keychain.encryptStream(plaintext.stream);\n      const meta = await keychain.encryptMetadata(metadata);\n      const verifierB64 = await keychain.authKeyB64();\n      const p = function() {};\n      const up = api.uploadWs(\n        enc,\n        meta,\n        verifierB64,\n        DEFAULTS.EXPIRE_SECONDS,\n        null,\n        p\n      );\n\n      up.cancel();\n      try {\n        await up.result;\n        assert.fail('not cancelled');\n      } catch (e) {\n        assert.equal(e.message, '0');\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/frontend/tests/auth-tests.js",
    "content": "import assert from 'assert';\nimport storage from '../../../app/storage';\nimport { decryptBundle, prepareScopedBundleKey } from '../../../app/fxa';\nimport { b64ToArray } from '../../../app/utils';\n\nconst decoder = new TextDecoder();\n\ndescribe('user auth', function() {\n  it('prepares ECDH keys for PKCE auth', async function() {\n    const empty = storage.get('scopedBundlePrivateKey');\n    assert.equal(empty, undefined);\n    const publicKeyB64 = await prepareScopedBundleKey(storage);\n    const publicKey = JSON.parse(decoder.decode(b64ToArray(publicKeyB64)));\n    assert(!publicKey.d, 'not a public key');\n    assert(publicKey.x);\n    assert(publicKey.y);\n    assert.equal(publicKey.kty, 'EC');\n    assert.equal(publicKey.crv, 'P-256');\n\n    const privateKey = JSON.parse(storage.get('scopedBundlePrivateKey'));\n    storage.remove('scopedBundlePrivateKey');\n    assert.equal(privateKey.kty, 'EC');\n    assert.equal(privateKey.crv, 'P-256');\n    assert(privateKey.d, 'not a private key');\n  });\n\n  it('decrypts the PKCE auth bundle', async function() {\n    storage.set(\n      'scopedBundlePrivateKey',\n      '{\"kty\":\"EC\",\"kid\":\"cV9_thVX9XRa-R2nVZF9rFdwrcR_eST4UZuUCx03ebI\",\"crv\":\"P-256\",\"x\":\"-0OOb6SPdYBz0CkQLWRu8ojDUhRe-VoKnwLEBi97KAk\",\"y\":\"U3fXgj1LV7KhiO5O60niMjPpDqToh15-R6C22NnmNXY\",\"d\":\"KfIQCxZrqSI6j69rAC6fEiGIYKwYv2buQG9NTcKOiGc\"}'\n    );\n    const jwks = await decryptBundle(\n      storage,\n      'eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiRUNESC1FUyIsImtpZCI6ImNWOV90aFZYOVhSYS1SMm5WWkY5ckZkd3JjUl9lU1Q0VVp1VUN4MDNlYkkiLCJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJqckcwajNFODNodDZJcDE1YmtuZWRUV3kwZmR1WnR0V3NtMkFybUNoQU5rIiwieSI6Ijl3SmNQUDRrQmQ5amtCbEJJcWRhclQ2NjVIQU00SndUX0FSSFc0aTN4QUUifX0..Dkf-FXtakCiPuXjW.-KfVQEntYjUe3f5OxslSQwjLFauc50RurLQHDV75sUixNTlsjTIldCZVb6WUKpQkpOdFHOUYFX9_Cvk2ENKdfcVm2eTuyomlKklHF3q5209KwJz8lDK3gOQuAlz79eDou0k_Z3JNGu-qZ8IiDhZZ9iNSgBrsq0BZwVXZ9ViSFEW-YzJBQlKmildscXhp_-Lf6-qiJJrPbZCXFD3PZmzcule3kyBOarg_fjjHLFlIpdjP1lI5wBETqdjk7iBKeO2isSQO7-8.q5EzqP6OPg9yb5BcJH2oFg'\n    );\n    assert.deepEqual(jwks, {\n      'https://identity.mozilla.com/apps/send': {\n        kty: 'oct',\n        scope: 'https://identity.mozilla.com/apps/send',\n        k: '5_jrbS76RzJ4EwlKSl527vqz3BDqf5DM4sNsoEK_hoA',\n        kid: '1414456160-n6yE-eL-ADvnsJo_huq3DA'\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/frontend/tests/crypto-tests.js",
    "content": "import assert from 'assert';\nimport { arrayToB64, b64ToArray } from '../../../app/utils';\n\ndescribe('webcrypto', function() {\n  it('can do it', async function() {\n    const encoder = new TextEncoder();\n    const x = b64ToArray('SPIfAlwbnncIFw3hEHYihw');\n    const a = await crypto.subtle.importKey('raw', x, 'PBKDF2', false, [\n      'deriveKey'\n    ]);\n\n    const ad = await crypto.subtle.deriveKey(\n      {\n        name: 'PBKDF2',\n        salt: encoder.encode('metadata'),\n        iterations: 100,\n        hash: 'SHA-256'\n      },\n      a,\n      {\n        name: 'AES-GCM',\n        length: 128\n      },\n      false,\n      ['encrypt', 'decrypt']\n    );\n\n    const ae = await crypto.subtle.encrypt(\n      {\n        name: 'AES-GCM',\n        iv: new Uint8Array(12),\n        tagLength: 128\n      },\n      ad,\n      encoder.encode('hello world!')\n    );\n\n    assert.equal(\n      arrayToB64(new Uint8Array(ae)),\n      'UXQQ4yVf55TRk9AZtz5QCwFofRvh-HdWJyxSCQ'\n    );\n\n    const ah = await crypto.subtle.deriveKey(\n      {\n        name: 'PBKDF2',\n        salt: encoder.encode('authentication'),\n        iterations: 100,\n        hash: 'SHA-256'\n      },\n      a,\n      {\n        name: 'HMAC',\n        hash: { name: 'SHA-256' }\n      },\n      true,\n      ['sign']\n    );\n    const ahx = await crypto.subtle.exportKey('raw', ah);\n    assert.equal(\n      arrayToB64(new Uint8Array(ahx)),\n      'wxXDmHgmMgrcDVD8zbDLRl2yNa8jSAQgsaeIBZ4vueygpxzaTK6ZE_6X-XHvllBly6pSuFNbSxcve0ZHhVdcEA'\n    );\n    // const jwk = await crypto.subtle.exportKey('jwk', ah)\n    // console.error(jwk)\n    const as = await crypto.subtle.sign(\n      {\n        name: 'HMAC'\n      },\n      ah,\n      encoder.encode('test')\n    );\n    assert.equal(\n      arrayToB64(new Uint8Array(as)),\n      'AOi4HcoCJxQ4nUYxlmHB1rlcxQBn-zVjrSHz-VW7S-I'\n    );\n\n    const b = await crypto.subtle.importKey('raw', x, 'HKDF', false, [\n      'deriveKey'\n    ]);\n    const bd = await crypto.subtle.deriveKey(\n      {\n        name: 'HKDF',\n        salt: new Uint8Array(),\n        info: encoder.encode('encryption'),\n        hash: 'SHA-256'\n      },\n      b,\n      {\n        name: 'AES-GCM',\n        length: 128\n      },\n      true,\n      ['encrypt', 'decrypt']\n    );\n    const bdx = await crypto.subtle.exportKey('raw', bd);\n\n    assert.equal(arrayToB64(new Uint8Array(bdx)), 'g7okjWWO9yueDz16-owShQ');\n\n    const bh = await crypto.subtle.deriveKey(\n      {\n        name: 'HKDF',\n        salt: new Uint8Array(),\n        info: encoder.encode('authentication'),\n        hash: 'SHA-256'\n      },\n      b,\n      {\n        name: 'HMAC',\n        hash: { name: 'SHA-256' }\n      },\n      true,\n      ['sign']\n    );\n\n    const bhx = await crypto.subtle.exportKey('raw', bh);\n\n    assert.equal(\n      arrayToB64(new Uint8Array(bhx)),\n      'TQOGtmQ8-ZfnWu6Iq-U1IAVBVREFuI17xqsW1shiC8eMCa-a5qeYTvoX3-5kCoCha8R59ycnPDnTz75clLBmbQ'\n    );\n  });\n});\n"
  },
  {
    "path": "test/frontend/tests/fileSender-tests.js",
    "content": "import assert from 'assert';\nimport FileSender from '../../../app/fileSender';\nimport Archive from '../../../app/archive';\n\n// FileSender uses a File in real life but a Blob works for testing\nconst blob = new Blob(['hello world!'], { type: 'text/plain' });\nblob.name = 'text.txt';\nconst archive = new Archive([blob]);\n\ndescribe('FileSender', function() {\n  describe('upload', function() {\n    it('returns an OwnedFile on success', async function() {\n      const fs = new FileSender();\n      const file = await fs.upload(archive);\n      assert.ok(file.id);\n      assert.equal(file.name, archive.name);\n    });\n  });\n});\n"
  },
  {
    "path": "test/frontend/tests/keychain-tests.js",
    "content": "import assert from 'assert';\nimport Keychain from '../../../app/keychain';\n\ndescribe('Keychain', function() {\n  describe('setPassword', function() {\n    it('changes the authKey', async function() {\n      const k = new Keychain();\n      const original = await k.authKeyB64();\n      k.setPassword('foo', 'some://url');\n      const pwd = await k.authKeyB64();\n      assert.notEqual(pwd, original);\n    });\n  });\n\n  describe('encrypt / decrypt metadata', function() {\n    it('can decrypt metadata it encrypts', async function() {\n      const k = new Keychain();\n      const meta = {\n        name: 'foo',\n        type: 'bar/baz'\n      };\n      const ciphertext = await k.encryptMetadata(meta);\n      const result = await k.decryptMetadata(ciphertext);\n      assert.equal(result.name, meta.name);\n      assert.equal(result.type, meta.type);\n    });\n  });\n});\n"
  },
  {
    "path": "test/frontend/tests/streaming-tests.js",
    "content": "const ece = require('http_ece');\n\nimport assert from 'assert';\nimport Archive from '../../../app/archive';\nimport { b64ToArray } from '../../../app/utils';\nimport { blobStream, concatStream } from '../../../app/streams';\nimport { decryptStream, encryptStream } from '../../../app/ece.js';\nimport { encryptedSize, concat } from '../../../app/utils';\n\nconst rs = 36;\n\nconst str = 'You are the dancing queen, young and sweet, only seventeen.';\nconst testSalt = 'I1BsxtFttlv3u_Oo94xnmw';\nconst keystr = 'yqdlZ-tYemfogSmv7Ws5PQ';\n\nconst buffer = Buffer.from(str);\nconst params = {\n  version: 'aes128gcm',\n  rs: rs,\n  salt: testSalt,\n  keyid: '',\n  key: keystr\n};\n\nconst encrypted = ece.encrypt(buffer, params);\nconst decrypted = ece.decrypt(encrypted, params);\n\ndescribe('Streaming', function() {\n  describe('blobStream', function() {\n    it('reads the entire blob', async function() {\n      const len = 12345;\n      const chunkSize = 1024;\n      const blob = new Blob([new Uint8Array(len)]);\n      const stream = blobStream(blob, chunkSize);\n      const reader = stream.getReader();\n      let bytes = 0;\n      let data = await reader.read();\n      while (!data.done) {\n        bytes += data.value.byteLength;\n        assert.ok(data.value.byteLength <= chunkSize, 'chunk too big');\n        data = await reader.read();\n      }\n      assert.equal(bytes, len);\n    });\n  });\n\n  describe('concatStream', function() {\n    it('reads all the streams', async function() {\n      const count = 5;\n      const len = 12345;\n      const streams = Array.from({ length: count }, () =>\n        blobStream(new Blob([new Uint8Array(len)]))\n      );\n      const concat = concatStream(streams);\n      const reader = concat.getReader();\n      let bytes = 0;\n      let data = await reader.read();\n      while (!data.done) {\n        bytes += data.value.byteLength;\n        data = await reader.read();\n      }\n      assert.equal(bytes, len * count);\n    });\n  });\n\n  //testing against http_ece's implementation\n  describe('ECE', function() {\n    const key = b64ToArray(keystr);\n    const salt = b64ToArray(testSalt).buffer;\n\n    it('can encrypt', async function() {\n      const stream = new Archive([new Blob([str], { type: 'text/plain' })])\n        .stream;\n      const encStream = encryptStream(stream, key, rs, salt);\n      const reader = encStream.getReader();\n\n      let result = new Uint8Array(0);\n\n      let state = await reader.read();\n      while (!state.done) {\n        result = concat(result, state.value);\n        state = await reader.read();\n      }\n\n      assert.deepEqual(result, new Uint8Array(encrypted));\n    });\n\n    it('can decrypt', async function() {\n      const stream = new Archive([new Blob([encrypted])]).stream;\n      const decStream = decryptStream(stream, key, rs);\n\n      const reader = decStream.getReader();\n      let result = new Uint8Array(0);\n\n      let state = await reader.read();\n      while (!state.done) {\n        result = concat(result, state.value);\n        state = await reader.read();\n      }\n      assert.deepEqual(result, new Uint8Array(decrypted));\n    });\n  });\n\n  describe('encryptedSize', function() {\n    it('matches the size of an encrypted buffer', function() {\n      assert.equal(encryptedSize(buffer.length, rs), encrypted.length);\n    });\n  });\n});\n"
  },
  {
    "path": "test/frontend/tests/workflow-tests.js",
    "content": "import assert from 'assert';\nimport Archive from '../../../app/archive';\nimport FileSender from '../../../app/fileSender';\nimport FileReceiver from '../../../app/fileReceiver';\nimport storage from '../../../app/storage';\n\nconst headless = /Headless/.test(navigator.userAgent);\n// TODO: save on headless doesn't work as it used to since it now\n// follows a link instead of fetch. Maybe there's a way to make it\n// work? For now always set noSave.\nconst options = { noSave: true || !headless, stream: true, storage }; // only run the saveFile code if headless\n\n// FileSender uses a File in real life but a Blob works for testing\nconst blob = new Blob([new ArrayBuffer(1024 * 128)], { type: 'text/plain' });\nblob.name = 'test.txt';\nconst archive = new Archive([blob]);\nnavigator.serviceWorker.register('/serviceWorker.js');\n\ndescribe('Upload / Download flow', function() {\n  this.timeout(0);\n  it('can only download once by default', async function() {\n    const fs = new FileSender();\n    const file = await fs.upload(archive);\n    const fr = new FileReceiver({\n      secretKey: file.toJSON().secretKey,\n      id: file.id,\n      nonce: file.keychain.nonce,\n      requiresPassword: false\n    });\n    await fr.getMetadata();\n    await fr.download(options);\n\n    try {\n      await fr.download(options);\n      assert.fail('downloaded again');\n    } catch (e) {\n      assert.equal(e.message, '404');\n    }\n  });\n\n  it('downloads with the correct password', async function() {\n    const fs = new FileSender();\n    const file = await fs.upload(archive);\n    await file.setPassword('magic');\n    const fr = new FileReceiver({\n      secretKey: file.toJSON().secretKey,\n      id: file.id,\n      url: file.url,\n      nonce: file.keychain.nonce,\n      requiresPassword: true,\n      password: 'magic'\n    });\n    await fr.getMetadata();\n    await fr.download(options);\n    assert.equal(fr.state, 'complete');\n  });\n\n  it('blocks invalid passwords from downloading', async function() {\n    const fs = new FileSender();\n    const file = await fs.upload(archive);\n    await file.setPassword('magic');\n    const fr = new FileReceiver({\n      secretKey: file.toJSON().secretKey,\n      id: file.id,\n      url: file.url,\n      nonce: file.keychain.nonce,\n      requiresPassword: true,\n      password: 'password'\n    });\n    try {\n      await fr.getMetadata();\n      assert.fail('got metadata with bad password');\n    } catch (e) {\n      assert.equal(e.message, '401');\n    }\n    try {\n      // We can't decrypt without IV from metadata\n      // but let's try to download anyway\n      await fr.download(options);\n      assert.fail('downloaded file with bad password');\n    } catch (e) {\n      assert.equal(e.message, '401');\n    }\n  });\n\n  it('retries a bad nonce', async function() {\n    const fs = new FileSender();\n    const file = await fs.upload(archive);\n    const fr = new FileReceiver({\n      secretKey: file.toJSON().secretKey,\n      id: file.id,\n      nonce: null, // oops\n      requiresPassword: false\n    });\n    await fr.getMetadata();\n    assert.equal(fr.fileInfo.name, archive.name);\n  });\n\n  it('can cancel the upload', async function() {\n    const fs = new FileSender();\n    const up = fs.upload(archive);\n    fs.cancel(); // before encrypting\n    try {\n      await up;\n      assert.fail('not cancelled 1');\n    } catch (e) {\n      assert.equal(e.message, '0');\n    }\n    fs.reset();\n    fs.once('encrypting', () => fs.cancel());\n    try {\n      await fs.upload(archive);\n      assert.fail('not cancelled 2');\n    } catch (e) {\n      assert.equal(e.message, '0');\n    }\n    fs.reset();\n    fs.once('progress', () => fs.cancel());\n    try {\n      await fs.upload(archive);\n      assert.fail('not cancelled 3');\n    } catch (e) {\n      assert.equal(e.message, '0');\n    }\n  });\n\n  it('can cancel the download', async function() {\n    const fs = new FileSender();\n    const file = await fs.upload(archive);\n    const fr = new FileReceiver({\n      secretKey: file.toJSON().secretKey,\n      id: file.id,\n      nonce: file.keychain.nonce,\n      requiresPassword: false\n    });\n    await fr.getMetadata();\n    fr.once('progress', () => fr.cancel());\n    try {\n      await fr.download(options);\n      assert.fail('not cancelled');\n    } catch (e) {\n      assert.equal(e.message, '0');\n    }\n  });\n\n  it('can increase download count on download', async function() {\n    this.timeout(0);\n    const fs = new FileSender();\n    const file = await fs.upload(archive);\n    const fr = new FileReceiver({\n      secretKey: file.toJSON().secretKey,\n      id: file.id,\n      nonce: file.keychain.nonce,\n      requiresPassword: false\n    });\n    await fr.getMetadata();\n    await fr.download(options);\n    await file.updateDownloadCount();\n    assert.equal(file.dtotal, 1);\n  });\n\n  it('does not increase download count when download cancelled', async function() {\n    const fs = new FileSender();\n    const file = await fs.upload(archive);\n    const fr = new FileReceiver({\n      secretKey: file.toJSON().secretKey,\n      id: file.id,\n      nonce: file.keychain.nonce,\n      requiresPassword: false\n    });\n    await fr.getMetadata();\n    fr.once('progress', () => fr.cancel());\n\n    try {\n      await fr.download(options);\n      assert.fail('not cancelled');\n    } catch (e) {\n      await file.updateDownloadCount();\n      assert.equal(file.dtotal, 0);\n    }\n  });\n\n  it('can allow multiple downloads', async function() {\n    const fs = new FileSender();\n    const a = new Archive([blob]);\n    a.dlimit = 2;\n    const file = await fs.upload(a);\n    const fr = new FileReceiver({\n      secretKey: file.toJSON().secretKey,\n      id: file.id,\n      nonce: file.keychain.nonce,\n      requiresPassword: false\n    });\n    await fr.getMetadata();\n    await fr.download(options);\n    await file.updateDownloadCount();\n    assert.equal(file.dtotal, 1);\n\n    await fr.download(options);\n    await file.updateDownloadCount();\n    assert.equal(file.dtotal, 2);\n    try {\n      await fr.download(options);\n      assert.fail('downloaded too many times');\n    } catch (e) {\n      assert.equal(e.message, '404');\n    }\n  });\n\n  it('can delete the file before download', async function() {\n    const fs = new FileSender();\n    const file = await fs.upload(archive);\n    const fr = new FileReceiver({\n      secretKey: file.toJSON().secretKey,\n      id: file.id,\n      nonce: file.keychain.nonce,\n      requiresPassword: false\n    });\n    await file.del();\n    try {\n      await fr.getMetadata();\n      assert.fail('file still exists');\n    } catch (e) {\n      assert.equal(e.message, '404');\n    }\n  });\n});\n"
  },
  {
    "path": "test/integration/README.md",
    "content": "# Integration Tests for [Firefox Send](https://send.firefox.com/).\n## How to run the tests locally\n### Clone the repository\n\nIf you have cloned this project already then you can skip this, otherwise you'll\nneed to clone this repo using Git. If you do not know how to clone a GitHub\nrepository, check out this [help page][git-clone] from GitHub.\n\nIf you think you would like to contribute to the tests by writing or maintaining\nthem in the future, it would be a good idea to create a fork of this repository\nfirst, and then clone that. GitHub also has great instructions for\n[forking a repository][git-fork].\n\n### App Setup\n\nPlease view the README at the root directory of the project.\n\n### Run the tests\n\nIncluded in the docker-compose file is an image containing Firefox Nightly.\n[tox][Tox] is our test environment manager and [pytest][pytest] is the test runner.\n\nTo run the tests, execute the commands below:\n```sh\nnpm run build\nnpm run test-integration\n```\n\n### Adding a test\n\nThe tests are written in Python using a POM, or Page Object Model. The plugin we use for this is called [pypom][pypom]. Please read the documentation there for good examples on how to use the Page Object Model when writing tests.\n\nThe pytest plugin that we use for running tests has a number of advanced command line options available too. The full documentation for the plugin can be found [here][pytest-selenium].\n\n### Watching a test run (within the docker container)\n\nThe tests are run on a live version of Firefox, but they are run headless. To access the container where the tests are run to view them follow these steps:\n\n1. Make sure all of the containers are running:\n```sh\ndocker-compose ps\n```\nIf not start them detached:\n```sh\ndocker-compose up -d\n```\n\n2. Open your favorite VNC viewer and type in `localhost:5900`.\n3. The password is ```secret```.\n4. The viewer should open a window with a Ubuntu logo. If that happens you are connected to the ```selenium-firefox``` image and if you start the test, you should see a Firefox window open and the tests running.\n\n### Debugging a failure\n\nWhether a test passes or fails will result in a HTML report being created. This report will have detailed information of the test run and if a test does fail, it will provide geckodriver logs, terminal logs, as well as a screenshot of the browser when the test failed. We use a pytest plugin called [pytest-html][pytest-html] to create this report. The report can be found at ```coverage/send-test.html```. It should be viewed within a browser.\n\n[flake8]: http://flake8.pycqa.org/en/latest/\n[git-clone]: https://help.github.com/articles/cloning-a-repository/\n[git-fork]: https://help.github.com/articles/fork-a-repo/\n[geckodriver]: https://github.com/mozilla/geckodriver/releases/tag/v0.19.1\n[pypom]: http://pypom.readthedocs.io/en/latest/\n[pytest]: https://docs.pytest.org/en/latest/\n[pytest-html]: https://github.com/pytest-dev/pytest-html\n[pytest-selenium]: http://pytest-selenium.readthedocs.org/\n[Selenium]: http://selenium-python.readthedocs.io/index.html\n[selenium-api]: http://selenium-python.readthedocs.io/locating-elements.html\n[Tox]: http://tox.readthedocs.io/\n"
  },
  {
    "path": "test/integration/download-tests.js",
    "content": "/* global browser */\nconst assert = require('assert');\nconst fs = require('fs');\nconst path = require('path');\n\nconst DownloadPage = require('./pages/desktop/download_page');\nconst HomePage = require('./pages/desktop/home_page');\n\ndescribe('Firefox Send', function() {\n  const homePage = new HomePage();\n  const downloadDir =\n    browser.desiredCapabilities['moz:firefoxOptions']['prefs'][\n      'browser.download.dir'\n    ];\n  const testFilesPath = path.join(__dirname, 'fixtures');\n  const testFiles = fs.readdirSync(testFilesPath);\n\n  beforeEach(function() {\n    homePage.open();\n  });\n\n  testFiles.forEach(file => {\n    it(`should upload and download files, file: ${file}`, function() {\n      browser.chooseFile(homePage.uploadInput, `${testFilesPath}/${file}`);\n      browser.waitForExist(homePage.uploadButton);\n      browser.click(homePage.uploadButton);\n      browser.waitForExist(homePage.shareUrl);\n      const downloadPage = new DownloadPage(\n        browser.getValue(homePage.shareUrl)\n      );\n      downloadPage.open();\n      downloadPage.download();\n      browser.waitForExist(downloadPage.downloadComplete);\n      assert.ok(fs.existsSync(path.join(downloadDir, file)));\n    });\n  });\n\n  it('should update the download count on home page after 1 download', function() {\n    browser.chooseFile(\n      homePage.uploadInput,\n      `${testFilesPath}/${testFiles[0]}`\n    );\n    browser.waitForExist(homePage.uploadButton);\n    browser.waitForExist(homePage.downloadCountSelect);\n    browser.selectByIndex(homePage.downloadCountSelect, 1);\n    browser.click(homePage.uploadButton);\n    browser.waitForExist(homePage.shareUrl);\n    const downloadPage = new DownloadPage(browser.getValue(homePage.shareUrl));\n    downloadPage.open();\n    downloadPage.download();\n    browser.waitForExist(downloadPage.downloadComplete);\n    browser.back();\n    browser.waitForExist('send-archive');\n    assert(\n      browser\n        .getText('send-archive > div:first-of-type')\n        .includes('Expires after 1 download')\n    );\n  });\n\n  it('should ensure that the downloaded file size matches the uploaded file size', function() {\n    browser.chooseFile(\n      homePage.uploadInput,\n      `${testFilesPath}/${testFiles[0]}`\n    );\n    // get the file size for upload\n    const uploadSize = fs.statSync(`${testFilesPath}/${testFiles[0]}`).size;\n\n    browser.waitForExist(homePage.uploadButton);\n    browser.click(homePage.uploadButton);\n\n    browser.waitForExist(homePage.shareUrl);\n    const downloadPage = new DownloadPage(browser.getValue(homePage.shareUrl));\n    downloadPage.open();\n    downloadPage.download();\n    browser.waitForExist(downloadPage.downloadComplete);\n\n    // get the file size for download\n    const downloadFile = path.join(downloadDir, `${testFiles[0]}`);\n    const downloadSize = fs.statSync(downloadFile).size;\n\n    // check if upload and download file sizes are equal\n    assert.equal(uploadSize, downloadSize);\n  });\n\n  it(`should upload and download file with added tracking parameter`, function() {\n    const trackingUrl =\n      '?fbclid=IaMFak3Tr4ck1ng1d_SDlP0shBk8SM2EN3cCLFKpHVl-k-Pvv0sf9Zy0tnTu9srqVY';\n    const password = 'strongpassword';\n\n    browser.chooseFile(\n      homePage.uploadInput,\n      `${testFilesPath}/${testFiles[0]}`\n    );\n    browser.waitForExist(homePage.addPassword);\n    browser.click(homePage.addPassword);\n    browser.waitForExist(homePage.passwordInput);\n    browser.setValue(homePage.passwordInput, password);\n    browser.click(homePage.uploadButton);\n    browser.waitForExist(homePage.shareUrl);\n    const shareUrl = browser.getValue(homePage.shareUrl);\n    const downloadPage = new DownloadPage(\n      shareUrl.replace('#', `${trackingUrl}#`)\n    );\n    downloadPage.open();\n    downloadPage.downloadUsingPassword(password);\n    browser.waitForExist(downloadPage.downloadComplete);\n    assert.ok(fs.existsSync(path.join(downloadDir, testFiles[0])));\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/txt-larger-testfile.txt",
    "content": "THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!THIS IS A TEST!\n"
  },
  {
    "path": "test/integration/fixtures/txt-small-testfile.txt",
    "content": "THIS IS A TEST!\n"
  },
  {
    "path": "test/integration/homepage-tests.js",
    "content": "/* global browser */\nconst assert = require('assert');\nconst HomePage = require('./pages/desktop/home_page');\n\ndescribe('Firefox Send homepage', function() {\n  this.retries(2);\n  const homePage = new HomePage();\n  const baseUrl = browser.options['baseUrl'];\n  const footerLinks = ['mozilla', 'cookies', 'github'];\n\n  beforeEach(function() {\n    homePage.open();\n    if (process.env.ANDROID) {\n      this.skip();\n    }\n  });\n\n  it('should have the right title', function() {\n    assert.equal(browser.getTitle(), 'Firefox Send');\n  });\n\n  footerLinks.forEach((link, i) => {\n    it(`should navigate to the correct page: ${link}`, function() {\n      // Click links on bottom of page\n      const els = browser.elements(homePage.footerLinks);\n      browser.elementIdClick(els.value[i].ELEMENT);\n      // Wait for page to load\n      browser.waitUntil(() => {\n        const url = browser.getUrl();\n        return url !== baseUrl;\n      });\n      assert.ok(browser.getUrl().includes(link));\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/pages/desktop/download_page.js",
    "content": "/* global browser */\nconst Page = require('./page');\n\nclass DownloadPage extends Page {\n  constructor(path) {\n    super(path);\n    this.fileId = /download\\/(\\w+)\\/\\??.*#/.exec(path)[1];\n    this.downloadButton = '#download-btn';\n    this.downloadComplete = '#download-complete';\n    this.passwordInput = '#password-input';\n    this.passwordButton = '#password-btn';\n  }\n\n  downloadUsingPassword(password) {\n    browser.waitForExist(this.passwordInput);\n    browser.setValue(this.passwordInput, password);\n    browser.click(this.passwordButton);\n    return browser.click(this.downloadButton);\n  }\n\n  download() {\n    browser.waitForExist(this.downloadButton);\n    return browser.click(this.downloadButton);\n  }\n}\nmodule.exports = DownloadPage;\n"
  },
  {
    "path": "test/integration/pages/desktop/home_page.js",
    "content": "/* global browser document */\nconst Page = require('./page');\n\nclass HomePage extends Page {\n  constructor() {\n    super('/');\n    this.footerLinks = 'footer a';\n    this.uploadInput = '#file-upload';\n    this.uploadButton = '#upload-btn';\n    this.progress = 'progress';\n    this.shareUrl = '#share-url';\n    this.downloadCountSelect = '#expire-after-dl-count-select';\n    this.addPassword = '#add-password';\n    this.passwordInput = '#password-input';\n    this.passwordButton = '#password-btn';\n  }\n\n  waitForPageToLoad() {\n    super.waitForPageToLoad();\n    browser.waitForExist(this.uploadInput);\n    this.showUploadInput();\n    return this;\n  }\n\n  showUploadInput() {\n    browser.execute(() => {\n      document.getElementById('file-upload').style.display = 'block';\n    });\n  }\n}\nmodule.exports = HomePage;\n"
  },
  {
    "path": "test/integration/pages/desktop/page.js",
    "content": "/* global browser window */\nclass Page {\n  constructor(path) {\n    this.path = path;\n  }\n\n  open() {\n    browser.url(this.path);\n    this.waitForPageToLoad();\n  }\n\n  /**\n   * @function waitForPageToLoad\n   * @returns {Object} An object representing the page.\n   * @throws ElementNotFound\n   */\n  waitForPageToLoad() {\n    browser.waitUntil(function() {\n      return browser.execute(function() {\n        return typeof window.app !== 'undefined';\n      });\n    }, 3000);\n    browser.pause(100);\n    return this;\n  }\n}\nmodule.exports = Page;\n"
  },
  {
    "path": "test/integration/progress-tests.js",
    "content": "/* global browser */\nconst assert = require('assert');\nconst HomePage = require('./pages/desktop/home_page');\n\ndescribe('Firefox Send progress page', function() {\n  const homePage = new HomePage();\n  beforeEach(function() {\n    homePage.open();\n  });\n\n  it('should show progress when a file is uploading', function() {\n    browser.chooseFile(homePage.uploadInput, __filename);\n    browser.waitForExist(homePage.uploadButton);\n    browser.click(homePage.uploadButton);\n\n    assert.ok(browser.waitForExist(homePage.progress));\n  });\n});\n"
  },
  {
    "path": "test/integration/send-test.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\"/>\n    <title>Test Report</title>\n    <style>body {\n\tfont-family: Helvetica, Arial, sans-serif;\n\tfont-size: 12px;\n\tmin-width: 1200px;\n\tcolor: #999;\n}\n\nh1 {\n\tfont-size: 24px;\n\tcolor: black;\n}\n\nh2 {\n\tfont-size: 16px;\n\tcolor: black;\n}\n\np {\n    color: black;\n}\n\na {\n\tcolor: #999;\n}\n\ntable {\n\tborder-collapse: collapse;\n}\n\n/******************************\n * SUMMARY INFORMATION\n ******************************/\n\n#environment td {\n\tpadding: 5px;\n\tborder: 1px solid #E6E6E6;\n}\n\n#environment tr:nth-child(odd) {\n\tbackground-color: #f6f6f6;\n}\n\n/******************************\n * TEST RESULT COLORS\n ******************************/\nspan.passed, .passed .col-result {\n\tcolor: green;\n}\nspan.skipped, span.xfailed, span.rerun, .skipped .col-result, .xfailed .col-result, .rerun .col-result {\n\tcolor: orange;\n}\nspan.error, span.failed, span.xpassed, .error .col-result, .failed .col-result, .xpassed .col-result  {\n\tcolor: red;\n}\n\n\n/******************************\n * RESULTS TABLE\n *\n * 1. Table Layout\n * 2. Extra\n * 3. Sorting items\n *\n ******************************/\n\n/*------------------\n * 1. Table Layout\n *------------------*/\n\n#results-table {\n\tborder: 1px solid #e6e6e6;\n\tcolor: #999;\n\tfont-size: 12px;\n\twidth: 100%\n}\n\n#results-table th, #results-table td {\n\tpadding: 5px;\n\tborder: 1px solid #E6E6E6;\n\ttext-align: left\n}\n#results-table th {\n\tfont-weight: bold\n}\n\n/*------------------\n * 2. Extra\n *------------------*/\n\n.log:only-child {\n\theight: inherit\n}\n.log {\n\tbackground-color: #e6e6e6;\n\tborder: 1px solid #e6e6e6;\n\tcolor: black;\n\tdisplay: block;\n\tfont-family: \"Courier New\", Courier, monospace;\n\theight: 230px;\n\toverflow-y: scroll;\n\tpadding: 5px;\n\twhite-space: pre-wrap\n}\ndiv.image {\n\tborder: 1px solid #e6e6e6;\n\tfloat: right;\n\theight: 240px;\n\tmargin-left: 5px;\n\toverflow: hidden;\n\twidth: 320px\n}\ndiv.image img {\n\twidth: 320px\n}\n.collapsed {\n\tdisplay: none;\n}\n.expander::after {\n\tcontent: \" (show details)\";\n\tcolor: #BBB;\n\tfont-style: italic;\n\tcursor: pointer;\n}\n.collapser::after {\n\tcontent: \" (hide details)\";\n\tcolor: #BBB;\n\tfont-style: italic;\n\tcursor: pointer;\n}\n\n/*------------------\n * 3. Sorting items\n *------------------*/\n.sortable {\n\tcursor: pointer;\n}\n\n.sort-icon {\n\tfont-size: 0px;\n\tfloat: left;\n\tmargin-right: 5px;\n\tmargin-top: 5px;\n\t/*triangle*/\n\twidth: 0;\n\theight: 0;\n\tborder-left: 8px solid transparent;\n\tborder-right: 8px solid transparent;\n}\n\n.inactive .sort-icon {\n\t/*finish triangle*/\n\tborder-top: 8px solid #E6E6E6;\n}\n\n.asc.active .sort-icon {\n\t/*finish triangle*/\n\tborder-bottom: 8px solid #999;\n}\n\n.desc.active .sort-icon {\n\t/*finish triangle*/\n\tborder-top: 8px solid #999;\n}\n</style></head>\n  <body onLoad=\"init()\">\n    <script>/* This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this file,\n * You can obtain one at http://mozilla.org/MPL/2.0/. */\n\n\nfunction toArray(iter) {\n    if (iter === null) {\n        return null;\n    }\n    return Array.prototype.slice.call(iter);\n}\n\nfunction find(selector, elem) {\n    if (!elem) {\n        elem = document;\n    }\n    return elem.querySelector(selector);\n}\n\nfunction find_all(selector, elem) {\n    if (!elem) {\n        elem = document;\n    }\n    return toArray(elem.querySelectorAll(selector));\n}\n\nfunction sort_column(elem) {\n    toggle_sort_states(elem);\n    var colIndex = toArray(elem.parentNode.childNodes).indexOf(elem);\n    var key;\n    if (elem.classList.contains('numeric')) {\n        key = key_num;\n    } else if (elem.classList.contains('result')) {\n        key = key_result;\n    } else {\n        key = key_alpha;\n    }\n    sort_table(elem, key(colIndex));\n}\n\nfunction show_all_extras() {\n    find_all('.col-result').forEach(show_extras);\n}\n\nfunction hide_all_extras() {\n    find_all('.col-result').forEach(hide_extras);\n}\n\nfunction show_extras(colresult_elem) {\n    var extras = colresult_elem.parentNode.nextElementSibling;\n    var expandcollapse = colresult_elem.firstElementChild;\n    extras.classList.remove(\"collapsed\");\n    expandcollapse.classList.remove(\"expander\");\n    expandcollapse.classList.add(\"collapser\");\n}\n\nfunction hide_extras(colresult_elem) {\n    var extras = colresult_elem.parentNode.nextElementSibling;\n    var expandcollapse = colresult_elem.firstElementChild;\n    extras.classList.add(\"collapsed\");\n    expandcollapse.classList.remove(\"collapser\");\n    expandcollapse.classList.add(\"expander\");\n}\n\nfunction show_filters() {\n    var filter_items = document.getElementsByClassName('filter');\n    for (var i = 0; i < filter_items.length; i++)\n        filter_items[i].hidden = false;\n}\n\nfunction add_collapse() {\n    // Add links for show/hide all\n    var resulttable = find('table#results-table');\n    var showhideall = document.createElement(\"p\");\n    showhideall.innerHTML = '<a href=\"javascript:show_all_extras()\">Show all details</a> / ' +\n                            '<a href=\"javascript:hide_all_extras()\">Hide all details</a>';\n    resulttable.parentElement.insertBefore(showhideall, resulttable);\n\n    // Add show/hide link to each result\n    find_all('.col-result').forEach(function(elem) {\n        var collapsed = get_query_parameter('collapsed') || 'Passed';\n        var extras = elem.parentNode.nextElementSibling;\n        var expandcollapse = document.createElement(\"span\");\n        if (collapsed.includes(elem.innerHTML)) {\n            extras.classList.add(\"collapsed\");\n            expandcollapse.classList.add(\"expander\");\n        } else {\n            expandcollapse.classList.add(\"collapser\");\n        }\n        elem.appendChild(expandcollapse);\n\n        elem.addEventListener(\"click\", function(event) {\n            if (event.currentTarget.parentNode.nextElementSibling.classList.contains(\"collapsed\")) {\n                show_extras(event.currentTarget);\n            } else {\n                hide_extras(event.currentTarget);\n            }\n        });\n    })\n}\n\nfunction get_query_parameter(name) {\n    var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);\n    return match && decodeURIComponent(match[1].replace(/\\+/g, ' '));\n}\n\nfunction init () {\n    reset_sort_headers();\n\n    add_collapse();\n\n    show_filters();\n\n    toggle_sort_states(find('.initial-sort'));\n\n    find_all('.sortable').forEach(function(elem) {\n        elem.addEventListener(\"click\",\n                              function(event) {\n                                  sort_column(elem);\n                              }, false)\n    });\n\n};\n\nfunction sort_table(clicked, key_func) {\n    var rows = find_all('.results-table-row');\n    var reversed = !clicked.classList.contains('asc');\n    var sorted_rows = sort(rows, key_func, reversed);\n    /* Whole table is removed here because browsers acts much slower\n     * when appending existing elements.\n     */\n    var thead = document.getElementById(\"results-table-head\");\n    document.getElementById('results-table').remove();\n    var parent = document.createElement(\"table\");\n    parent.id = \"results-table\";\n    parent.appendChild(thead);\n    sorted_rows.forEach(function(elem) {\n        parent.appendChild(elem);\n    });\n    document.getElementsByTagName(\"BODY\")[0].appendChild(parent);\n}\n\nfunction sort(items, key_func, reversed) {\n    var sort_array = items.map(function(item, i) {\n        return [key_func(item), i];\n    });\n    var multiplier = reversed ? -1 : 1;\n\n    sort_array.sort(function(a, b) {\n        var key_a = a[0];\n        var key_b = b[0];\n        return multiplier * (key_a >= key_b ? 1 : -1);\n    });\n\n    return sort_array.map(function(item) {\n        var index = item[1];\n        return items[index];\n    });\n}\n\nfunction key_alpha(col_index) {\n    return function(elem) {\n        return elem.childNodes[1].childNodes[col_index].firstChild.data.toLowerCase();\n    };\n}\n\nfunction key_num(col_index) {\n    return function(elem) {\n        return parseFloat(elem.childNodes[1].childNodes[col_index].firstChild.data);\n    };\n}\n\nfunction key_result(col_index) {\n    return function(elem) {\n        var strings = ['Error', 'Failed', 'Rerun', 'XFailed', 'XPassed',\n                       'Skipped', 'Passed'];\n        return strings.indexOf(elem.childNodes[1].childNodes[col_index].firstChild.data);\n    };\n}\n\nfunction reset_sort_headers() {\n    find_all('.sort-icon').forEach(function(elem) {\n        elem.parentNode.removeChild(elem);\n    });\n    find_all('.sortable').forEach(function(elem) {\n        var icon = document.createElement(\"div\");\n        icon.className = \"sort-icon\";\n        icon.textContent = \"vvv\";\n        elem.insertBefore(icon, elem.firstChild);\n        elem.classList.remove(\"desc\", \"active\");\n        elem.classList.add(\"asc\", \"inactive\");\n    });\n}\n\nfunction toggle_sort_states(elem) {\n    //if active, toggle between asc and desc\n    if (elem.classList.contains('active')) {\n        elem.classList.toggle('asc');\n        elem.classList.toggle('desc');\n    }\n\n    //if inactive, reset all other functions and add ascending active\n    if (elem.classList.contains('inactive')) {\n        reset_sort_headers();\n        elem.classList.remove('inactive');\n        elem.classList.add('active');\n    }\n}\n\nfunction is_all_rows_hidden(value) {\n  return value.hidden == false;\n}\n\nfunction filter_table(elem) {\n    var outcome_att = \"data-test-result\";\n    var outcome = elem.getAttribute(outcome_att);\n    class_outcome = outcome + \" results-table-row\";\n    var outcome_rows = document.getElementsByClassName(class_outcome);\n\n    for(var i = 0; i < outcome_rows.length; i++){\n        outcome_rows[i].hidden = !elem.checked;\n    }\n\n    var rows = find_all('.results-table-row').filter(is_all_rows_hidden);\n    var all_rows_hidden = rows.length == 0 ? true : false;\n    var not_found_message = document.getElementById(\"not-found-message\");\n    not_found_message.hidden = !all_rows_hidden;\n}\n</script>\n    <h1>send-test.html</h1>\n    <p>Report generated on 14-Jun-2018 at 14:20:27 by<a href=\"https://pypi.python.org/pypi/pytest-html\"> pytest-html</a> v1.19.0</p>\n    <h2>Environment</h2>\n    <table id=\"environment\">\n      <tr>\n        <td>Base URL</td>\n        <td><a href=\"http://localhost:1443\" target=\"_blank\">http://localhost:1443</a></td></tr>\n      <tr>\n        <td>Driver</td>\n        <td>Firefox</td></tr>\n      <tr>\n        <td>JAVA_HOME</td>\n        <td>/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home</td></tr>\n      <tr>\n        <td>Packages</td>\n        <td>{&apos;pytest&apos;: &apos;3.6.1&apos;, &apos;py&apos;: &apos;1.5.3&apos;, &apos;pluggy&apos;: &apos;0.6.0&apos;}</td></tr>\n      <tr>\n        <td>Platform</td>\n        <td>Darwin-17.5.0-x86_64-i386-64bit</td></tr>\n      <tr>\n        <td>Plugins</td>\n        <td>{&apos;xdist&apos;: &apos;1.22.2&apos;, &apos;variables&apos;: &apos;1.7.1&apos;, &apos;selenium&apos;: &apos;1.13.0&apos;, &apos;metadata&apos;: &apos;1.7.0&apos;, &apos;html&apos;: &apos;1.19.0&apos;, &apos;forked&apos;: &apos;0.2&apos;, &apos;base-url&apos;: &apos;1.4.1&apos;}</td></tr>\n      <tr>\n        <td>Python</td>\n        <td>3.6.5</td></tr></table>\n    <h2>Summary</h2>\n    <p>3 tests ran in 20.54 seconds. </p>\n    <p class=\"filter\" hidden=\"true\">(Un)check the boxes to filter the results.</p><input checked=\"true\" class=\"filter\" data-test-result=\"passed\" hidden=\"true\" name=\"filter_checkbox\" onChange=\"filter_table(this)\" type=\"checkbox\"/><span class=\"passed\">3 passed</span>, <input checked=\"true\" class=\"filter\" data-test-result=\"skipped\" disabled=\"true\" hidden=\"true\" name=\"filter_checkbox\" onChange=\"filter_table(this)\" type=\"checkbox\"/><span class=\"skipped\">0 skipped</span>, <input checked=\"true\" class=\"filter\" data-test-result=\"failed\" disabled=\"true\" hidden=\"true\" name=\"filter_checkbox\" onChange=\"filter_table(this)\" type=\"checkbox\"/><span class=\"failed\">0 failed</span>, <input checked=\"true\" class=\"filter\" data-test-result=\"error\" disabled=\"true\" hidden=\"true\" name=\"filter_checkbox\" onChange=\"filter_table(this)\" type=\"checkbox\"/><span class=\"error\">0 errors</span>, <input checked=\"true\" class=\"filter\" data-test-result=\"xfailed\" disabled=\"true\" hidden=\"true\" name=\"filter_checkbox\" onChange=\"filter_table(this)\" type=\"checkbox\"/><span class=\"xfailed\">0 expected failures</span>, <input checked=\"true\" class=\"filter\" data-test-result=\"xpassed\" disabled=\"true\" hidden=\"true\" name=\"filter_checkbox\" onChange=\"filter_table(this)\" type=\"checkbox\"/><span class=\"xpassed\">0 unexpected passes</span>\n    <h2>Results</h2>\n    <table id=\"results-table\">\n      <thead id=\"results-table-head\">\n        <tr>\n          <th class=\"sortable result initial-sort\" col=\"result\">Result</th>\n          <th class=\"sortable\" col=\"name\">Test</th>\n          <th class=\"sortable numeric\" col=\"duration\">Duration</th>\n          <th>Links</th></tr>\n        <tr hidden=\"true\" id=\"not-found-message\">\n          <th colspan=\"4\">No results found. Try to check the filters</th></tr></thead>\n      <tbody class=\"passed results-table-row\">\n        <tr>\n          <td class=\"col-result\">Passed</td>\n          <td class=\"col-name\">test_download.py::test_download</td>\n          <td class=\"col-duration\">0.00</td>\n          <td class=\"col-links\"></td></tr>\n        <tr>\n          <td class=\"extra\" colspan=\"4\">\n            <div class=\"empty log\">No log output captured.</div></td></tr></tbody>\n      <tbody class=\"passed results-table-row\">\n        <tr>\n          <td class=\"col-result\">Passed</td>\n          <td class=\"col-name\">test_progress.py::test_progress</td>\n          <td class=\"col-duration\">0.00</td>\n          <td class=\"col-links\"></td></tr>\n        <tr>\n          <td class=\"extra\" colspan=\"4\">\n            <div class=\"empty log\">No log output captured.</div></td></tr></tbody>\n      <tbody class=\"passed results-table-row\">\n        <tr>\n          <td class=\"col-result\">Passed</td>\n          <td class=\"col-name\">test_upload.py::test_upload</td>\n          <td class=\"col-duration\">0.01</td>\n          <td class=\"col-links\"></td></tr>\n        <tr>\n          <td class=\"extra\" colspan=\"4\">\n            <div class=\"empty log\">No log output captured.</div></td></tr></tbody></table></body></html>"
  },
  {
    "path": "test/readme.md",
    "content": "# Tests\n\nTo run all the tests use `npm test`. This will run the tests and produce a code coverage report at [coverage/index.html](../coverage/index.html). The full test suite is run as a hook on each `git push`. [Mocha](https://mochajs.org) is our preferred test runner.\n\n## Frontend\n\nUnit tests reside in `test/frontend/tests`.\n\nFrontend tests can be ran in the browser by running `npm start` and then browsing to http://localhost:8080/test. Doing it this way will watch for changes and rerun the suite automatically.\n\nYou can also run them in headless Chrome by using `npm run test:frontend`. The results will be printed to the console.\n\n## Backend\n\nUnit tests reside in `test/backend`\n\nBackend test can be run with `npm run test:backend`. [Sinon](http://sinonjs.org/) and [proxyquire](https://github.com/thlorenz/proxyquire) are used for mocking.\n\n## Integration\n\nIntegration tests include UI tests that run with Selenium.\n\nThe preferred way to run these locally is with `npm run test-integration` which requires docker. To watch the tests connect with VNC. On mac enter `vnc://localhost:5900` in Safari and use the password `secret` to connect. For info on debugging a test see the [wdio debug docs](http://webdriver.io/api/utility/debug.html).\n"
  },
  {
    "path": "test/testServer.js",
    "content": "let server = null;\n\nmodule.exports = {\n  onPrepare: function() {\n    return new Promise(function(resolve) {\n      const webpack = require('webpack');\n      const middleware = require('webpack-dev-middleware');\n      const express = require('express');\n      const expressWs = require('@dannycoates/express-ws');\n      const assets = require('../common/assets');\n      const routes = require('../server/routes');\n      const tests = require('./frontend/routes');\n      const app = express();\n      const config = require('../webpack.config');\n      const wpm = middleware(webpack(config(null, { mode: 'development' })), {\n        logLevel: 'silent'\n      });\n      app.use(wpm);\n      assets.setMiddleware(wpm);\n      expressWs(app, null, { perMessageDeflate: false });\n      routes(app);\n      app.ws('/api/ws', require('../server/routes/ws'));\n      tests(app);\n      wpm.waitUntilValid(() => {\n        server = app.listen(8000, resolve);\n      });\n    });\n  },\n  onComplete: function() {\n    server.close();\n  }\n};\n"
  },
  {
    "path": "test/wdio.circleci.conf.js",
    "content": "// eslint-disable-next-line node/no-extraneous-require\nconst ip = require('ip');\nconst common = require('./wdio.common.conf');\n\n/*/\n\nConfig for running selenium from a circleci docker container against localhost\n\n/*/\n\nexports.config = Object.assign({}, common.config, {\n  baseUrl: `http://${ip.address()}:8000`,\n  maxInstances: 1,\n  bail: 1,\n  services: [require('./testServer'), 'selenium-standalone']\n});\n"
  },
  {
    "path": "test/wdio.common.conf.js",
    "content": "const path = require('path');\nconst mkdirp = require('mkdirp');\nconst rimraf = require('rimraf');\nconst dir = path.join(__dirname, 'integration', 'downloads');\n\nmkdirp.sync(dir);\nrimraf.sync(`${dir}${path.sep}*`);\n\nexports.config = {\n  specs: [path.join(__dirname, './integration/**/*-tests.js')],\n  exclude: [],\n  maxInstances: 10,\n  capabilities: [\n    {\n      browserName: 'firefox',\n      'moz:firefoxOptions': {\n        log: { level: 'trace' },\n        prefs: {\n          'browser.download.panel.shown': false,\n          'browser.helperApps.neverAsk.openFile': 'text/plain',\n          'browser.helperApps.neverAsk.saveToDisk': 'text/plain',\n          'browser.download.folderList': 2,\n          'browser.download.dir': dir\n        }\n      }\n    }\n  ],\n  pageLoadStrategy: 'normal',\n  watch: false,\n  async: true,\n  logLevel: 'error',\n  coloredLogs: true,\n  deprecationWarnings: true,\n  bail: 0,\n  screenshotOnReject: false,\n  baseUrl: 'http://localhost:8000',\n  waitforTimeout: 20000,\n  connectionRetryTimeout: 90000,\n  connectionRetryCount: 3,\n  services: ['firefox-profile'],\n  framework: 'mocha',\n  reporters: ['dot', 'spec'],\n  mochaOpts: {\n    ui: 'bdd',\n    timeout: 30000,\n    retries: 1\n  }\n};\n"
  },
  {
    "path": "test/wdio.docker.conf.js",
    "content": "// eslint-disable-next-line node/no-extraneous-require\nconst ip = require('ip');\nconst common = require('./wdio.common.conf');\nconst dir =\n  common.config.capabilities[0]['moz:firefoxOptions'].prefs[\n    'browser.download.dir'\n  ];\n\n/*/\n\nConfig for running selenium in a new docker container against localhost\n\n/*/\n\nexports.config = Object.assign({}, common.config, {\n  baseUrl: `http://${ip.address()}:8000`,\n  maxInstances: 1,\n  services: ['docker', require('./testServer')],\n  dockerOptions: {\n    image: 'selenium/standalone-firefox-debug',\n    healthCheck: 'http://localhost:4444',\n    options: {\n      p: ['4444:4444', '5900:5900'],\n      mount: `type=bind,source=${dir},destination=${dir},consistency=delegated`,\n      shmSize: '2g'\n    }\n  }\n});\n"
  },
  {
    "path": "test/wdio.local.conf.js",
    "content": "// eslint-disable-next-line node/no-extraneous-require\nconst ip = require('ip');\nconst common = require('./wdio.common.conf');\n\n/*/\n\nConfig for running selenium against localhost\n\n/*/\n\nexports.config = Object.assign({}, common.config, {\n  baseUrl: `http://${ip.address()}:8000`,\n  maxInstances: 1,\n  bail: 1,\n  services: [require('./testServer')]\n});\n"
  },
  {
    "path": "test/wdio.remote.config.js",
    "content": "const common = require('./wdio.common.conf');\nconst path = require('path');\n\n/*/\n\nConfig for running saucelabs against a hosted server\n\n/*/\n\nexports.config = Object.assign({}, common.config, {\n  baseUrl: process.env.TEST_SERVER || 'https://send.dev.mozaws.net',\n  exclude: [\n    // the /test endpoint only exists on localhost\n    path.join(__dirname, './integration/unit-tests.js'),\n    // we don't have access to the fs in this context\n    path.join(__dirname, './integration/download-tests.js')\n  ],\n  capabilities: [\n    { browserName: 'firefox' },\n    { browserName: 'chrome' },\n    { browserName: 'MicrosoftEdge' },\n    {\n      browserName: 'safari'\n    }\n  ],\n  services: ['sauce'],\n  user: process.env.SAUCE_USERNAME,\n  key: process.env.SAUCE_ACCESS_KEY\n});\n"
  },
  {
    "path": "test/wdio.saucelabs.config.js",
    "content": "const common = require('./wdio.common.conf');\nconst path = require('path');\n\n/*/\n\nConfig for running saucelabs against localhost\n\n/*/\n\nexports.config = Object.assign({}, common.config, {\n  maxInstances: 2,\n  exclude: [path.join(__dirname, './integration/download-tests.js')],\n  capabilities: [\n    { browserName: 'firefox' },\n    { browserName: 'chrome' },\n    { browserName: 'MicrosoftEdge' },\n    {\n      browserName: 'safari'\n    }\n  ],\n  services: ['sauce', require('./testServer')],\n  sauceConnect: true,\n  sauceConnectOpts: {\n    // uncomment to debug\n    // logfile: __dirname + '/sc.log',\n    // verbose: true\n  },\n  user: process.env.SAUCE_USERNAME,\n  key: process.env.SAUCE_ACCESS_KEY\n});\n"
  },
  {
    "path": "webpack.config.js",
    "content": "const path = require('path');\nconst webpack = require('webpack');\nconst CopyPlugin = require('copy-webpack-plugin');\nconst ManifestPlugin = require('webpack-manifest-plugin');\nconst VersionPlugin = require('./build/version_plugin');\nconst AndroidIndexPlugin = require('./build/android_index_plugin');\nconst ExtractTextPlugin = require('extract-text-webpack-plugin');\n\nconst webJsOptions = {\n  babelrc: false,\n  presets: [\n    [\n      '@babel/preset-env',\n      {\n        bugfixes: true,\n        useBuiltIns: 'entry',\n        corejs: 3\n      }\n    ]\n  ],\n  plugins: [\n    '@babel/plugin-syntax-dynamic-import',\n    'module:nanohtml',\n    ['@babel/plugin-proposal-class-properties', { loose: false }]\n  ]\n};\n\nconst serviceWorker = {\n  target: 'webworker',\n  entry: {\n    serviceWorker: './app/serviceWorker.js'\n  },\n  output: {\n    filename: '[name].js',\n    path: path.resolve(__dirname, 'dist'),\n    publicPath: '/'\n  },\n  devtool: 'source-map',\n  module: {\n    rules: [\n      {\n        test: /\\.(png|jpg)$/,\n        loader: 'file-loader',\n        options: {\n          name: '[name].[contenthash:8].[ext]'\n        }\n      },\n      {\n        test: /\\.svg$/,\n        use: [\n          {\n            loader: 'file-loader',\n            options: {\n              name: '[name].[contenthash:8].[ext]'\n            }\n          },\n          {\n            loader: 'svgo-loader',\n            options: {\n              plugins: [\n                { removeViewBox: false }, // true causes stretched images\n                { convertStyleToAttrs: true }, // for CSP, no unsafe-eval\n                { removeTitle: true } // for smallness\n              ]\n            }\n          }\n        ]\n      },\n      {\n        // loads all assets from assets/ for use by common/assets.js\n        test: require.resolve('./common/generate_asset_map.js'),\n        use: ['babel-loader', 'val-loader']\n      }\n    ]\n  },\n  plugins: [new webpack.IgnorePlugin(/\\.\\.\\/dist/)]\n};\n\nconst web = {\n  target: 'web',\n  entry: {\n    app: ['./app/main.js']\n    // android: ['./android/android.js'],\n    // ios: ['./ios/ios.js']\n  },\n  output: {\n    chunkFilename: '[name].[contenthash:8].js',\n    filename: '[name].[contenthash:8].js',\n    path: path.resolve(__dirname, 'dist')\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.js$/,\n        oneOf: [\n          {\n            loader: 'babel-loader',\n            include: [\n              path.resolve(__dirname, 'app'),\n              path.resolve(__dirname, 'common'),\n              // some dependencies need to get re-babeled because we\n              // have different targets than their default configs\n              path.resolve(\n                __dirname,\n                'node_modules/@dannycoates/webcrypto-liner'\n              ),\n              path.resolve(__dirname, 'node_modules/@fluent'),\n              path.resolve(__dirname, 'node_modules/intl-pluralrules')\n            ],\n            options: webJsOptions\n          },\n          {\n            // Strip asserts from our deps, mainly choojs family\n            include: [path.resolve(__dirname, 'node_modules')],\n            exclude: [\n              path.resolve(__dirname, 'node_modules/crc'),\n              path.resolve(__dirname, 'node_modules/@fluent'),\n              path.resolve(__dirname, 'node_modules/@sentry'),\n              path.resolve(__dirname, 'node_modules/tslib'),\n              path.resolve(__dirname, 'node_modules/webcrypto-core')\n            ],\n            loader: 'webpack-unassert-loader'\n          }\n        ]\n      },\n      {\n        test: /\\.(png|jpg)$/,\n        loader: 'file-loader',\n        options: {\n          name: '[name].[contenthash:8].[ext]'\n        }\n      },\n      {\n        test: /\\.svg$/,\n        use: [\n          {\n            loader: 'file-loader',\n            options: {\n              name: '[name].[contenthash:8].[ext]'\n            }\n          },\n          {\n            loader: 'svgo-loader',\n            options: {\n              plugins: [\n                { cleanupIDs: false },\n                { removeViewBox: false }, // true causes stretched images\n                { convertStyleToAttrs: true }, // for CSP, no unsafe-eval\n                { removeTitle: true } // for smallness\n              ]\n            }\n          }\n        ]\n      },\n      {\n        // creates style.css with all styles\n        test: /\\.css$/,\n        use: ExtractTextPlugin.extract({\n          use: [\n            {\n              loader: 'css-loader',\n              options: {\n                importLoaders: 1\n              }\n            },\n            'postcss-loader'\n          ]\n        })\n      },\n      {\n        test: /\\.ftl$/,\n        use: 'raw-loader'\n      },\n      {\n        // creates test.js for /test\n        test: require.resolve('./test/frontend/index.js'),\n        use: ['babel-loader', 'val-loader']\n      },\n      {\n        // loads all assets from assets/ for use by common/assets.js\n        test: require.resolve('./common/generate_asset_map.js'),\n        use: ['babel-loader', 'val-loader']\n      }\n    ]\n  },\n  plugins: [\n    new CopyPlugin([\n      {\n        context: 'public',\n        from: '*.*'\n      }\n    ]),\n    new webpack.EnvironmentPlugin(['NODE_ENV']),\n    new webpack.IgnorePlugin(/\\.\\.\\/dist/), // used in common/*.js\n    new ExtractTextPlugin({\n      filename: '[name].[md5:contenthash:8].css'\n    }),\n    new VersionPlugin(), // used for the /__version__ route\n    new AndroidIndexPlugin(),\n    new ManifestPlugin() // used by server side to resolve hashed assets\n  ],\n  devtool: 'source-map',\n  devServer: {\n    before:\n      process.env.NODE_ENV === 'development' && require('./server/bin/dev'),\n    compress: true,\n    hot: false,\n    host: '0.0.0.0',\n    proxy: {\n      '/api/ws': {\n        target: 'ws://localhost:1338',\n        ws: true,\n        secure: false\n      }\n    }\n  }\n};\n\nmodule.exports = (env, argv) => {\n  const mode = argv.mode || 'production';\n  // eslint-disable-next-line no-console\n  console.error(`mode: ${mode}`);\n  process.env.NODE_ENV = web.mode = serviceWorker.mode = mode;\n  if (mode === 'development') {\n    // istanbul instruments the source for code coverage\n    webJsOptions.plugins.push('istanbul');\n    web.entry.tests = ['./test/frontend/index.js'];\n  }\n  return [web, serviceWorker];\n};\n"
  }
]