Merge branch 'develop' into patch-3
							
								
								
									
										21
									
								
								.babelrc
									
									
									
									
									
								
							
							
						
						@ -1,4 +1,21 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "presets": ["react", "es2015", "es2016"],
 | 
					    "presets": [
 | 
				
			||||||
  "plugins": ["transform-class-properties", "transform-object-rest-spread", "transform-async-to-bluebird", "transform-runtime", "add-module-exports"]
 | 
					        "react",
 | 
				
			||||||
 | 
					        "es2015",
 | 
				
			||||||
 | 
					        "es2016"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "plugins": [
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            "transform-builtin-extend",
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "globals": ["Error"]
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "transform-class-properties",
 | 
				
			||||||
 | 
					        "transform-object-rest-spread",
 | 
				
			||||||
 | 
					        "transform-async-to-bluebird",
 | 
				
			||||||
 | 
					        "transform-runtime",
 | 
				
			||||||
 | 
					        "add-module-exports",
 | 
				
			||||||
 | 
					        "syntax-dynamic-import"
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										57
									
								
								.buildkite/pipeline.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					steps:
 | 
				
			||||||
 | 
					  - label: ":eslint: Lint"
 | 
				
			||||||
 | 
					    command:
 | 
				
			||||||
 | 
					      - "yarn install"
 | 
				
			||||||
 | 
					      - "yarn lint"
 | 
				
			||||||
 | 
					    plugins:
 | 
				
			||||||
 | 
					      - docker#v3.0.1:
 | 
				
			||||||
 | 
					          image: "node:10"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - label: ":karma: Tests"
 | 
				
			||||||
 | 
					    agents:
 | 
				
			||||||
 | 
					      # We use a medium sized instance instead of the normal small ones because
 | 
				
			||||||
 | 
					      # webpack loves to gorge itself on resources.
 | 
				
			||||||
 | 
					      queue: "medium"
 | 
				
			||||||
 | 
					    command:
 | 
				
			||||||
 | 
					      # Install chrome
 | 
				
			||||||
 | 
					      - "echo '--- Installing Chrome'"
 | 
				
			||||||
 | 
					      - "wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -"
 | 
				
			||||||
 | 
					      - "sh -c 'echo \"deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main\" >> /etc/apt/sources.list.d/google.list'"
 | 
				
			||||||
 | 
					      - "apt-get update"
 | 
				
			||||||
 | 
					      - "apt-get install -y google-chrome-stable"
 | 
				
			||||||
 | 
					      # Run tests
 | 
				
			||||||
 | 
					      - "echo '--- Fetching Dependencies'"
 | 
				
			||||||
 | 
					      - "./scripts/fetch-develop.deps.sh --depth 1"
 | 
				
			||||||
 | 
					      - "yarn install"
 | 
				
			||||||
 | 
					      - "echo '+++ Running Tests'"
 | 
				
			||||||
 | 
					      - "yarn test"
 | 
				
			||||||
 | 
					    env:
 | 
				
			||||||
 | 
					      CHROME_BIN: "/usr/bin/google-chrome-stable"
 | 
				
			||||||
 | 
					    plugins:
 | 
				
			||||||
 | 
					      - docker#v3.0.1:
 | 
				
			||||||
 | 
					          image: "node:10"
 | 
				
			||||||
 | 
					          propagate-environment: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - label: ":hammer: Package"
 | 
				
			||||||
 | 
					    command:
 | 
				
			||||||
 | 
					      - "echo '--- Fetching Dependencies'"
 | 
				
			||||||
 | 
					      - "./scripts/fetch-develop.deps.sh --depth 1"
 | 
				
			||||||
 | 
					      - "yarn install"
 | 
				
			||||||
 | 
					      - "echo '+++ Packaging'"
 | 
				
			||||||
 | 
					      - "./scripts/ci_package.sh"
 | 
				
			||||||
 | 
					    branches: "develop"
 | 
				
			||||||
 | 
					    artifact_paths: "dist/riot-*.tar.gz"
 | 
				
			||||||
 | 
					    plugins:
 | 
				
			||||||
 | 
					      - docker#v3.0.1:
 | 
				
			||||||
 | 
					          image: "node:10"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - label: "🌐 i18n"
 | 
				
			||||||
 | 
					    command:
 | 
				
			||||||
 | 
					      - "echo '--- Fetching Dependencies'"
 | 
				
			||||||
 | 
					      - "./scripts/fetch-develop.deps.sh --depth 1"
 | 
				
			||||||
 | 
					      - "yarn install"
 | 
				
			||||||
 | 
					      - "echo '+++ Testing i18n output'"
 | 
				
			||||||
 | 
					      - "yarn diff-i18n"
 | 
				
			||||||
 | 
					    plugins:
 | 
				
			||||||
 | 
					      - docker#v3.0.1:
 | 
				
			||||||
 | 
					          image: "node:10"
 | 
				
			||||||
							
								
								
									
										11
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					# Exclude a bunch of stuff which can make the build context a larger than it needs to be
 | 
				
			||||||
 | 
					.git/
 | 
				
			||||||
 | 
					test/
 | 
				
			||||||
 | 
					webapp/
 | 
				
			||||||
 | 
					lib/
 | 
				
			||||||
 | 
					node_modules/
 | 
				
			||||||
 | 
					electron_app/
 | 
				
			||||||
 | 
					karma-reports/
 | 
				
			||||||
 | 
					.idea/
 | 
				
			||||||
 | 
					.tmp/
 | 
				
			||||||
 | 
					config.json*
 | 
				
			||||||
							
								
								
									
										2
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					patreon: matrixdotorg
 | 
				
			||||||
 | 
					liberapay: matrixdotorg
 | 
				
			||||||
							
								
								
									
										2
									
								
								.github/ISSUE_TEMPLATE.md
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -43,4 +43,4 @@ For the web app:
 | 
				
			|||||||
For the desktop app:
 | 
					For the desktop app:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
 | 
					- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
 | 
				
			||||||
- **Version**: 0.x.y <!-- check the user settings panel if unsure -->
 | 
					- **Version**: 1.x.y <!-- check the user settings panel if unsure -->
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										56
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					name: Bug report
 | 
				
			||||||
 | 
					about: Create a report to help us improve
 | 
				
			||||||
 | 
					title: ''
 | 
				
			||||||
 | 
					labels: bug
 | 
				
			||||||
 | 
					assignees: ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- Please report security issues by email to security@matrix.org -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- This is a bug report template. By following the instructions below and
 | 
				
			||||||
 | 
					filling out the sections with your information, you will help the us to get all
 | 
				
			||||||
 | 
					the necessary data to fix your issue.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can also preview your report before submitting it. You may remove sections
 | 
				
			||||||
 | 
					that aren't relevant to your particular case.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Text between <!-- and --> marks will be invisible in the report.
 | 
				
			||||||
 | 
					-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Description
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Describe here the problem that you are experiencing, or the feature you are requesting.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Steps to reproduce
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- For bugs, list the steps
 | 
				
			||||||
 | 
					- that reproduce the bug
 | 
				
			||||||
 | 
					- using hyphens as bullet points
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Describe how what happens differs from what you expected.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- Please send us logs for your bug report. They're very important for bugs
 | 
				
			||||||
 | 
					which are hard to reproduce. To do this, create this issue then go to your
 | 
				
			||||||
 | 
					account settings and click 'Submit Debug Logs' from the Help & About tab -->
 | 
				
			||||||
 | 
					Logs being sent: yes/no
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- Include screenshots if possible: you can drag and drop images below. -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Version information
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- IMPORTANT: please answer the following questions, to help us narrow down the problem -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **Platform**: web (in-browser) or desktop?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For the web app:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **Browser**: Chrome, Safari, Firefox? which version?
 | 
				
			||||||
 | 
					- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
 | 
				
			||||||
 | 
					- **URL**: riot.im/develop / riot.im/app / somewhere else? If a private server, what version of riot-web?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For the desktop app:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
 | 
				
			||||||
 | 
					- **Version**: 1.x.y <!-- check the user settings panel if unsure -->
 | 
				
			||||||
							
								
								
									
										20
									
								
								.github/ISSUE_TEMPLATE/suggestion-or-feature-request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					name: Suggestion or Feature request
 | 
				
			||||||
 | 
					about: Suggest an idea for this project
 | 
				
			||||||
 | 
					title: ''
 | 
				
			||||||
 | 
					labels: suggestion
 | 
				
			||||||
 | 
					assignees: ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Is your suggestion related to a problem? Please describe.**
 | 
				
			||||||
 | 
					A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Describe the solution you'd like**
 | 
				
			||||||
 | 
					A clear and concise description of what you want to happen.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Describe alternatives you've considered**
 | 
				
			||||||
 | 
					A clear and concise description of any alternative solutions or features you've considered.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Additional context**
 | 
				
			||||||
 | 
					Add any other context or screenshots about the feature request here.
 | 
				
			||||||
							
								
								
									
										58
									
								
								.github/ISSUE_TEMPLATE/user-interface-or-usability-bug-report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					name: User Interface or Usability Bug report
 | 
				
			||||||
 | 
					about: Please include screenshots in UI/UX bug reports
 | 
				
			||||||
 | 
					title: ''
 | 
				
			||||||
 | 
					labels: bug, ui/ux
 | 
				
			||||||
 | 
					assignees: ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- A picture's worth a thousand words: PLEASE INCLUDE A SCREENSHOT :P -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- Please report security issues by email to security@matrix.org -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- This is a bug report template. By following the instructions below and
 | 
				
			||||||
 | 
					filling out the sections with your information, you will help the us to get all
 | 
				
			||||||
 | 
					the necessary data to fix your issue.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can also preview your report before submitting it. You may remove sections
 | 
				
			||||||
 | 
					that aren't relevant to your particular case.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Text between <!-- and --> marks will be invisible in the report.
 | 
				
			||||||
 | 
					-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Description
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Describe here the problem that you are experiencing, or the feature you are requesting.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Steps to reproduce
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- For bugs, list the steps
 | 
				
			||||||
 | 
					- that reproduce the bug
 | 
				
			||||||
 | 
					- using hyphens as bullet points
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Describe how what happens differs from what you expected.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- Please send us logs for your bug report. They're very important for bugs
 | 
				
			||||||
 | 
					which are hard to reproduce. To do this, create this issue then go to your
 | 
				
			||||||
 | 
					account settings and click 'Submit Debug Logs' from the Help & About tab -->
 | 
				
			||||||
 | 
					Logs being sent: yes/no
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- Include screenshots if possible: you can drag and drop images below. -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Version information
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- IMPORTANT: please answer the following questions, to help us narrow down the problem -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **Platform**: web (in-browser) or desktop?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For the web app:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **Browser**: Chrome, Safari, Firefox? which version?
 | 
				
			||||||
 | 
					- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
 | 
				
			||||||
 | 
					- **URL**: riot.im/develop / riot.im/app / somewhere else? If a private server, what version of riot-web?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For the desktop app:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
 | 
				
			||||||
 | 
					- **Version**: 1.x.y <!-- check the user settings panel if unsure -->
 | 
				
			||||||
							
								
								
									
										8
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,19 +1,23 @@
 | 
				
			|||||||
/build
 | 
					/build
 | 
				
			||||||
/cert.pem
 | 
					/cert.pem
 | 
				
			||||||
/dist
 | 
					/dist
 | 
				
			||||||
/karma-reports
 | 
					 | 
				
			||||||
/key.pem
 | 
					/key.pem
 | 
				
			||||||
/lib
 | 
					/lib
 | 
				
			||||||
/node_modules
 | 
					/node_modules
 | 
				
			||||||
/electron_app/node_modules
 | 
					/electron_app/node_modules
 | 
				
			||||||
/electron_app/dist
 | 
					/electron_app/dist
 | 
				
			||||||
 | 
					/electron_app/pub
 | 
				
			||||||
/packages/
 | 
					/packages/
 | 
				
			||||||
/webapp
 | 
					/webapp
 | 
				
			||||||
/.npmrc
 | 
					/.npmrc
 | 
				
			||||||
 | 
					/*.log
 | 
				
			||||||
 | 
					package-lock.json
 | 
				
			||||||
.DS_Store
 | 
					.DS_Store
 | 
				
			||||||
npm-debug.log
 | 
					 | 
				
			||||||
electron/dist
 | 
					electron/dist
 | 
				
			||||||
electron/pub
 | 
					electron/pub
 | 
				
			||||||
**/.idea
 | 
					**/.idea
 | 
				
			||||||
/config.json
 | 
					/config.json
 | 
				
			||||||
 | 
					/config.json.*
 | 
				
			||||||
 | 
					/config.local*.json
 | 
				
			||||||
/src/component-index.js
 | 
					/src/component-index.js
 | 
				
			||||||
 | 
					/.tmp
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										35
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						@ -1,35 +0,0 @@
 | 
				
			|||||||
# we need trusty for the chrome addon
 | 
					 | 
				
			||||||
dist: trusty
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# we don't need sudo, so can run in a container, which makes startup much
 | 
					 | 
				
			||||||
# quicker.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# unfortunately we do temporarily require sudo as a workaround for
 | 
					 | 
				
			||||||
# https://github.com/travis-ci/travis-ci/issues/8836
 | 
					 | 
				
			||||||
sudo: required
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
language: node_js
 | 
					 | 
				
			||||||
node_js:
 | 
					 | 
				
			||||||
    # make sure we work with a range of node versions.
 | 
					 | 
				
			||||||
    # As of the time of writing:
 | 
					 | 
				
			||||||
    #  - 4.x is still in LTS (until April 2018), but some of our deps (notably
 | 
					 | 
				
			||||||
    #    extract-zip) don't work with it
 | 
					 | 
				
			||||||
    #  - 5.x has been EOLed for nearly a year.
 | 
					 | 
				
			||||||
    #  - 6.x is the active 'LTS' version
 | 
					 | 
				
			||||||
    #  - 7.x is no longer supported
 | 
					 | 
				
			||||||
    #  - 8.x is the current 'current' version (until October 2017)
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # see: https://github.com/nodejs/LTS/
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # anything before 6.3 ships with npm 3.9 or earlier, which had problems
 | 
					 | 
				
			||||||
    # with symlinks in node_modules (see
 | 
					 | 
				
			||||||
    # https://github.com/npm/npm/releases/tag/v3.10.0 'FIXES AND REFACTORING').
 | 
					 | 
				
			||||||
    - 6.3
 | 
					 | 
				
			||||||
    - 6
 | 
					 | 
				
			||||||
    - 7
 | 
					 | 
				
			||||||
addons:
 | 
					 | 
				
			||||||
    chrome: stable
 | 
					 | 
				
			||||||
install:
 | 
					 | 
				
			||||||
    # clone the deps with depth 1: we know we will only ever need that one
 | 
					 | 
				
			||||||
    # commit.
 | 
					 | 
				
			||||||
    - scripts/fetch-develop.deps.sh --depth 1 && npm install
 | 
					 | 
				
			||||||
							
								
								
									
										1454
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						@ -1,4 +1,4 @@
 | 
				
			|||||||
Contributing code to Riot
 | 
					Contributing code to Riot
 | 
				
			||||||
=========================
 | 
					=========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Riot follows the same pattern as https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.rst.
 | 
					Riot follows the same pattern as https://github.com/matrix-org/matrix-js-sdk/blob/master/CONTRIBUTING.rst.
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										31
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					# Builder
 | 
				
			||||||
 | 
					FROM node:10-alpine as builder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Support custom branches of the react-sdk and js-sdk. This also helps us build
 | 
				
			||||||
 | 
					# images of riot-web develop.
 | 
				
			||||||
 | 
					ARG USE_CUSTOM_SDKS=false
 | 
				
			||||||
 | 
					ARG REACT_SDK_REPO="https://github.com/matrix-org/matrix-react-sdk.git"
 | 
				
			||||||
 | 
					ARG REACT_SDK_BRANCH="master"
 | 
				
			||||||
 | 
					ARG JS_SDK_REPO="https://github.com/matrix-org/matrix-js-sdk.git"
 | 
				
			||||||
 | 
					ARG JS_SDK_BRANCH="master"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apk add --no-cache git dos2unix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /src
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY . /src
 | 
				
			||||||
 | 
					RUN dos2unix /src/scripts/docker-link-repos.sh && sh /src/scripts/docker-link-repos.sh
 | 
				
			||||||
 | 
					RUN yarn --network-timeout=100000 install
 | 
				
			||||||
 | 
					RUN yarn build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Copy the config now so that we don't create another layer in the app image
 | 
				
			||||||
 | 
					RUN cp /src/config.sample.json /src/webapp/config.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# App
 | 
				
			||||||
 | 
					FROM nginx:alpine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY --from=builder /src/webapp /app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN rm -rf /usr/share/nginx/html \
 | 
				
			||||||
 | 
					 && ln -s /app /usr/share/nginx/html
 | 
				
			||||||
							
								
								
									
										351
									
								
								README.md
									
									
									
									
									
								
							
							
						
						@ -1,40 +1,41 @@
 | 
				
			|||||||
Riot
 | 
					Riot
 | 
				
			||||||
====
 | 
					====
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Riot (formerly known as Vector) is a Matrix web client built using the Matrix
 | 
					Riot (formerly known as Vector) is a Matrix web client built using the [Matrix React SDK](https://github.com/matrix-org/matrix-react-sdk).
 | 
				
			||||||
React SDK (https://github.com/matrix-org/matrix-react-sdk).
 | 
					
 | 
				
			||||||
 | 
					Riot is officially supported on the web in modern versions of Chrome, Firefox, and Safari. Other browsers may work, however
 | 
				
			||||||
 | 
					official support is not provided. For accessing Riot on an Android or iOS device, check out [riot-android](https://github.com/vector-im/riot-android)
 | 
				
			||||||
 | 
					and [riot-ios](https://github.com/vector-im/riot-ios) - riot-web does not support mobile devices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Getting Started
 | 
					Getting Started
 | 
				
			||||||
===============
 | 
					===============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The easiest way to test Riot is to just use the hosted copy at
 | 
					The easiest way to test Riot is to just use the hosted copy at https://riot.im/app.
 | 
				
			||||||
https://riot.im/app.  The develop branch is continuously deployed by Jenkins at
 | 
					The `develop` branch is continuously deployed by Jenkins at https://riot.im/develop
 | 
				
			||||||
https://riot.im/develop for those who like living dangerously.
 | 
					for those who like living dangerously.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To host your own copy of Riot, the quickest bet is to use a pre-built
 | 
					To host your own copy of Riot, the quickest bet is to use a pre-built
 | 
				
			||||||
released version of Riot:
 | 
					released version of Riot:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. Download the latest version from https://github.com/vector-im/riot-web/releases
 | 
					1. Download the latest version from https://github.com/vector-im/riot-web/releases
 | 
				
			||||||
1. Untar the tarball on your web server
 | 
					1. Untar the tarball on your web server
 | 
				
			||||||
1. Move (or symlink) the riot-x.x.x directory to an appropriate name
 | 
					1. Move (or symlink) the `riot-x.x.x` directory to an appropriate name
 | 
				
			||||||
1. If desired, copy `config.sample.json` to `config.json` and edit it
 | 
					1. If desired, copy `config.sample.json` to `config.json` and edit it
 | 
				
			||||||
   as desired. See below for details.
 | 
					   as desired. See the [configuration docs](docs/config.md) for details.
 | 
				
			||||||
1. Enter the URL into your browser and log into Riot!
 | 
					1. Enter the URL into your browser and log into Riot!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Releases are signed by PGP, and can be checked against the public key
 | 
					Releases are signed using gpg and the OpenPGP standard, and can be checked against the public key located
 | 
				
			||||||
at https://riot.im/packages/keys/riot.asc
 | 
					at https://packages.riot.im/riot-release-key.asc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Note that Chrome does not allow microphone or webcam access for sites served
 | 
					Note that for the security of your chats will need to serve Riot
 | 
				
			||||||
over http (except localhost), so for working VoIP you will need to serve Riot
 | 
					over HTTPS. Major browsers also do not allow you to use VoIP/video
 | 
				
			||||||
over https.
 | 
					chats over HTTP, as WebRTC is only usable over HTTPS.
 | 
				
			||||||
 | 
					There are some exceptions like when using localhost, which is
 | 
				
			||||||
 | 
					considered a [secure context](https://developer.mozilla.org/docs/Web/Security/Secure_Contexts)
 | 
				
			||||||
 | 
					and thus allowed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Installation Steps for Debian Stretch
 | 
					To install Riot as a desktop application, see [Running as a desktop
 | 
				
			||||||
1. Add the repository to your sources.list using either of the following two options:
 | 
					app](#running-as-a-desktop-app) below.
 | 
				
			||||||
  - Directly to sources.list: `echo "deb https://riot.im/packages/debian/ stretch main" | sudo tee -a /etc/apt/sources.list`
 | 
					 | 
				
			||||||
  - As a separate entry in sources.list.d: `echo "deb https://riot.im/packages/debian/ stretch main" | sudo tee /etc/apt/sources.list.d/riot.list`
 | 
					 | 
				
			||||||
2. Add the gpg signing key for the riot repository: `curl -s https://riot.im/packages/debian/repo-key.asc | sudo apt-key add -`
 | 
					 | 
				
			||||||
3. Update your package lists: `sudo apt-get update`
 | 
					 | 
				
			||||||
4. Install Riot: `sudo apt-get install riot-web`
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Important Security Note
 | 
					Important Security Note
 | 
				
			||||||
=======================
 | 
					=======================
 | 
				
			||||||
@ -49,115 +50,81 @@ We have put some coarse mitigations into place to try to protect against this
 | 
				
			|||||||
situation, but it's still not good practice to do it in the first place.  See
 | 
					situation, but it's still not good practice to do it in the first place.  See
 | 
				
			||||||
https://github.com/vector-im/riot-web/issues/1977 for more details.
 | 
					https://github.com/vector-im/riot-web/issues/1977 for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The same applies for end-to-end encrypted content, but since this is decrypted
 | 
				
			||||||
 | 
					on the client, Riot needs a way to supply the decrypted content from a separate
 | 
				
			||||||
 | 
					origin to the one Riot is hosted on. This currently done with a 'cross origin
 | 
				
			||||||
 | 
					renderer' which is a small piece of javascript hosted on a different domain.
 | 
				
			||||||
 | 
					To avoid all Riot installs needing one of these to be set up, riot.im hosts
 | 
				
			||||||
 | 
					one on usercontent.riot.im which is used by default.
 | 
				
			||||||
 | 
					https://github.com/vector-im/riot-web/issues/6173 tracks progress on replacing
 | 
				
			||||||
 | 
					this with something better.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Building From Source
 | 
					Building From Source
 | 
				
			||||||
====================
 | 
					====================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Riot is a modular webapp built with modern ES6 and requires a npm build system
 | 
					Riot is a modular webapp built with modern ES6 and uses a Node.js build system.
 | 
				
			||||||
to build.
 | 
					Ensure you have the latest LTS version of Node.js installed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. Install or update `node.js` so that your `node` is at least v6.3.0 (and `npm`
 | 
					Using `yarn` instead of `npm` is recommended. Please see the Yarn [install
 | 
				
			||||||
   is at least v3.10.x).
 | 
					guide](https://yarnpkg.com/docs/install/) if you do not have it already.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Install or update `node.js` so that your `node` is at least v10.x.
 | 
				
			||||||
 | 
					1. Install `yarn` if not present already.
 | 
				
			||||||
1. Clone the repo: `git clone https://github.com/vector-im/riot-web.git`.
 | 
					1. Clone the repo: `git clone https://github.com/vector-im/riot-web.git`.
 | 
				
			||||||
1. Switch to the riot-web directory: `cd riot-web`.
 | 
					1. Switch to the riot-web directory: `cd riot-web`.
 | 
				
			||||||
1. If you're using the `develop` branch, install the develop versions of the
 | 
					1. Install the prerequisites: `yarn install`.
 | 
				
			||||||
   dependencies, as the released ones will be too old:
 | 
					1. If you're using the `develop` branch then it is recommended to set up a proper
 | 
				
			||||||
   ```
 | 
					   development environment ("Setting up a dev environment" below) however one can
 | 
				
			||||||
 | 
					   install the develop versions of the dependencies instead:
 | 
				
			||||||
 | 
					   ```bash
 | 
				
			||||||
   scripts/fetch-develop.deps.sh
 | 
					   scripts/fetch-develop.deps.sh
 | 
				
			||||||
   ```
 | 
					   ```
 | 
				
			||||||
   Whenever you git pull on riot-web you will also probably need to force an update
 | 
					   Whenever you git pull on `riot-web` you will also probably need to force an update
 | 
				
			||||||
   to these dependencies - the simplest way is to re-run the script, but you can also
 | 
					   to these dependencies - the simplest way is to re-run the script, but you can also
 | 
				
			||||||
   manually update and rebuild them:
 | 
					   manually update and rebuild them:
 | 
				
			||||||
   ```
 | 
					   ```bash
 | 
				
			||||||
   cd matrix-js-sdk
 | 
					   cd matrix-js-sdk
 | 
				
			||||||
   git pull
 | 
					   git pull
 | 
				
			||||||
   npm install # re-run to pull in any new dependencies
 | 
					   yarn install # re-run to pull in any new dependencies
 | 
				
			||||||
   # Depending on your version of npm, npm run build may happen as part of
 | 
					 | 
				
			||||||
   # the npm install above (https://docs.npmjs.com/misc/scripts#prepublish-and-prepare)
 | 
					 | 
				
			||||||
   # If in doubt, run it anyway:
 | 
					 | 
				
			||||||
   npm run build
 | 
					 | 
				
			||||||
   cd ../matrix-react-sdk
 | 
					   cd ../matrix-react-sdk
 | 
				
			||||||
   git pull
 | 
					   git pull
 | 
				
			||||||
   npm install
 | 
					   yarn install
 | 
				
			||||||
   npm run build
 | 
					 | 
				
			||||||
   ```
 | 
					   ```
 | 
				
			||||||
   However, we recommend setting up a proper development environment (see "Setting
 | 
					   Or just use https://riot.im/develop - the continuous integration release of the
 | 
				
			||||||
   up a dev environment" below) if you want to run your own copy of the
 | 
					   develop branch. (Note that we don't reference the develop versions in git directly
 | 
				
			||||||
   `develop` branch, as it makes it much easier to keep these dependencies
 | 
					   due to https://github.com/npm/npm/issues/3055.)
 | 
				
			||||||
   up-to-date.  Or just use https://riot.im/develop - the continuous integration
 | 
					 | 
				
			||||||
   release of the develop branch.
 | 
					 | 
				
			||||||
   (Note that we don't reference the develop versions in git directly due to
 | 
					 | 
				
			||||||
   https://github.com/npm/npm/issues/3055.)
 | 
					 | 
				
			||||||
1. Install the prerequisites: `npm install`.
 | 
					 | 
				
			||||||
1. Configure the app by copying `config.sample.json` to `config.json` and
 | 
					1. Configure the app by copying `config.sample.json` to `config.json` and
 | 
				
			||||||
   modifying it (see below for details).
 | 
					   modifying it. See the [configuration docs](docs/config.md) for details.
 | 
				
			||||||
1. `npm run dist` to build a tarball to deploy. Untaring this file will give
 | 
					1. `yarn dist` to build a tarball to deploy. Untaring this file will give
 | 
				
			||||||
   a version-specific directory containing all the files that need to go on your
 | 
					   a version-specific directory containing all the files that need to go on your
 | 
				
			||||||
   web server.
 | 
					   web server.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Note that `npm run dist` is not supported on Windows, so Windows users can run `npm
 | 
					Note that `yarn dist` is not supported on Windows, so Windows users can run `yarn build`,
 | 
				
			||||||
run build`, which will build all the necessary files into the `webapp`
 | 
					which will build all the necessary files into the `webapp` directory. The version of Riot
 | 
				
			||||||
directory. The version of Riot will not appear in Settings without
 | 
					will not appear in Settings without using the dist script. You can then mount the
 | 
				
			||||||
using the dist script. You can then mount the `webapp` directory on your
 | 
					`webapp` directory on your webserver to actually serve up the app, which is entirely static content.
 | 
				
			||||||
webserver to actually serve up the app, which is entirely static content.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
config.json
 | 
					 | 
				
			||||||
===========
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You can configure the app by copying `config.sample.json` to
 | 
					 | 
				
			||||||
`config.json` and customising it:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. `default_hs_url` is the default home server url.
 | 
					 | 
				
			||||||
1. `default_is_url` is the default identity server url (this is the server used
 | 
					 | 
				
			||||||
   for verifying third party identifiers like email addresses). If this is blank,
 | 
					 | 
				
			||||||
   registering with an email address, adding an email address to your account,
 | 
					 | 
				
			||||||
   or inviting users via email address will not work.  Matrix identity servers are
 | 
					 | 
				
			||||||
   very simple web services which map third party identifiers (currently only email
 | 
					 | 
				
			||||||
   addresses) to matrix IDs: see http://matrix.org/docs/spec/identity_service/unstable.html
 | 
					 | 
				
			||||||
   for more details.  Currently the only public matrix identity servers are https://matrix.org
 | 
					 | 
				
			||||||
   and https://vector.im.  In future identity servers will be decentralised.
 | 
					 | 
				
			||||||
1. `integrations_ui_url`: URL to the web interface for the integrations server. The integrations
 | 
					 | 
				
			||||||
   server is not Riot and normally not your Home Server either. The integration server settings
 | 
					 | 
				
			||||||
   may be left blank to disable integrations.
 | 
					 | 
				
			||||||
1. `integrations_rest_url`: URL to the REST interface for the integrations server.
 | 
					 | 
				
			||||||
1. `roomDirectory`: config for the public room directory. This section is optional.
 | 
					 | 
				
			||||||
1. `roomDirectory.servers`: List of other Home Servers' directories to include in the drop
 | 
					 | 
				
			||||||
   down list. Optional.
 | 
					 | 
				
			||||||
1. `update_base_url` (electron app only): HTTPS URL to a web server to download
 | 
					 | 
				
			||||||
   updates from. This should be the path to the directory containing `macos`
 | 
					 | 
				
			||||||
   and `win32` (for update packages, not installer packages).
 | 
					 | 
				
			||||||
1. `cross_origin_renderer_url`: URL to a static HTML page hosting code to help display
 | 
					 | 
				
			||||||
   encrypted file attachments. This MUST be hosted on a completely separate domain to
 | 
					 | 
				
			||||||
   anything else since it is used to isolate the privileges of file attachments to this
 | 
					 | 
				
			||||||
   domain. Default: `https://usercontent.riot.im/v1.html`. This needs to contain v1.html from
 | 
					 | 
				
			||||||
   https://github.com/matrix-org/usercontent/blob/master/v1.html
 | 
					 | 
				
			||||||
1. `piwik`: an object containing the following properties:
 | 
					 | 
				
			||||||
    1. `url`: The URL of the Piwik instance to use for collecting Analytics
 | 
					 | 
				
			||||||
    1. `whitelistedHSUrls`: a list of HS URLs to not redact from the Analytics
 | 
					 | 
				
			||||||
    1. `whitelistedISUrls`: a list of IS URLs to not redact from the Analytics
 | 
					 | 
				
			||||||
    1. `siteId`: The Piwik Site ID to use when sending Analytics to the Piwik server configured above
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Running as a Desktop app
 | 
					Running as a Desktop app
 | 
				
			||||||
========================
 | 
					========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Riot can also be run as a desktop app, wrapped in electron. You can download a
 | 
					Riot can also be run as a desktop app, wrapped in Electron. You can download a
 | 
				
			||||||
pre-built version from https://riot.im/desktop.html or, if you prefer,
 | 
					pre-built version from https://riot.im/download/desktop/ or, if you prefer,
 | 
				
			||||||
build it yourself. Requires Electron >=1.6.0
 | 
					build it yourself.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To run as a desktop app:
 | 
					To build it yourself, follow the instructions below.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. Follow the instructions in 'Building From Source' above, but run
 | 
					1. Follow the instructions in 'Building From Source' above, but run
 | 
				
			||||||
   `npm run build` instead of `npm run dist` (since we don't need the tarball).
 | 
					   `yarn build` instead of `yarn dist` (since we don't need the tarball).
 | 
				
			||||||
2. Install electron and run it:
 | 
					2. Install Electron and run it:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   ```
 | 
					   ```bash
 | 
				
			||||||
   npm install electron
 | 
					   yarn electron
 | 
				
			||||||
   npm run electron
 | 
					 | 
				
			||||||
   ```
 | 
					   ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To build packages, use electron-builder. This is configured to output:
 | 
					To build packages, use `electron-builder`. This is configured to output:
 | 
				
			||||||
 * dmg + zip for macOS
 | 
					 * `dmg` + `zip` for macOS
 | 
				
			||||||
 * exe + nupkg for Windows
 | 
					 * `exe` + `nupkg` for Windows
 | 
				
			||||||
 * deb for Linux
 | 
					 * `deb` for Linux
 | 
				
			||||||
But this can be customised by editing the `build` section of package.json
 | 
					But this can be customised by editing the `build` section of package.json
 | 
				
			||||||
as per https://github.com/electron-userland/electron-builder/wiki/Options
 | 
					as per https://github.com/electron-userland/electron-builder/wiki/Options
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -165,59 +132,99 @@ See https://github.com/electron-userland/electron-builder/wiki/Multi-Platform-Bu
 | 
				
			|||||||
for dependencies required for building packages for various platforms.
 | 
					for dependencies required for building packages for various platforms.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The only platform that can build packages for all three platforms is macOS:
 | 
					The only platform that can build packages for all three platforms is macOS:
 | 
				
			||||||
```
 | 
					```bash
 | 
				
			||||||
brew install wine --without-x11
 | 
					 | 
				
			||||||
brew install mono
 | 
					brew install mono
 | 
				
			||||||
brew install gnu-tar
 | 
					yarn install
 | 
				
			||||||
npm install
 | 
					yarn build:electron
 | 
				
			||||||
npm run build:electron
 | 
					 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
For other packages, use electron-builder manually. For example, to build a package
 | 
					For other packages, use `electron-builder` manually. For example, to build a
 | 
				
			||||||
for 64 bit Linux:
 | 
					package for 64 bit Linux:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 1. Follow the instructions in 'Building From Source' above
 | 
					 1. Follow the instructions in 'Building From Source' above
 | 
				
			||||||
 2. `node_modules/.bin/build -l --x64`
 | 
					 2. `node_modules/.bin/build -l --x64`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
All electron packages go into `electron/dist/`
 | 
					All Electron packages go into `electron_app/dist/`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Many thanks to @aviraldg for the initial work on the electron integration.
 | 
					Many thanks to @aviraldg for the initial work on the Electron integration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Other options for running as a desktop app:
 | 
					Other options for running as a desktop app:
 | 
				
			||||||
 * https://github.com/krisak/vector-electron-desktop
 | 
					 | 
				
			||||||
 * @asdf:matrix.org points out that you can use nativefier and it just works(tm)
 | 
					 * @asdf:matrix.org points out that you can use nativefier and it just works(tm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```bash
 | 
				
			||||||
sudo npm install nativefier -g
 | 
					yarn global add nativefier
 | 
				
			||||||
nativefier https://riot.im/app/
 | 
					nativefier https://riot.im/app/
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The [configuration docs](docs/config.md#desktop-app-configuration) show how to
 | 
				
			||||||
 | 
					override the desktop app's default settings if desired.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Running from Docker
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The Docker image can be used to serve riot-web as a web server. The easiest way to use 
 | 
				
			||||||
 | 
					it is to use the prebuilt image:
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					docker run -p 80:80 vectorim/riot-web
 | 
				
			||||||
 | 
					``` 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To supply your own custom `config.json`, map a volume to `/app/config.json`. For example, 
 | 
				
			||||||
 | 
					if your custom config was located at `/etc/riot-web/config.json` then your Docker command
 | 
				
			||||||
 | 
					would be:
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					docker run -p 80:80 -v /etc/riot-web/config.json:/app/config.json vectorim/riot-web
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To build the image yourself:
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					git clone https://github.com/vector-im/riot-web.git riot-web
 | 
				
			||||||
 | 
					cd riot-web
 | 
				
			||||||
 | 
					git checkout master
 | 
				
			||||||
 | 
					docker build -t vectorim/riot-web .
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you're building a custom branch, or want to use the develop branch, check out the appropriate
 | 
				
			||||||
 | 
					riot-web branch and then run:
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					docker build -t vectorim/riot-web:develop \
 | 
				
			||||||
 | 
					    --build-arg USE_CUSTOM_SDKS=true \
 | 
				
			||||||
 | 
					    --build-arg REACT_SDK_REPO="https://github.com/matrix-org/matrix-react-sdk.git" \
 | 
				
			||||||
 | 
					    --build-arg REACT_SDK_BRANCH="develop" \
 | 
				
			||||||
 | 
					    --build-arg JS_SDK_REPO="https://github.com/matrix-org/matrix-js-sdk.git" \
 | 
				
			||||||
 | 
					    --build-arg JS_SDK_BRANCH="develop" \
 | 
				
			||||||
 | 
					    .
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config.json
 | 
				
			||||||
 | 
					===========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Riot supports a variety of settings to configure default servers, behaviour, themes, etc.
 | 
				
			||||||
 | 
					See the [configuration docs](docs/config.md) for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Labs Features
 | 
				
			||||||
 | 
					=============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Some features of Riot may be enabled by flags in the `Labs` section of the settings.
 | 
				
			||||||
 | 
					Some of these features are described in [labs.md](https://github.com/vector-im/riot-web/blob/develop/docs/labs.md).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Development
 | 
					Development
 | 
				
			||||||
===========
 | 
					===========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Before attempting to develop on Riot you **must** read the developer guide
 | 
					Before attempting to develop on Riot you **must** read the [developer guide
 | 
				
			||||||
for `matrix-react-sdk` at https://github.com/matrix-org/matrix-react-sdk, which
 | 
					for `matrix-react-sdk`](https://github.com/matrix-org/matrix-react-sdk), which
 | 
				
			||||||
also defines the design, architecture and style for Riot too.
 | 
					also defines the design, architecture and style for Riot too.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You should also familiarise yourself with the ["Here be Dragons" guide
 | 
				
			||||||
 | 
					](https://docs.google.com/document/d/12jYzvkidrp1h7liEuLIe6BMdU0NUjndUYI971O06ooM)
 | 
				
			||||||
 | 
					to the tame & not-so-tame dragons (gotchas) which exist in the codebase.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The idea of Riot is to be a relatively lightweight "skin" of customisations on
 | 
					The idea of Riot is to be a relatively lightweight "skin" of customisations on
 | 
				
			||||||
top of the underlying `matrix-react-sdk`. `matrix-react-sdk` provides both the
 | 
					top of the underlying `matrix-react-sdk`. `matrix-react-sdk` provides both the
 | 
				
			||||||
higher and lower level React components useful for building Matrix communication
 | 
					higher and lower level React components useful for building Matrix communication
 | 
				
			||||||
apps using React.
 | 
					apps using React.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
After creating a new component you must run `npm run reskindex` to regenerate
 | 
					After creating a new component you must run `yarn reskindex` to regenerate
 | 
				
			||||||
the `component-index.js` for the app (used in future for skinning)
 | 
					the `component-index.js` for the app (used in future for skinning).
 | 
				
			||||||
 | 
					 | 
				
			||||||
**However, as of July 2016 this layering abstraction is broken due to rapid
 | 
					 | 
				
			||||||
development on Riot forcing `matrix-react-sdk` to move fast at the expense of
 | 
					 | 
				
			||||||
maintaining a clear abstraction between the two.**  Hacking on Riot inevitably
 | 
					 | 
				
			||||||
means hacking equally on `matrix-react-sdk`, and there are bits of
 | 
					 | 
				
			||||||
`matrix-react-sdk` behaviour incorrectly residing in the `riot-web` project
 | 
					 | 
				
			||||||
(e.g. matrix-react-sdk specific CSS), and a bunch of Riot specific behaviour
 | 
					 | 
				
			||||||
in the `matrix-react-sdk` (grep for `vector` / `riot`).  This separation problem will be
 | 
					 | 
				
			||||||
solved asap once development on Riot (and thus matrix-react-sdk) has
 | 
					 | 
				
			||||||
stabilised.  Until then, the two projects should basically be considered as a
 | 
					 | 
				
			||||||
single unit.  In particular, `matrix-react-sdk` issues are currently filed
 | 
					 | 
				
			||||||
against `riot-web` in github.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Please note that Riot is intended to run correctly without access to the public
 | 
					Please note that Riot is intended to run correctly without access to the public
 | 
				
			||||||
internet.  So please don't depend on resources (JS libs, CSS, images, fonts)
 | 
					internet.  So please don't depend on resources (JS libs, CSS, images, fonts)
 | 
				
			||||||
@ -234,55 +241,67 @@ having to manually rebuild each time.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
First clone and build `matrix-js-sdk`:
 | 
					First clone and build `matrix-js-sdk`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. `git clone git@github.com:matrix-org/matrix-js-sdk.git`
 | 
					``` bash
 | 
				
			||||||
1. `pushd matrix-js-sdk`
 | 
					git clone https://github.com/matrix-org/matrix-js-sdk.git
 | 
				
			||||||
1. `git checkout develop`
 | 
					pushd matrix-js-sdk
 | 
				
			||||||
1. `npm install`
 | 
					git checkout develop
 | 
				
			||||||
1. `npm install source-map-loader` # because webpack is made of fail (https://github.com/webpack/webpack/issues/1472)
 | 
					yarn link
 | 
				
			||||||
1. `popd`
 | 
					yarn install
 | 
				
			||||||
 | 
					popd
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Then similarly with `matrix-react-sdk`:
 | 
					Then similarly with `matrix-react-sdk`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. `git clone git@github.com:matrix-org/matrix-react-sdk.git`
 | 
					```bash
 | 
				
			||||||
1. `pushd matrix-react-sdk`
 | 
					git clone https://github.com/matrix-org/matrix-react-sdk.git
 | 
				
			||||||
1. `git checkout develop`
 | 
					pushd matrix-react-sdk
 | 
				
			||||||
1. `npm install`
 | 
					git checkout develop
 | 
				
			||||||
1. `rm -r node_modules/matrix-js-sdk; ln -s ../../matrix-js-sdk node_modules/`
 | 
					yarn link
 | 
				
			||||||
1. `popd`
 | 
					yarn link matrix-js-sdk
 | 
				
			||||||
 | 
					yarn install
 | 
				
			||||||
 | 
					popd
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Finally, build and start Riot itself:
 | 
					Finally, build and start Riot itself:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. `git clone git@github.com:vector-im/riot-web.git`
 | 
					```bash
 | 
				
			||||||
1. `cd riot-web`
 | 
					git clone https://github.com/vector-im/riot-web.git
 | 
				
			||||||
1. `git checkout develop`
 | 
					cd riot-web
 | 
				
			||||||
1. `npm install`
 | 
					git checkout develop
 | 
				
			||||||
1. `rm -r node_modules/matrix-js-sdk; ln -s ../../matrix-js-sdk node_modules/`
 | 
					yarn link matrix-js-sdk
 | 
				
			||||||
1. `rm -r node_modules/matrix-react-sdk; ln -s ../../matrix-react-sdk node_modules/`
 | 
					yarn link matrix-react-sdk
 | 
				
			||||||
1. `npm start`
 | 
					yarn install
 | 
				
			||||||
1. Wait a few seconds for the initial build to finish; you should see something like:
 | 
					yarn start
 | 
				
			||||||
    ```
 | 
					```
 | 
				
			||||||
    Hash: b0af76309dd56d7275c8
 | 
					
 | 
				
			||||||
    Version: webpack 1.12.14
 | 
					Wait a few seconds for the initial build to finish; you should see something like:
 | 
				
			||||||
    Time: 14533ms
 | 
					```
 | 
				
			||||||
             Asset     Size  Chunks             Chunk Names
 | 
					Hash: b0af76309dd56d7275c8
 | 
				
			||||||
         bundle.js   4.2 MB       0  [emitted]  main
 | 
					Version: webpack 1.12.14
 | 
				
			||||||
        bundle.css  91.5 kB       0  [emitted]  main
 | 
					Time: 14533ms
 | 
				
			||||||
     bundle.js.map  5.29 MB       0  [emitted]  main
 | 
					         Asset     Size  Chunks             Chunk Names
 | 
				
			||||||
    bundle.css.map   116 kB       0  [emitted]  main
 | 
					     bundle.js   4.2 MB       0  [emitted]  main
 | 
				
			||||||
        + 1013 hidden modules
 | 
					    bundle.css  91.5 kB       0  [emitted]  main
 | 
				
			||||||
    ```
 | 
					 bundle.js.map  5.29 MB       0  [emitted]  main
 | 
				
			||||||
 | 
					bundle.css.map   116 kB       0  [emitted]  main
 | 
				
			||||||
 | 
					    + 1013 hidden modules
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
   Remember, the command will not terminate since it runs the web server
 | 
					   Remember, the command will not terminate since it runs the web server
 | 
				
			||||||
   and rebuilds source files when they change. This development server also
 | 
					   and rebuilds source files when they change. This development server also
 | 
				
			||||||
   disables caching, so do NOT use it in production.
 | 
					   disables caching, so do NOT use it in production.
 | 
				
			||||||
1. Open http://127.0.0.1:8080/ in your browser to see your newly built Riot.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
When you make changes to `matrix-react-sdk` or `matrix-js-sdk`, you will need
 | 
					Configure the app by copying `config.sample.json` to `config.json` and
 | 
				
			||||||
to run `npm run build` in the relevant directory. You can do this automatically
 | 
					modifying it. See the [configuration docs](docs/config.md) for details.
 | 
				
			||||||
by instead running `npm start` in the directory, to start a development builder
 | 
					
 | 
				
			||||||
which will watch for changes to the files and rebuild automatically.
 | 
					Open http://127.0.0.1:8080/ in your browser to see your newly built Riot.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					___
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When you make changes to `matrix-react-sdk` or `matrix-js-sdk` they should be
 | 
				
			||||||
 | 
					automatically picked up by webpack and built.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you add or remove any components from the Riot skin, you will need to rebuild
 | 
					If you add or remove any components from the Riot skin, you will need to rebuild
 | 
				
			||||||
the skin's index by running, `npm run reskindex`.
 | 
					the skin's index by running, `yarn reskindex`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If any of these steps error with, `file table overflow`, you are probably on a mac
 | 
					If any of these steps error with, `file table overflow`, you are probably on a mac
 | 
				
			||||||
which has a very low limit on max open files. Run `ulimit -Sn 1024` and try again.
 | 
					which has a very low limit on max open files. Run `ulimit -Sn 1024` and try again.
 | 
				
			||||||
@ -298,12 +317,12 @@ are designed to run in a browser instance under the control of
 | 
				
			|||||||
* Make sure you have Chrome installed (a recent version, like 59)
 | 
					* Make sure you have Chrome installed (a recent version, like 59)
 | 
				
			||||||
* Make sure you have `matrix-js-sdk` and `matrix-react-sdk` installed and
 | 
					* Make sure you have `matrix-js-sdk` and `matrix-react-sdk` installed and
 | 
				
			||||||
  built, as above
 | 
					  built, as above
 | 
				
			||||||
* `npm run test`
 | 
					* `yarn test`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The above will run the tests under Chrome in a `headless` mode.
 | 
					The above will run the tests under Chrome in a `headless` mode.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can also tell karma to run the tests in a loop (every time the source
 | 
					You can also tell karma to run the tests in a loop (every time the source
 | 
				
			||||||
changes), in an instance of Chrome on your desktop, with `npm run
 | 
					changes), in an instance of Chrome on your desktop, with `yarn
 | 
				
			||||||
test-multi`. This also gives you the option of running the tests in 'debug'
 | 
					test-multi`. This also gives you the option of running the tests in 'debug'
 | 
				
			||||||
mode, which is useful for stepping through the tests in the developer tools.
 | 
					mode, which is useful for stepping through the tests in the developer tools.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,13 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "default_hs_url": "https://matrix.org",
 | 
					    "default_server_config": {
 | 
				
			||||||
    "default_is_url": "https://vector.im",
 | 
					        "m.homeserver": {
 | 
				
			||||||
 | 
					            "base_url": "https://matrix.org",
 | 
				
			||||||
 | 
					            "server_name": "matrix.org"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "m.identity_server": {
 | 
				
			||||||
 | 
					            "base_url": "https://vector.im"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "disable_custom_urls": false,
 | 
					    "disable_custom_urls": false,
 | 
				
			||||||
    "disable_guests": false,
 | 
					    "disable_guests": false,
 | 
				
			||||||
    "disable_login_language_selector": false,
 | 
					    "disable_login_language_selector": false,
 | 
				
			||||||
@ -8,13 +15,24 @@
 | 
				
			|||||||
    "brand": "Riot",
 | 
					    "brand": "Riot",
 | 
				
			||||||
    "integrations_ui_url": "https://scalar.vector.im/",
 | 
					    "integrations_ui_url": "https://scalar.vector.im/",
 | 
				
			||||||
    "integrations_rest_url": "https://scalar.vector.im/api",
 | 
					    "integrations_rest_url": "https://scalar.vector.im/api",
 | 
				
			||||||
 | 
					    "integrations_widgets_urls": [
 | 
				
			||||||
 | 
					        "https://scalar.vector.im/_matrix/integrations/v1",
 | 
				
			||||||
 | 
					        "https://scalar.vector.im/api",
 | 
				
			||||||
 | 
					        "https://scalar-staging.vector.im/_matrix/integrations/v1",
 | 
				
			||||||
 | 
					        "https://scalar-staging.vector.im/api",
 | 
				
			||||||
 | 
					        "https://scalar-staging.riot.im/scalar/api"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "integrations_jitsi_widget_url": "https://scalar.vector.im/api/widgets/jitsi.html",
 | 
				
			||||||
    "bug_report_endpoint_url": "https://riot.im/bugreports/submit",
 | 
					    "bug_report_endpoint_url": "https://riot.im/bugreports/submit",
 | 
				
			||||||
 | 
					    "defaultCountryCode": "GB",
 | 
				
			||||||
 | 
					    "showLabsSettings": false,
 | 
				
			||||||
    "features": {
 | 
					    "features": {
 | 
				
			||||||
        "feature_groups": "labs",
 | 
					        "feature_pinning": "labs",
 | 
				
			||||||
        "feature_pinning": "labs"
 | 
					        "feature_custom_status": "labs",
 | 
				
			||||||
 | 
					        "feature_custom_tags": "labs",
 | 
				
			||||||
 | 
					        "feature_state_counters": "labs"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "default_federate": true,
 | 
					    "default_federate": true,
 | 
				
			||||||
    "welcomePageUrl": "home.html",
 | 
					 | 
				
			||||||
    "default_theme": "light",
 | 
					    "default_theme": "light",
 | 
				
			||||||
    "roomDirectory": {
 | 
					    "roomDirectory": {
 | 
				
			||||||
        "servers": [
 | 
					        "servers": [
 | 
				
			||||||
@ -27,5 +45,11 @@
 | 
				
			|||||||
        "whitelistedHSUrls": ["https://matrix.org"],
 | 
					        "whitelistedHSUrls": ["https://matrix.org"],
 | 
				
			||||||
        "whitelistedISUrls": ["https://vector.im", "https://matrix.org"],
 | 
					        "whitelistedISUrls": ["https://vector.im", "https://matrix.org"],
 | 
				
			||||||
        "siteId": 1
 | 
					        "siteId": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "enable_presence_by_hs_url": {
 | 
				
			||||||
 | 
					        "https://matrix.org": false
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "settingDefaults": {
 | 
				
			||||||
 | 
					        "breadcrumbs": true
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										119
									
								
								docs/config.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,119 @@
 | 
				
			|||||||
 | 
					Configuration
 | 
				
			||||||
 | 
					=============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can configure the app by copying `config.sample.json` to
 | 
				
			||||||
 | 
					`config.json` and customising it:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For a good example, see https://riot.im/develop/config.json.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. `default_server_config` sets the default homeserver and identity server URL for
 | 
				
			||||||
 | 
					   Riot to use. The object is the same as returned by [https://<server_name>/.well-known/matrix/client](https://matrix.org/docs/spec/client_server/latest.html#get-well-known-matrix-client),
 | 
				
			||||||
 | 
					   with added support for a `server_name` under the `m.homeserver` section to display
 | 
				
			||||||
 | 
					   a custom homeserver name. Alternatively, the config can contain a `default_server_name`
 | 
				
			||||||
 | 
					   instead which is where Riot will go to get that same object, although this option is
 | 
				
			||||||
 | 
					   deprecated - see the `.well-known` link above for more information on using this option.
 | 
				
			||||||
 | 
					   Note that the `default_server_name` is used to get a complete server configuration
 | 
				
			||||||
 | 
					   whereas the `server_name` in the `default_server_config` is for display purposes only.
 | 
				
			||||||
 | 
					   * *Note*: The URLs can also be individually specified as `default_hs_url` and
 | 
				
			||||||
 | 
					     `default_is_url`, however these are deprecated. They are maintained for backwards
 | 
				
			||||||
 | 
					     compatibility with older configurations. `default_is_url` is respected only
 | 
				
			||||||
 | 
					     if `default_hs_url` is used.
 | 
				
			||||||
 | 
					   * The identity server is used for verifying third party identifiers like emails
 | 
				
			||||||
 | 
					     and phone numbers. It is not used to store your password or account information.
 | 
				
			||||||
 | 
					     If not provided, the identity server defaults to vector.im. Currently the only
 | 
				
			||||||
 | 
					     two public identity servers are https://matrix.org and https://vector.im, however
 | 
				
			||||||
 | 
					     in future identity servers will be decentralised. In the future it will be possible
 | 
				
			||||||
 | 
					     to disable the identity server functionality.
 | 
				
			||||||
 | 
					   * Riot will fail to load if a mix of `default_server_config`, `default_server_name`, or
 | 
				
			||||||
 | 
					     `default_hs_url` is specified. When multiple sources are specified, it is unclear
 | 
				
			||||||
 | 
					     which should take priority and therefore the application cannot continue.
 | 
				
			||||||
 | 
					1. `features`: Lookup of optional features that may be `enable`d, `disable`d, or exposed to the user
 | 
				
			||||||
 | 
					   in the `labs` section of settings.  The available optional experimental features vary from
 | 
				
			||||||
 | 
					   release to release. The available features are described in [labs.md](labs.md).
 | 
				
			||||||
 | 
					1. `showLabsSettings`: Shows the "labs" tab of user settings even when no `features` are enabled
 | 
				
			||||||
 | 
					   or present. Useful for getting at settings which may be otherwise hidden.
 | 
				
			||||||
 | 
					1. `brand`: String to pass to your homeserver when configuring email notifications, to let the
 | 
				
			||||||
 | 
					   homeserver know what email template to use when talking to you.
 | 
				
			||||||
 | 
					1. `branding`: Configures various branding and logo details, such as:
 | 
				
			||||||
 | 
					    1. `welcomeBackgroundUrl`: An image to use as a wallpaper outside the app
 | 
				
			||||||
 | 
					       during authentication flows
 | 
				
			||||||
 | 
					    1. `authHeaderLogoUrl`: An logo image that is shown in the header during
 | 
				
			||||||
 | 
					       authentication flows
 | 
				
			||||||
 | 
					    1. `authFooterLinks`: a list of links to show in the authentication page footer:
 | 
				
			||||||
 | 
					      `[{"text": "Link text", "url": "https://link.target"}, {"text": "Other link", ...}]`
 | 
				
			||||||
 | 
					1. `integrations_ui_url`: URL to the web interface for the integrations server. The integrations
 | 
				
			||||||
 | 
					   server is not Riot and normally not your homeserver either. The integration server settings
 | 
				
			||||||
 | 
					   may be left blank to disable integrations.
 | 
				
			||||||
 | 
					1. `integrations_rest_url`: URL to the REST interface for the integrations server.
 | 
				
			||||||
 | 
					1. `integrations_widgets_urls`: list of URLs to the REST interface for the widget integrations server.
 | 
				
			||||||
 | 
					1. `bug_report_endpoint_url`: endpoint to send bug reports to (must be running a
 | 
				
			||||||
 | 
					   https://github.com/matrix-org/rageshake server). Bug reports are sent when a user clicks
 | 
				
			||||||
 | 
					   "Send Logs" within the application. Bug reports can be disabled by leaving the
 | 
				
			||||||
 | 
					   `bug_report_endpoint_url` out of your config file.
 | 
				
			||||||
 | 
					1. `roomDirectory`: config for the public room directory. This section is optional.
 | 
				
			||||||
 | 
					1. `roomDirectory.servers`: List of other homeservers' directories to include in the drop
 | 
				
			||||||
 | 
					   down list. Optional.
 | 
				
			||||||
 | 
					1. `default_theme`: name of theme to use by default (e.g. 'light')
 | 
				
			||||||
 | 
					1. `update_base_url` (electron app only): HTTPS URL to a web server to download
 | 
				
			||||||
 | 
					   updates from. This should be the path to the directory containing `macos`
 | 
				
			||||||
 | 
					   and `win32` (for update packages, not installer packages).
 | 
				
			||||||
 | 
					1. `cross_origin_renderer_url`: URL to a static HTML page hosting code to help display
 | 
				
			||||||
 | 
					   encrypted file attachments. This MUST be hosted on a completely separate domain to
 | 
				
			||||||
 | 
					   anything else since it is used to isolate the privileges of file attachments to this
 | 
				
			||||||
 | 
					   domain. Default: `https://usercontent.riot.im/v1.html`. This needs to contain v1.html from
 | 
				
			||||||
 | 
					   https://github.com/matrix-org/usercontent/blob/master/v1.html
 | 
				
			||||||
 | 
					1. `piwik`: Analytics can be disabled by setting `piwik: false` or by leaving the piwik config
 | 
				
			||||||
 | 
					   option out of your config file. If you want to enable analytics, set `piwik` to be an object
 | 
				
			||||||
 | 
					   containing the following properties:
 | 
				
			||||||
 | 
					    1. `url`: The URL of the Piwik instance to use for collecting analytics
 | 
				
			||||||
 | 
					    1. `whitelistedHSUrls`: a list of HS URLs to not redact from the analytics
 | 
				
			||||||
 | 
					    1. `whitelistedISUrls`: a list of IS URLs to not redact from the analytics
 | 
				
			||||||
 | 
					    1. `siteId`: The Piwik Site ID to use when sending analytics to the Piwik server configured above
 | 
				
			||||||
 | 
					1. `welcomeUserId`: the user ID of a bot to invite whenever users register that can give them a tour
 | 
				
			||||||
 | 
					1. `embeddedPages`: Configures the pages displayed in portions of Riot that
 | 
				
			||||||
 | 
					   embed static files, such as:
 | 
				
			||||||
 | 
					    1. `welcomeUrl`: Initial content shown on the outside of the app when not
 | 
				
			||||||
 | 
					       logged in. Defaults to `welcome.html` supplied with Riot.
 | 
				
			||||||
 | 
					    1. `homeUrl`: Content shown on the inside of the app when a specific room is
 | 
				
			||||||
 | 
					       not selected. By default, no home page is configured. If one is set, a
 | 
				
			||||||
 | 
					       button to access it will be shown in the top left menu.
 | 
				
			||||||
 | 
					1. `defaultCountryCode`: The ISO 3166 alpha2 country code to use when showing
 | 
				
			||||||
 | 
					   country selectors, like the phone number input on the registration page.
 | 
				
			||||||
 | 
					   Defaults to `GB` if the given code is unknown or not provided.
 | 
				
			||||||
 | 
					1. `settingDefaults`:  Defaults for settings that support the `config` level,
 | 
				
			||||||
 | 
					   as an object mapping setting name to value (note that the "theme" setting
 | 
				
			||||||
 | 
					   is special cased to the `default_theme` in the config file).
 | 
				
			||||||
 | 
					1. `disable_custom_urls`: disallow the user to change the
 | 
				
			||||||
 | 
					   default homeserver when signing up or logging in.
 | 
				
			||||||
 | 
					1. `permalinkPrefix`: Used to change the URL that Riot generates permalinks with.
 | 
				
			||||||
 | 
					   By default, this is "https://matrix.to" to generate matrix.to (spec) permalinks.
 | 
				
			||||||
 | 
					   Set this to your Riot instance URL if you run an unfederated server (eg: 
 | 
				
			||||||
 | 
					   "https://riot.example.org").
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that `index.html` also has an og:image meta tag that is set to an image
 | 
				
			||||||
 | 
					hosted on riot.im. This is the image used if links to your copy of Riot
 | 
				
			||||||
 | 
					appear in some websites like Facebook, and indeed Riot itself. This has to be
 | 
				
			||||||
 | 
					static in the HTML and an absolute URL (and HTTP rather than HTTPS), so it's
 | 
				
			||||||
 | 
					not possible for this to be an option in config.json. If you'd like to change
 | 
				
			||||||
 | 
					it, you can build Riot, but run
 | 
				
			||||||
 | 
					`RIOT_OG_IMAGE_URL="http://example.com/logo.png" yarn build`.
 | 
				
			||||||
 | 
					Alternatively, you can edit the `og:image` meta tag in `index.html` directly
 | 
				
			||||||
 | 
					each time you download a new version of Riot.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Desktop app configuration
 | 
				
			||||||
 | 
					=========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To run multiple instances of the desktop app for different accounts, you can
 | 
				
			||||||
 | 
					launch the executable with the `--profile` argument followed by a unique
 | 
				
			||||||
 | 
					identifier, e.g `riot-web --profile Work` for it to run a separate profile and
 | 
				
			||||||
 | 
					not interfere with the default one.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Alternatively, a custom location for the profile data can be specified using the
 | 
				
			||||||
 | 
					`--profile-dir` flag followed by the desired path.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ `%APPDATA%\$NAME\config.json` on Windows
 | 
				
			||||||
 | 
					+ `$XDG_CONFIG_HOME\$NAME\config.json` or `~/.config/$NAME/config.json` on Linux
 | 
				
			||||||
 | 
					+ `~Library/Application Support/$NAME/config.json` on macOS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In the paths above, `$NAME` is typically `Riot`, unless you use `--profile
 | 
				
			||||||
 | 
					$PROFILE` in which case it becomes `Riot-$PROFILE`.
 | 
				
			||||||
							
								
								
									
										51
									
								
								docs/labs.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					# Labs features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Some notes on the features you can enable by going to `Settings->Labs`. Not exhaustive, chat in
 | 
				
			||||||
 | 
					[#riot-web:matrix.org](https://matrix.to/#/#riot-web:matrix.org) for more information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Be warned! Labs features are not finalised, they may be fragile, they may change, they may be
 | 
				
			||||||
 | 
					dropped. Ask in the room if you are unclear about any details here.**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Message pinning (`feature_pinning`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Allows you to pin messages in the room. To pin a message, use the 3 dots to the right of the message
 | 
				
			||||||
 | 
					and select "Pin".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Custom status (`feature_custom_status`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					An experimental approach for supporting custom status messages across DMs. To set a status, click on
 | 
				
			||||||
 | 
					your avatar next to the message composer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Custom tags (`feature_custom_tags`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					An experimental approach for dealing with custom tags. Custom tags will appear in the bottom portion
 | 
				
			||||||
 | 
					of the community filter panel.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Setting custom tags is not supported by Riot.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Render simple counters in room header (`feature_state_counters`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Allows rendering of labelled counters above the message list.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Once enabled, send a custom state event to a room to set values:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. In a room, type `/devtools` to bring up the devtools interface
 | 
				
			||||||
 | 
					2. Click "Send Custom Event"
 | 
				
			||||||
 | 
					3. Toggle from "Event" to "State Event"
 | 
				
			||||||
 | 
					4. Set the event type to: `re.jki.counter` and give it a unique key
 | 
				
			||||||
 | 
					5. Specify the content in the following format:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "link": "",
 | 
				
			||||||
 | 
					    "severity": "normal",
 | 
				
			||||||
 | 
					    "title": "my counter",
 | 
				
			||||||
 | 
					    "value": 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					That's it. Now should see your new counter under the header.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Multiple integration managers (`feature_many_integration_managers`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Exposes a way to access all the integration managers known to Riot. This is an implementation of [MSC1957](https://github.com/matrix-org/matrix-doc/pull/1957).
 | 
				
			||||||
							
								
								
									
										53
									
								
								docs/memory-profiles-and-leaks.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					## Memory leaks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Riot usually emits slow behaviour just before it is about to crash. Getting a 
 | 
				
			||||||
 | 
					memory snapshot (below) just before that happens is ideal in figuring out what
 | 
				
			||||||
 | 
					is going wrong.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Common symptoms are clicking on a room and it feels like the tab froze and scrolling
 | 
				
			||||||
 | 
					becoming jumpy/staggered. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you receive a white screen (electron) or the chrome crash page, it is likely
 | 
				
			||||||
 | 
					run out of memory and it is too late for a memory profile. Please do report when
 | 
				
			||||||
 | 
					this happens though so we can try and narrow down what might have gone wrong.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Memory profiles/snapshots
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When investigating memory leaks/problems it's usually important to compare snapshots
 | 
				
			||||||
 | 
					from different points in the Riot session lifecycle. Most importantly, a snapshot
 | 
				
			||||||
 | 
					to establish the baseline or "normal" memory usage is useful. Taking a snapshot
 | 
				
			||||||
 | 
					roughly 30-60 minutes after starting Riot is a good time to establish "normal"
 | 
				
			||||||
 | 
					memory usage for the app - anything after that is at risk of hiding the memory leak
 | 
				
			||||||
 | 
					and anything newer is still in the warmup stages of the app.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Memory profiles can contain sensitive information.** If you are submitting a memory
 | 
				
			||||||
 | 
					profile to us for debugging purposes, please pick the appropriate Riot developer and
 | 
				
			||||||
 | 
					send them over an encrypted private message. *Do not share your memory profile in
 | 
				
			||||||
 | 
					public channels or with people you do not trust.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Taking a memory profile (Firefox)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Press CTRL+SHIFT+I (I as in eye).
 | 
				
			||||||
 | 
					2. Click the Memory tab.
 | 
				
			||||||
 | 
					3. Press the camera icon in the top left of the pane.
 | 
				
			||||||
 | 
					4. Wait a bit (coffee is a good option).
 | 
				
			||||||
 | 
					5. When the save button appears on the left side of the panel, click it to save the
 | 
				
			||||||
 | 
					   profile locally.
 | 
				
			||||||
 | 
					6. Compress the file (gzip or regular zip) to make the file smaller.
 | 
				
			||||||
 | 
					7. Send the compressed file to whoever asked for it (if you trust them).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					While the profile is in progress, the tab might be frozen or unresponsive.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Taking a memory profile (Chrome/Desktop)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Press CTRL+SHIFT+I (I as in eye).
 | 
				
			||||||
 | 
					2. Click the Memory tab.
 | 
				
			||||||
 | 
					3. Select "Heap Snapshot" and the riot.im VM instance (not the indexeddb one).
 | 
				
			||||||
 | 
					4. Click "Take Snapshot".
 | 
				
			||||||
 | 
					5. Wait a bit (coffee is a good option).
 | 
				
			||||||
 | 
					6. When the save button appears on the left side of the panel, click it to save the
 | 
				
			||||||
 | 
					   profile locally.
 | 
				
			||||||
 | 
					7. Compress the file (gzip or regular zip) to make the file smaller.
 | 
				
			||||||
 | 
					8. Send the compressed file to whoever asked for it (if you trust them).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					While the profile is in progress, the tab might be frozen or unresponsive.
 | 
				
			||||||
							
								
								
									
										13
									
								
								docs/shortcuts.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					# Keyboard Shortcuts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The modifier is <kbd>Ctrl</kbd> on Windows & Linux and <kbd>⌘</kbd> on Mac.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>m</kbd> - toggle markdown
 | 
				
			||||||
 | 
					- <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>d</kbd> - toggle mic mute
 | 
				
			||||||
 | 
					- <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>e</kbd> - toggle video on/off
 | 
				
			||||||
 | 
					- <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>k</kbd> - jump to named room
 | 
				
			||||||
 | 
					- <kbd>↑</kbd>/<kbd>↓</kbd> - navigate old messages to edit when the composer is in focus
 | 
				
			||||||
 | 
					- <kbd>↑</kbd>/<kbd>↓</kbd> - next/prev room when focus in room list
 | 
				
			||||||
 | 
					- <kbd>Alt</kbd>+<kbd>↑</kbd>/<kbd>↓</kbd> - resend previous messages when the composer is in focus
 | 
				
			||||||
 | 
					- <kbd>PageUp</kbd>/<kbd>PageDown</kbd> - scroll timeline up/down
 | 
				
			||||||
 | 
					- <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>Home</kbd>/<kbd>End</kbd> - jump to timeline start/end
 | 
				
			||||||
@ -3,6 +3,8 @@
 | 
				
			|||||||
## Requirements
 | 
					## Requirements
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- A working [Development Setup](../../#setting-up-a-dev-environment)
 | 
					- A working [Development Setup](../../#setting-up-a-dev-environment)
 | 
				
			||||||
 | 
					  - Including up-to-date versions of matrix-react-sdk and matrix-js-sdk
 | 
				
			||||||
 | 
					- Latest LTS version of Node.js installed
 | 
				
			||||||
- Be able to understand English
 | 
					- Be able to understand English
 | 
				
			||||||
- Be able to understand the language you want to translate riot-web into
 | 
					- Be able to understand the language you want to translate riot-web into
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -30,9 +32,15 @@ function getColorName(hex) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 1. Check if the import ``import { _t } from 'matrix-react-sdk/lib/languageHandler';`` is present. If not add it to the other import statements. Also import `_td` if needed.
 | 
					 1. Check if the import ``import { _t } from 'matrix-react-sdk/lib/languageHandler';`` is present. If not add it to the other import statements. Also import `_td` if needed.
 | 
				
			||||||
 1. Add ``_t()`` to your string. (Don't forget curly braces when you assign an expression to JSX attributes in the render method). If the string is introduced at a point before the translation system has not yet been initialized, use `_td()` instead, and call `_t()` at the appropriate time.
 | 
					 1. Add ``_t()`` to your string. (Don't forget curly braces when you assign an expression to JSX attributes in the render method). If the string is introduced at a point before the translation system has not yet been initialized, use `_td()` instead, and call `_t()` at the appropriate time.
 | 
				
			||||||
 1. Run `npm run i18n` to update ``src/i18n/strings/en_EN.json`` (if it fails because it can't find the script, your dev environment predates the script, so reinstall/link react-sdk with `npm link ../matrix-react-sdk`). If it segfaults, you may be on Node 6, so try a newer version of node.
 | 
					 1. Run `yarn i18n` to update ``src/i18n/strings/en_EN.json``
 | 
				
			||||||
 1. If you added a string with a plural, you can add other English plural variants to ``src/i18n/strings/en_EN.json`` (remeber to edit the one in the same project as the source file containing your new translation).
 | 
					 1. If you added a string with a plural, you can add other English plural variants to ``src/i18n/strings/en_EN.json`` (remeber to edit the one in the same project as the source file containing your new translation).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Editing existing strings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Edit every occurrence of the string inside `_t()` and `_td()` in the JSX files.
 | 
				
			||||||
 | 
					1. Run `yarn i18n` to update `src/i18n/strings/en_EN.json`. (Be sure to run this in the same project as the JSX files you just edited.)
 | 
				
			||||||
 | 
					1. Run `yarn prunei18n` to remove the old string from `src/i18n/strings/*.json`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Adding variables inside a string.
 | 
					## Adding variables inside a string.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. Extend your ``_t()`` call. Instead of ``_t(STRING)`` use ``_t(STRING, {})``
 | 
					1. Extend your ``_t()`` call. Instead of ``_t(STRING)`` use ``_t(STRING, {})``
 | 
				
			||||||
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 36 KiB  | 
| 
		 Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 6.2 KiB  | 
| 
		 Before Width: | Height: | Size: 673 B After Width: | Height: | Size: 702 B  | 
| 
		 Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB  | 
| 
		 Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB  | 
| 
		 Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.2 KiB  | 
| 
		 Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 29 KiB  | 
| 
		 Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.0 KiB  | 
| 
		 Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 4.5 KiB  | 
| 
		 Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 5.4 KiB  | 
							
								
								
									
										14
									
								
								electron_app/build/linux/after-install.tpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Link to the binary
 | 
				
			||||||
 | 
					ln -sf '/opt/${productFilename}/${executable}' '/usr/bin/${executable}'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# SUID chrome-sandbox for Electron 5+
 | 
				
			||||||
 | 
					# Remove this entire file (after-install.tpl) and remove the reference in
 | 
				
			||||||
 | 
					# package.json once this change has been upstreamed so we go back to the copy
 | 
				
			||||||
 | 
					# from upstream.
 | 
				
			||||||
 | 
					# https://github.com/electron-userland/electron-builder/pull/4163
 | 
				
			||||||
 | 
					chmod 4755 '/opt/${productFilename}/chrome-sandbox' || true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					update-mime-database /usr/share/mime || true
 | 
				
			||||||
 | 
					update-desktop-database /usr/share/applications || true
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 36 KiB  | 
| 
		 Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 13 KiB  | 
@ -2,11 +2,12 @@
 | 
				
			|||||||
  "name": "riot-web",
 | 
					  "name": "riot-web",
 | 
				
			||||||
  "productName": "Riot",
 | 
					  "productName": "Riot",
 | 
				
			||||||
  "main": "src/electron-main.js",
 | 
					  "main": "src/electron-main.js",
 | 
				
			||||||
  "version": "0.13.5",
 | 
					  "version": "1.5.0",
 | 
				
			||||||
  "description": "A feature-rich client for Matrix.org",
 | 
					  "description": "A feature-rich client for Matrix.org",
 | 
				
			||||||
  "author": "Vector Creations Ltd.",
 | 
					  "author": "New Vector Ltd.",
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "auto-launch": "^5.0.1",
 | 
					    "auto-launch": "^5.0.1",
 | 
				
			||||||
 | 
					    "electron-store": "^2.0.0",
 | 
				
			||||||
    "electron-window-state": "^4.1.0",
 | 
					    "electron-window-state": "^4.1.0",
 | 
				
			||||||
    "minimist": "^1.2.0",
 | 
					    "minimist": "^1.2.0",
 | 
				
			||||||
    "png-to-ico": "^1.0.2"
 | 
					    "png-to-ico": "^1.0.2"
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,6 @@
 | 
				
			|||||||
This directory contains the config file for the official riot.im distribution
 | 
					This directory contains the config file for the official riot.im distribution
 | 
				
			||||||
of Riot Desktop. You probably do not want to build with this config unless
 | 
					of Riot Desktop.
 | 
				
			||||||
you're building the official riot.im distribution, or you'll find your builds
 | 
					
 | 
				
			||||||
will replace themselves with the riot.im build.
 | 
					You probably do not want to build with this config unless you're building the
 | 
				
			||||||
 | 
					official riot.im distribution, or you'll find your builds will replace
 | 
				
			||||||
 | 
					themselves with the riot.im build.
 | 
				
			||||||
 | 
				
			|||||||
@ -1,14 +1,17 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "update_base_url": "https://riot.im/download/desktop/update/",
 | 
					    "update_base_url": "https://packages.riot.im/desktop/update/",
 | 
				
			||||||
    "default_hs_url": "https://matrix.org",
 | 
					    "default_server_name": "matrix.org",
 | 
				
			||||||
    "default_is_url": "https://vector.im",
 | 
					 | 
				
			||||||
    "brand": "Riot",
 | 
					    "brand": "Riot",
 | 
				
			||||||
    "integrations_ui_url": "https://scalar.vector.im/",
 | 
					    "integrations_ui_url": "https://scalar.vector.im/",
 | 
				
			||||||
    "integrations_rest_url": "https://scalar.vector.im/api",
 | 
					    "integrations_rest_url": "https://scalar.vector.im/api",
 | 
				
			||||||
    "integrations_widgets_urls": [
 | 
					    "integrations_widgets_urls": [
 | 
				
			||||||
        "https://scalar-staging.riot.im/scalar/api",
 | 
					        "https://scalar.vector.im/_matrix/integrations/v1",
 | 
				
			||||||
        "https://scalar.vector.im/api"
 | 
					        "https://scalar.vector.im/api",
 | 
				
			||||||
 | 
					        "https://scalar-staging.vector.im/_matrix/integrations/v1",
 | 
				
			||||||
 | 
					        "https://scalar-staging.vector.im/api",
 | 
				
			||||||
 | 
					        "https://scalar-staging.riot.im/scalar/api"
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "hosting_signup_link": "https://modular.im/?utm_source=riot-web&utm_medium=web",
 | 
				
			||||||
    "bug_report_endpoint_url": "https://riot.im/bugreports/submit",
 | 
					    "bug_report_endpoint_url": "https://riot.im/bugreports/submit",
 | 
				
			||||||
    "welcomeUserId": "@riot-bot:matrix.org",
 | 
					    "welcomeUserId": "@riot-bot:matrix.org",
 | 
				
			||||||
    "roomDirectory": {
 | 
					    "roomDirectory": {
 | 
				
			||||||
@ -18,6 +21,19 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "piwik": {
 | 
					    "piwik": {
 | 
				
			||||||
        "url": "https://piwik.riot.im/",
 | 
					        "url": "https://piwik.riot.im/",
 | 
				
			||||||
        "siteId": 1
 | 
					        "siteId": 1,
 | 
				
			||||||
 | 
					        "policyUrl": "https://matrix.org/docs/guides/riot_im_cookie_policy"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "phasedRollOut": {
 | 
				
			||||||
 | 
					        "feature_lazyloading": {
 | 
				
			||||||
 | 
					            "offset": 1539684000000,
 | 
				
			||||||
 | 
					            "period": 604800000
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "features": {
 | 
				
			||||||
 | 
					        "feature_lazyloading": "enable"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "enable_presence_by_hs_url": {
 | 
				
			||||||
 | 
					        "https://matrix.org": false
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								electron_app/riot.im/env.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					export OSSLSIGNCODE_SIGNARGS='-pkcs11module /Library/Frameworks/eToken.framework/Versions/Current/libeToken.dylib -pkcs11engine /usr/local/lib/engines/engine_pkcs11.so -certs electron_app/riot.im/New_Vector_Ltd.pem -key 0a3271cbc1ec0fd8afb37f6bbe0cd65ba08d3b4d -t http://timestamp.comodoca.com -h sha256 -verbose'
 | 
				
			||||||
@ -1,7 +1,8 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
Copyright 2016 Aviral Dasgupta
 | 
					Copyright 2016 Aviral Dasgupta
 | 
				
			||||||
Copyright 2016 OpenMarket Ltd
 | 
					Copyright 2016 OpenMarket Ltd
 | 
				
			||||||
Copyright 2017 Michael Telatynski <7t3chguy@gmail.com>
 | 
					Copyright 2018, 2019 New Vector Ltd
 | 
				
			||||||
 | 
					Copyright 2017, 2019 Michael Telatynski <7t3chguy@gmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
@ -22,19 +23,45 @@ limitations under the License.
 | 
				
			|||||||
const checkSquirrelHooks = require('./squirrelhooks');
 | 
					const checkSquirrelHooks = require('./squirrelhooks');
 | 
				
			||||||
if (checkSquirrelHooks()) return;
 | 
					if (checkSquirrelHooks()) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const argv = require('minimist')(process.argv);
 | 
					const argv = require('minimist')(process.argv, {
 | 
				
			||||||
const electron = require('electron');
 | 
					    alias: {help: "h"},
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const {app, ipcMain, powerSaveBlocker, BrowserWindow, Menu, autoUpdater, protocol} = require('electron');
 | 
				
			||||||
const AutoLaunch = require('auto-launch');
 | 
					const AutoLaunch = require('auto-launch');
 | 
				
			||||||
 | 
					const path = require('path');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const tray = require('./tray');
 | 
					const tray = require('./tray');
 | 
				
			||||||
const vectorMenu = require('./vectormenu');
 | 
					const vectorMenu = require('./vectormenu');
 | 
				
			||||||
const webContentsHandler = require('./webcontents-handler');
 | 
					const webContentsHandler = require('./webcontents-handler');
 | 
				
			||||||
const updater = require('./updater');
 | 
					const updater = require('./updater');
 | 
				
			||||||
 | 
					const { migrateFromOldOrigin } = require('./originMigrator');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const windowStateKeeper = require('electron-window-state');
 | 
					const windowStateKeeper = require('electron-window-state');
 | 
				
			||||||
 | 
					const Store = require('electron-store');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (argv.profile) {
 | 
					if (argv["help"]) {
 | 
				
			||||||
    electron.app.setPath('userData', `${electron.app.getPath('userData')}-${argv.profile}`);
 | 
					    console.log("Options:");
 | 
				
			||||||
 | 
					    console.log("  --profile-dir {path}: Path to where to store the profile.");
 | 
				
			||||||
 | 
					    console.log("  --profile {name}:     Name of alternate profile to use, allows for running multiple accounts.");
 | 
				
			||||||
 | 
					    console.log("  --devtools:           Install and use react-devtools and react-perf.");
 | 
				
			||||||
 | 
					    console.log("  --no-update:          Disable automatic updating.");
 | 
				
			||||||
 | 
					    console.log("  --hidden:             Start the application hidden in the system tray.");
 | 
				
			||||||
 | 
					    console.log("  --help:               Displays this help message.");
 | 
				
			||||||
 | 
					    console.log("And more such as --proxy, see:" +
 | 
				
			||||||
 | 
					        "https://github.com/electron/electron/blob/master/docs/api/chrome-command-line-switches.md");
 | 
				
			||||||
 | 
					    app.exit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// boolean flag set whilst we are doing one-time origin migration
 | 
				
			||||||
 | 
					// We only serve the origin migration script while we're actually
 | 
				
			||||||
 | 
					// migrating to mitigate any risk of it being used maliciously.
 | 
				
			||||||
 | 
					let migratingOrigin = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (argv['profile-dir']) {
 | 
				
			||||||
 | 
					    app.setPath('userData', argv['profile-dir']);
 | 
				
			||||||
 | 
					} else if (argv['profile']) {
 | 
				
			||||||
 | 
					    app.setPath('userData', `${app.getPath('userData')}-${argv['profile']}`);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let vectorConfig = {};
 | 
					let vectorConfig = {};
 | 
				
			||||||
@ -47,8 +74,19 @@ try {
 | 
				
			|||||||
    // Continue with the defaults (ie. an empty config)
 | 
					    // Continue with the defaults (ie. an empty config)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					try {
 | 
				
			||||||
 | 
					    // Load local config and use it to override values from the one baked with the build
 | 
				
			||||||
 | 
					    const localConfig = require(path.join(app.getPath('userData'), 'config.json'));
 | 
				
			||||||
 | 
					    vectorConfig = Object.assign(vectorConfig, localConfig);
 | 
				
			||||||
 | 
					} catch (e) {
 | 
				
			||||||
 | 
					    // Could not load local config, this is expected in most cases.
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const store = new Store({ name: "electron-config" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let mainWindow = null;
 | 
					let mainWindow = null;
 | 
				
			||||||
global.appQuitting = false;
 | 
					global.appQuitting = false;
 | 
				
			||||||
 | 
					global.minimizeToTray = store.get('minimizeToTray', true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// handle uncaught errors otherwise it displays
 | 
					// handle uncaught errors otherwise it displays
 | 
				
			||||||
@ -62,14 +100,14 @@ process.on('uncaughtException', function(error) {
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let focusHandlerAttached = false;
 | 
					let focusHandlerAttached = false;
 | 
				
			||||||
electron.ipcMain.on('setBadgeCount', function(ev, count) {
 | 
					ipcMain.on('setBadgeCount', function(ev, count) {
 | 
				
			||||||
    electron.app.setBadgeCount(count);
 | 
					    app.setBadgeCount(count);
 | 
				
			||||||
    if (count === 0) {
 | 
					    if (count === 0 && mainWindow) {
 | 
				
			||||||
        mainWindow.flashFrame(false);
 | 
					        mainWindow.flashFrame(false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
electron.ipcMain.on('loudNotification', function() {
 | 
					ipcMain.on('loudNotification', function() {
 | 
				
			||||||
    if (process.platform === 'win32' && mainWindow && !mainWindow.isFocused() && !focusHandlerAttached) {
 | 
					    if (process.platform === 'win32' && mainWindow && !mainWindow.isFocused() && !focusHandlerAttached) {
 | 
				
			||||||
        mainWindow.flashFrame(true);
 | 
					        mainWindow.flashFrame(true);
 | 
				
			||||||
        mainWindow.once('focus', () => {
 | 
					        mainWindow.once('focus', () => {
 | 
				
			||||||
@ -81,39 +119,108 @@ electron.ipcMain.on('loudNotification', function() {
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let powerSaveBlockerId;
 | 
					let powerSaveBlockerId;
 | 
				
			||||||
electron.ipcMain.on('app_onAction', function(ev, payload) {
 | 
					ipcMain.on('app_onAction', function(ev, payload) {
 | 
				
			||||||
    switch (payload.action) {
 | 
					    switch (payload.action) {
 | 
				
			||||||
        case 'call_state':
 | 
					        case 'call_state':
 | 
				
			||||||
            if (powerSaveBlockerId && electron.powerSaveBlocker.isStarted(powerSaveBlockerId)) {
 | 
					            if (powerSaveBlockerId && powerSaveBlocker.isStarted(powerSaveBlockerId)) {
 | 
				
			||||||
                if (payload.state === 'ended') {
 | 
					                if (payload.state === 'ended') {
 | 
				
			||||||
                    electron.powerSaveBlocker.stop(powerSaveBlockerId);
 | 
					                    powerSaveBlocker.stop(powerSaveBlockerId);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                if (payload.state === 'connected') {
 | 
					                if (payload.state === 'connected') {
 | 
				
			||||||
                    powerSaveBlockerId = electron.powerSaveBlocker.start('prevent-display-sleep');
 | 
					                    powerSaveBlockerId = powerSaveBlocker.start('prevent-display-sleep');
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					autoUpdater.on('update-downloaded', (ev, releaseNotes, releaseName, releaseDate, updateURL) => {
 | 
				
			||||||
electron.app.commandLine.appendSwitch('--enable-usermedia-screen-capturing');
 | 
					    if (!mainWindow) return;
 | 
				
			||||||
 | 
					    // forward to renderer
 | 
				
			||||||
const shouldQuit = electron.app.makeSingleInstance((commandLine, workingDirectory) => {
 | 
					    mainWindow.webContents.send('update-downloaded', {
 | 
				
			||||||
    // Someone tried to run a second instance, we should focus our window.
 | 
					        releaseNotes,
 | 
				
			||||||
    if (mainWindow) {
 | 
					        releaseName,
 | 
				
			||||||
        if (!mainWindow.isVisible()) mainWindow.show();
 | 
					        releaseDate,
 | 
				
			||||||
        if (mainWindow.isMinimized()) mainWindow.restore();
 | 
					        updateURL,
 | 
				
			||||||
        mainWindow.focus();
 | 
					    });
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (shouldQuit) {
 | 
					ipcMain.on('ipcCall', async function(ev, payload) {
 | 
				
			||||||
    console.log('Other instance detected: exiting');
 | 
					    if (!mainWindow) return;
 | 
				
			||||||
    electron.app.exit();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const args = payload.args || [];
 | 
				
			||||||
 | 
					    let ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (payload.name) {
 | 
				
			||||||
 | 
					        case 'getUpdateFeedUrl':
 | 
				
			||||||
 | 
					            ret = autoUpdater.getFeedURL();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'getAutoLaunchEnabled':
 | 
				
			||||||
 | 
					            ret = await launcher.isEnabled();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'setAutoLaunchEnabled':
 | 
				
			||||||
 | 
					            if (args[0]) {
 | 
				
			||||||
 | 
					                launcher.enable();
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                launcher.disable();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'getMinimizeToTrayEnabled':
 | 
				
			||||||
 | 
					            ret = global.minimizeToTray;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'setMinimizeToTrayEnabled':
 | 
				
			||||||
 | 
					            store.set('minimizeToTray', global.minimizeToTray = args[0]);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'getAutoHideMenuBarEnabled':
 | 
				
			||||||
 | 
					            ret = global.mainWindow.isMenuBarAutoHide();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'setAutoHideMenuBarEnabled':
 | 
				
			||||||
 | 
					            store.set('autoHideMenuBar', args[0]);
 | 
				
			||||||
 | 
					            global.mainWindow.setAutoHideMenuBar(args[0]);
 | 
				
			||||||
 | 
					            global.mainWindow.setMenuBarVisibility(!args[0]);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'getAppVersion':
 | 
				
			||||||
 | 
					            ret = app.getVersion();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'focusWindow':
 | 
				
			||||||
 | 
					            if (mainWindow.isMinimized()) {
 | 
				
			||||||
 | 
					                mainWindow.restore();
 | 
				
			||||||
 | 
					            } else if (!mainWindow.isVisible()) {
 | 
				
			||||||
 | 
					                mainWindow.show();
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                mainWindow.focus();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'origin_migrate':
 | 
				
			||||||
 | 
					            migratingOrigin = true;
 | 
				
			||||||
 | 
					            await migrateFromOldOrigin();
 | 
				
			||||||
 | 
					            migratingOrigin = false;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'getConfig':
 | 
				
			||||||
 | 
					            ret = vectorConfig;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            mainWindow.webContents.send('ipcReply', {
 | 
				
			||||||
 | 
					                id: payload.id,
 | 
				
			||||||
 | 
					                error: "Unknown IPC Call: " + payload.name,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mainWindow.webContents.send('ipcReply', {
 | 
				
			||||||
 | 
					        id: payload.id,
 | 
				
			||||||
 | 
					        reply: ret,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.commandLine.appendSwitch('--enable-usermedia-screen-capturing');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const gotLock = app.requestSingleInstanceLock();
 | 
				
			||||||
 | 
					if (!gotLock) {
 | 
				
			||||||
 | 
					    console.log('Other instance detected: exiting');
 | 
				
			||||||
 | 
					    app.exit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const launcher = new AutoLaunch({
 | 
					const launcher = new AutoLaunch({
 | 
				
			||||||
    name: vectorConfig.brand || 'Riot',
 | 
					    name: vectorConfig.brand || 'Riot',
 | 
				
			||||||
@ -123,61 +230,109 @@ const launcher = new AutoLaunch({
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const settings = {
 | 
					// Register the scheme the app is served from as 'standard'
 | 
				
			||||||
    'auto-launch': {
 | 
					// which allows things like relative URLs and IndexedDB to
 | 
				
			||||||
        get: launcher.isEnabled,
 | 
					// work.
 | 
				
			||||||
        set: function(bool) {
 | 
					// Also mark it as secure (ie. accessing resources from this
 | 
				
			||||||
            if (bool) {
 | 
					// protocol and HTTPS won't trigger mixed content warnings).
 | 
				
			||||||
                return launcher.enable();
 | 
					protocol.registerSchemesAsPrivileged([{
 | 
				
			||||||
            } else {
 | 
					    scheme: 'vector',
 | 
				
			||||||
                return launcher.disable();
 | 
					    privileges: {
 | 
				
			||||||
            }
 | 
					        standard: true,
 | 
				
			||||||
        },
 | 
					        secure: true,
 | 
				
			||||||
 | 
					        supportFetchAPI: true,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
};
 | 
					}]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
electron.ipcMain.on('settings_get', async function(ev) {
 | 
					app.on('ready', () => {
 | 
				
			||||||
    const data = {};
 | 
					    if (argv['devtools']) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
        await Promise.all(Object.keys(settings).map(async function (setting) {
 | 
					 | 
				
			||||||
            data[setting] = await settings[setting].get();
 | 
					 | 
				
			||||||
        }));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ev.sender.send('settings', data);
 | 
					 | 
				
			||||||
    } catch(e) { console.error(e); }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
electron.ipcMain.on('settings_set', function(ev, key, value) {
 | 
					 | 
				
			||||||
    console.log(key, value);
 | 
					 | 
				
			||||||
    if (settings[key] && settings[key].set) {
 | 
					 | 
				
			||||||
        settings[key].set(value);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
electron.app.on('ready', () => {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (argv.devtools) {
 | 
					 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            const { default: installExtension, REACT_DEVELOPER_TOOLS, REACT_PERF } = require('electron-devtools-installer');
 | 
					            const { default: installExt, REACT_DEVELOPER_TOOLS, REACT_PERF } = require('electron-devtools-installer');
 | 
				
			||||||
            installExtension(REACT_DEVELOPER_TOOLS)
 | 
					            installExt(REACT_DEVELOPER_TOOLS)
 | 
				
			||||||
                .then((name) => console.log(`Added Extension: ${name}`))
 | 
					                .then((name) => console.log(`Added Extension: ${name}`))
 | 
				
			||||||
                .catch((err) => console.log('An error occurred: ', err));
 | 
					                .catch((err) => console.log('An error occurred: ', err));
 | 
				
			||||||
            installExtension(REACT_PERF)
 | 
					            installExt(REACT_PERF)
 | 
				
			||||||
                .then((name) => console.log(`Added Extension: ${name}`))
 | 
					                .then((name) => console.log(`Added Extension: ${name}`))
 | 
				
			||||||
                .catch((err) => console.log('An error occurred: ', err));
 | 
					                .catch((err) => console.log('An error occurred: ', err));
 | 
				
			||||||
        } catch(e) {console.log(e);}
 | 
					        } catch (e) {
 | 
				
			||||||
 | 
					            console.log(e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protocol.registerFileProtocol('vector', (request, callback) => {
 | 
				
			||||||
 | 
					        if (request.method !== 'GET') {
 | 
				
			||||||
 | 
					            callback({error: -322}); // METHOD_NOT_SUPPORTED from chromium/src/net/base/net_error_list.h
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (vectorConfig.update_base_url) {
 | 
					        const parsedUrl = new URL(request.url);
 | 
				
			||||||
        console.log(`Starting auto update with base URL: ${vectorConfig.update_base_url}`);
 | 
					        if (parsedUrl.protocol !== 'vector:') {
 | 
				
			||||||
        updater.start(vectorConfig.update_base_url);
 | 
					            callback({error: -302}); // UNKNOWN_URL_SCHEME
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (parsedUrl.host !== 'vector') {
 | 
				
			||||||
 | 
					            callback({error: -105}); // NAME_NOT_RESOLVED
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const target = parsedUrl.pathname.split('/');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // path starts with a '/'
 | 
				
			||||||
 | 
					        if (target[0] !== '') {
 | 
				
			||||||
 | 
					            callback({error: -6}); // FILE_NOT_FOUND
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (target[target.length - 1] == '') {
 | 
				
			||||||
 | 
					            target[target.length - 1] = 'index.html';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let baseDir;
 | 
				
			||||||
 | 
					        // first part of the path determines where we serve from
 | 
				
			||||||
 | 
					        if (migratingOrigin && target[1] === 'origin_migrator_dest') {
 | 
				
			||||||
 | 
					            // the origin migrator destination page
 | 
				
			||||||
 | 
					            // (only the destination script needs to come from the
 | 
				
			||||||
 | 
					            // custom protocol: the source part is loaded from a
 | 
				
			||||||
 | 
					            // file:// as that's the origin we're migrating from).
 | 
				
			||||||
 | 
					            baseDir = __dirname + "/../../origin_migrator/dest";
 | 
				
			||||||
 | 
					        } else if (target[1] === 'webapp') {
 | 
				
			||||||
 | 
					            baseDir = __dirname + "/../../webapp";
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            callback({error: -6}); // FILE_NOT_FOUND
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Normalise the base dir and the target path separately, then make sure
 | 
				
			||||||
 | 
					        // the target path isn't trying to back out beyond its root
 | 
				
			||||||
 | 
					        baseDir = path.normalize(baseDir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const relTarget = path.normalize(path.join(...target.slice(2)));
 | 
				
			||||||
 | 
					        if (relTarget.startsWith('..')) {
 | 
				
			||||||
 | 
					            callback({error: -6}); // FILE_NOT_FOUND
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        const absTarget = path.join(baseDir, relTarget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        callback({
 | 
				
			||||||
 | 
					            path: absTarget,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }, (error) => {
 | 
				
			||||||
 | 
					        if (error) console.error('Failed to register protocol');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (argv['no-update']) {
 | 
				
			||||||
 | 
					        console.log('Auto update disabled via command line flag "--no-update"');
 | 
				
			||||||
 | 
					    } else if (vectorConfig['update_base_url']) {
 | 
				
			||||||
 | 
					        console.log(`Starting auto update with base URL: ${vectorConfig['update_base_url']}`);
 | 
				
			||||||
 | 
					        updater.start(vectorConfig['update_base_url']);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        console.log('No update_base_url is defined: auto update is disabled');
 | 
					        console.log('No update_base_url is defined: auto update is disabled');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const iconPath = `${__dirname}/../img/riot.${process.platform === 'win32' ? 'ico' : 'png'}`;
 | 
					    // It's important to call `path.join` so we don't end up with the packaged
 | 
				
			||||||
 | 
					    // asar in the final path.
 | 
				
			||||||
 | 
					    const iconFile = `riot.${process.platform === 'win32' ? 'ico' : 'png'}`;
 | 
				
			||||||
 | 
					    const iconPath = path.join(__dirname, "..", "..", "img", iconFile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Load the previous window state with fallback to defaults
 | 
					    // Load the previous window state with fallback to defaults
 | 
				
			||||||
    const mainWindowState = windowStateKeeper({
 | 
					    const mainWindowState = windowStateKeeper({
 | 
				
			||||||
@ -185,18 +340,31 @@ electron.app.on('ready', () => {
 | 
				
			|||||||
        defaultHeight: 768,
 | 
					        defaultHeight: 768,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mainWindow = global.mainWindow = new electron.BrowserWindow({
 | 
					    const preloadScript = path.normalize(`${__dirname}/preload.js`);
 | 
				
			||||||
 | 
					    mainWindow = global.mainWindow = new BrowserWindow({
 | 
				
			||||||
        icon: iconPath,
 | 
					        icon: iconPath,
 | 
				
			||||||
        show: false,
 | 
					        show: false,
 | 
				
			||||||
        autoHideMenuBar: true,
 | 
					        autoHideMenuBar: store.get('autoHideMenuBar', true),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        x: mainWindowState.x,
 | 
					        x: mainWindowState.x,
 | 
				
			||||||
        y: mainWindowState.y,
 | 
					        y: mainWindowState.y,
 | 
				
			||||||
        width: mainWindowState.width,
 | 
					        width: mainWindowState.width,
 | 
				
			||||||
        height: mainWindowState.height,
 | 
					        height: mainWindowState.height,
 | 
				
			||||||
 | 
					        webPreferences: {
 | 
				
			||||||
 | 
					            preload: preloadScript,
 | 
				
			||||||
 | 
					            nodeIntegration: false,
 | 
				
			||||||
 | 
					            sandbox: true,
 | 
				
			||||||
 | 
					            enableRemoteModule: false,
 | 
				
			||||||
 | 
					            // We don't use this: it's useful for the preload script to
 | 
				
			||||||
 | 
					            // share a context with the main page so we can give select
 | 
				
			||||||
 | 
					            // objects to the main page. The sandbox option isolates the
 | 
				
			||||||
 | 
					            // main page from the background script.
 | 
				
			||||||
 | 
					            contextIsolation: false,
 | 
				
			||||||
 | 
					            webgl: false,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    mainWindow.loadURL(`file://${__dirname}/../../webapp/index.html`);
 | 
					    mainWindow.loadURL('vector://vector/webapp/');
 | 
				
			||||||
    electron.Menu.setApplicationMenu(vectorMenu);
 | 
					    Menu.setApplicationMenu(vectorMenu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // explicitly hide because setApplicationMenu on Linux otherwise shows...
 | 
					    // explicitly hide because setApplicationMenu on Linux otherwise shows...
 | 
				
			||||||
    // https://github.com/electron/electron/issues/9621
 | 
					    // https://github.com/electron/electron/issues/9621
 | 
				
			||||||
@ -208,17 +376,22 @@ electron.app.on('ready', () => {
 | 
				
			|||||||
        brand: vectorConfig.brand || 'Riot',
 | 
					        brand: vectorConfig.brand || 'Riot',
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!argv.hidden) {
 | 
					    mainWindow.once('ready-to-show', () => {
 | 
				
			||||||
        mainWindow.once('ready-to-show', () => {
 | 
					        mainWindowState.manage(mainWindow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!argv['hidden']) {
 | 
				
			||||||
            mainWindow.show();
 | 
					            mainWindow.show();
 | 
				
			||||||
        });
 | 
					        } else {
 | 
				
			||||||
    }
 | 
					            // hide here explicitly because window manage above sometimes shows it
 | 
				
			||||||
 | 
					            mainWindow.hide();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mainWindow.on('closed', () => {
 | 
					    mainWindow.on('closed', () => {
 | 
				
			||||||
        mainWindow = global.mainWindow = null;
 | 
					        mainWindow = global.mainWindow = null;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    mainWindow.on('close', (e) => {
 | 
					    mainWindow.on('close', (e) => {
 | 
				
			||||||
        if (!global.appQuitting && (tray.hasTray() || process.platform === 'darwin')) {
 | 
					        if (global.minimizeToTray && !global.appQuitting && (tray.hasTray() || process.platform === 'darwin')) {
 | 
				
			||||||
            // On Mac, closing the window just hides it
 | 
					            // On Mac, closing the window just hides it
 | 
				
			||||||
            // (this is generally how single-window Mac apps
 | 
					            // (this is generally how single-window Mac apps
 | 
				
			||||||
            // behave, eg. Mail.app)
 | 
					            // behave, eg. Mail.app)
 | 
				
			||||||
@ -240,26 +413,37 @@ electron.app.on('ready', () => {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    webContentsHandler(mainWindow.webContents);
 | 
					    webContentsHandler(mainWindow.webContents);
 | 
				
			||||||
    mainWindowState.manage(mainWindow);
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
electron.app.on('window-all-closed', () => {
 | 
					app.on('window-all-closed', () => {
 | 
				
			||||||
    electron.app.quit();
 | 
					    app.quit();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
electron.app.on('activate', () => {
 | 
					app.on('activate', () => {
 | 
				
			||||||
    mainWindow.show();
 | 
					    mainWindow.show();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
electron.app.on('before-quit', () => {
 | 
					app.on('before-quit', () => {
 | 
				
			||||||
    global.appQuitting = true;
 | 
					    global.appQuitting = true;
 | 
				
			||||||
    if (mainWindow) {
 | 
					    if (mainWindow) {
 | 
				
			||||||
        mainWindow.webContents.send('before-quit');
 | 
					        mainWindow.webContents.send('before-quit');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.on('second-instance', (ev, commandLine, workingDirectory) => {
 | 
				
			||||||
 | 
					    // If other instance launched with --hidden then skip showing window
 | 
				
			||||||
 | 
					    if (commandLine.includes('--hidden')) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Someone tried to run a second instance, we should focus our window.
 | 
				
			||||||
 | 
					    if (mainWindow) {
 | 
				
			||||||
 | 
					        if (!mainWindow.isVisible()) mainWindow.show();
 | 
				
			||||||
 | 
					        if (mainWindow.isMinimized()) mainWindow.restore();
 | 
				
			||||||
 | 
					        mainWindow.focus();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Set the App User Model ID to match what the squirrel
 | 
					// Set the App User Model ID to match what the squirrel
 | 
				
			||||||
// installer uses for the shortcut icon.
 | 
					// installer uses for the shortcut icon.
 | 
				
			||||||
// This makes notifications work on windows 8.1 (and is
 | 
					// This makes notifications work on windows 8.1 (and is
 | 
				
			||||||
// a noop on other platforms).
 | 
					// a noop on other platforms).
 | 
				
			||||||
electron.app.setAppUserModelId('com.squirrel.riot-web.Riot');
 | 
					app.setAppUserModelId('com.squirrel.riot-web.Riot');
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										72
									
								
								electron_app/src/originMigrator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2018 New Vector Ltd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const { BrowserWindow, ipcMain } = require('electron');
 | 
				
			||||||
 | 
					const path = require('path');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function migrateFromOldOrigin() {
 | 
				
			||||||
 | 
					    console.log("Attempting to migrate data between origins");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // We can use the same preload script: we just need ipcRenderer exposed
 | 
				
			||||||
 | 
					    const preloadScript = path.normalize(`${__dirname}/preload.js`);
 | 
				
			||||||
 | 
					    await new Promise(resolve => {
 | 
				
			||||||
 | 
					        const migrateWindow = new BrowserWindow({
 | 
				
			||||||
 | 
					            show: false,
 | 
				
			||||||
 | 
					            webPreferences: {
 | 
				
			||||||
 | 
					                preload: preloadScript,
 | 
				
			||||||
 | 
					                nodeIntegration: false,
 | 
				
			||||||
 | 
					                sandbox: true,
 | 
				
			||||||
 | 
					                enableRemoteModule: false,
 | 
				
			||||||
 | 
					                webgl: false,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        const onOriginMigrationComplete = (e, success, sentSummary, storedSummary) => {
 | 
				
			||||||
 | 
					            // we use once but we'll only get one of these events,
 | 
				
			||||||
 | 
					            // so remove the listener for the other one
 | 
				
			||||||
 | 
					            ipcMain.removeListener('origin_migration_nodata', onOriginMigrationNoData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (success) {
 | 
				
			||||||
 | 
					                console.log("Origin migration completed successfully!");
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                console.error("Origin migration failed!");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            console.error("Data sent", sentSummary);
 | 
				
			||||||
 | 
					            console.error("Data stored", storedSummary);
 | 
				
			||||||
 | 
					            migrateWindow.close();
 | 
				
			||||||
 | 
					            resolve();
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        const onOriginMigrationNoData = (e, success, sentSummary, storedSummary) => {
 | 
				
			||||||
 | 
					            ipcMain.removeListener('origin_migration_complete', onOriginMigrationComplete);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            console.log("No session to migrate from old origin");
 | 
				
			||||||
 | 
					            migrateWindow.close();
 | 
				
			||||||
 | 
					            resolve();
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ipcMain.once('origin_migration_complete', onOriginMigrationComplete);
 | 
				
			||||||
 | 
					        ipcMain.once('origin_migration_nodata', onOriginMigrationNoData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Normalise the path because in the distribution, __dirname will be inside the
 | 
				
			||||||
 | 
					        // electron asar.
 | 
				
			||||||
 | 
					        const sourcePagePath = path.normalize(__dirname + '/../../origin_migrator/source.html');
 | 
				
			||||||
 | 
					        console.log("Loading path: " + sourcePagePath);
 | 
				
			||||||
 | 
					        migrateWindow.loadURL('file://' + sourcePagePath);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = {
 | 
				
			||||||
 | 
					    migrateFromOldOrigin,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
Copyright 2015, 2016 OpenMarket Ltd
 | 
					Copyright 2018, 2019 New Vector Ltd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
@ -14,11 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mx_MTextBody {
 | 
					const { ipcRenderer } = require('electron');
 | 
				
			||||||
    white-space: pre-wrap;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mx_MTextBody pre{
 | 
					// expose ipcRenderer to the renderer process
 | 
				
			||||||
  overflow-y: auto;
 | 
					window.ipcRenderer = ipcRenderer;
 | 
				
			||||||
  max-height: 30vh;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -65,7 +65,7 @@ exports.create = function(config) {
 | 
				
			|||||||
    global.mainWindow.webContents.on('page-favicon-updated', async function(ev, favicons) {
 | 
					    global.mainWindow.webContents.on('page-favicon-updated', async function(ev, favicons) {
 | 
				
			||||||
        if (!favicons || favicons.length <= 0 || !favicons[0].startsWith('data:')) {
 | 
					        if (!favicons || favicons.length <= 0 || !favicons[0].startsWith('data:')) {
 | 
				
			||||||
            if (lastFavicon !== null) {
 | 
					            if (lastFavicon !== null) {
 | 
				
			||||||
                win.setIcon(defaultIcon);
 | 
					                global.mainWindow.setIcon(defaultIcon);
 | 
				
			||||||
                trayIcon.setImage(defaultIcon);
 | 
					                trayIcon.setImage(defaultIcon);
 | 
				
			||||||
                lastFavicon = null;
 | 
					                lastFavicon = null;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -37,7 +37,7 @@ const template = [
 | 
				
			|||||||
        submenu: [
 | 
					        submenu: [
 | 
				
			||||||
            { type: 'separator' },
 | 
					            { type: 'separator' },
 | 
				
			||||||
            { role: 'resetzoom' },
 | 
					            { role: 'resetzoom' },
 | 
				
			||||||
            { role: 'zoomin' },
 | 
					            { role: 'zoomin', accelerator: 'CommandOrControl+=' },
 | 
				
			||||||
            { role: 'zoomout' },
 | 
					            { role: 'zoomout' },
 | 
				
			||||||
            { type: 'separator' },
 | 
					            { type: 'separator' },
 | 
				
			||||||
            { role: 'togglefullscreen' },
 | 
					            { role: 'togglefullscreen' },
 | 
				
			||||||
@ -57,8 +57,8 @@ const template = [
 | 
				
			|||||||
        role: 'help',
 | 
					        role: 'help',
 | 
				
			||||||
        submenu: [
 | 
					        submenu: [
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                label: 'riot.im',
 | 
					                label: 'Riot Help',
 | 
				
			||||||
                click() { shell.openExternal('https://riot.im/'); },
 | 
					                click() { shell.openExternal('https://about.riot.im/help'); },
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,14 @@
 | 
				
			|||||||
const {clipboard, nativeImage, Menu, MenuItem, shell} = require('electron');
 | 
					const {clipboard, nativeImage, Menu, MenuItem, shell, dialog} = require('electron');
 | 
				
			||||||
const url = require('url');
 | 
					const url = require('url');
 | 
				
			||||||
 | 
					const fs = require('fs');
 | 
				
			||||||
 | 
					const request = require('request');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const MAILTO_PREFIX = "mailto:";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const PERMITTED_URL_SCHEMES = [
 | 
					const PERMITTED_URL_SCHEMES = [
 | 
				
			||||||
    'http:',
 | 
					    'http:',
 | 
				
			||||||
    'https:',
 | 
					    'https:',
 | 
				
			||||||
    'mailto:',
 | 
					    MAILTO_PREFIX,
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function safeOpenURL(target) {
 | 
					function safeOpenURL(target) {
 | 
				
			||||||
@ -32,19 +36,27 @@ function onWindowOrNavigate(ev, target) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function onLinkContextMenu(ev, params) {
 | 
					function onLinkContextMenu(ev, params) {
 | 
				
			||||||
    const url = params.linkURL || params.srcURL;
 | 
					    let url = params.linkURL || params.srcURL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (url.startsWith('vector://vector/webapp')) {
 | 
				
			||||||
 | 
					        url = "https://riot.im/app/" + url.substring(23);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const popupMenu = new Menu();
 | 
					    const popupMenu = new Menu();
 | 
				
			||||||
    popupMenu.append(new MenuItem({
 | 
					    // No point trying to open blob: URLs in an external browser: it ain't gonna work.
 | 
				
			||||||
        label: url,
 | 
					    if (!url.startsWith('blob:')) {
 | 
				
			||||||
        click() {
 | 
					        popupMenu.append(new MenuItem({
 | 
				
			||||||
            safeOpenURL(url);
 | 
					            label: url,
 | 
				
			||||||
        },
 | 
					            click() {
 | 
				
			||||||
    }));
 | 
					                safeOpenURL(url);
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        }));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let addSaveAs = false;
 | 
				
			||||||
    if (params.mediaType && params.mediaType === 'image' && !url.startsWith('file://')) {
 | 
					    if (params.mediaType && params.mediaType === 'image' && !url.startsWith('file://')) {
 | 
				
			||||||
        popupMenu.append(new MenuItem({
 | 
					        popupMenu.append(new MenuItem({
 | 
				
			||||||
            label: 'Copy Image',
 | 
					            label: 'Copy image',
 | 
				
			||||||
            click() {
 | 
					            click() {
 | 
				
			||||||
                if (url.startsWith('data:')) {
 | 
					                if (url.startsWith('data:')) {
 | 
				
			||||||
                    clipboard.writeImage(nativeImage.createFromDataURL(url));
 | 
					                    clipboard.writeImage(nativeImage.createFromDataURL(url));
 | 
				
			||||||
@ -53,15 +65,63 @@ function onLinkContextMenu(ev, params) {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        }));
 | 
					        }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // We want the link to be ordered below the copy stuff, but don't want to duplicate
 | 
				
			||||||
 | 
					        // the `if` statement, so use a flag.
 | 
				
			||||||
 | 
					        addSaveAs = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    popupMenu.append(new MenuItem({
 | 
					    // No point offering to copy a blob: URL either
 | 
				
			||||||
        label: 'Copy Link Address',
 | 
					    if (!url.startsWith('blob:')) {
 | 
				
			||||||
        click() {
 | 
					        // Special-case e-mail URLs to strip the `mailto:` like modern browsers do
 | 
				
			||||||
            clipboard.writeText(url);
 | 
					        if (url.startsWith(MAILTO_PREFIX)) {
 | 
				
			||||||
        },
 | 
					            popupMenu.append(new MenuItem({
 | 
				
			||||||
    }));
 | 
					                label: 'Copy email address',
 | 
				
			||||||
    popupMenu.popup();
 | 
					                click() {
 | 
				
			||||||
 | 
					                    clipboard.writeText(url.substr(MAILTO_PREFIX.length));
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            popupMenu.append(new MenuItem({
 | 
				
			||||||
 | 
					                label: 'Copy link address',
 | 
				
			||||||
 | 
					                click() {
 | 
				
			||||||
 | 
					                    clipboard.writeText(url);
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (addSaveAs) {
 | 
				
			||||||
 | 
					        popupMenu.append(new MenuItem({
 | 
				
			||||||
 | 
					            label: 'Save image as...',
 | 
				
			||||||
 | 
					            click() {
 | 
				
			||||||
 | 
					                const targetFileName = params.titleText || "image.png";
 | 
				
			||||||
 | 
					                const filePath = dialog.showSaveDialog({
 | 
				
			||||||
 | 
					                    defaultPath: targetFileName,
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!filePath) return; // user cancelled dialog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    if (url.startsWith("data:")) {
 | 
				
			||||||
 | 
					                        fs.writeFileSync(filePath, nativeImage.createFromDataURL(url));
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        request.get(url).pipe(fs.createWriteStream(filePath));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } catch (err) {
 | 
				
			||||||
 | 
					                    console.error(err);
 | 
				
			||||||
 | 
					                    dialog.showMessageBox({
 | 
				
			||||||
 | 
					                        type: "error",
 | 
				
			||||||
 | 
					                        title: "Failed to save image",
 | 
				
			||||||
 | 
					                        message: "The image failed to save",
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        }));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // popup() requires an options object even for no options
 | 
				
			||||||
 | 
					    popupMenu.popup({});
 | 
				
			||||||
    ev.preventDefault();
 | 
					    ev.preventDefault();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -88,7 +148,8 @@ function onSelectedContextMenu(ev, params) {
 | 
				
			|||||||
    const items = _CutCopyPasteSelectContextMenus(params);
 | 
					    const items = _CutCopyPasteSelectContextMenus(params);
 | 
				
			||||||
    const popupMenu = Menu.buildFromTemplate(items);
 | 
					    const popupMenu = Menu.buildFromTemplate(items);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    popupMenu.popup();
 | 
					    // popup() requires an options object even for no options
 | 
				
			||||||
 | 
					    popupMenu.popup({});
 | 
				
			||||||
    ev.preventDefault();
 | 
					    ev.preventDefault();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -101,13 +162,26 @@ function onEditableContextMenu(ev, params) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const popupMenu = Menu.buildFromTemplate(items);
 | 
					    const popupMenu = Menu.buildFromTemplate(items);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    popupMenu.popup();
 | 
					    // popup() requires an options object even for no options
 | 
				
			||||||
 | 
					    popupMenu.popup({});
 | 
				
			||||||
    ev.preventDefault();
 | 
					    ev.preventDefault();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = (webContents) => {
 | 
					module.exports = (webContents) => {
 | 
				
			||||||
    webContents.on('new-window', onWindowOrNavigate);
 | 
					    webContents.on('new-window', onWindowOrNavigate);
 | 
				
			||||||
 | 
					    // XXX: The below now does absolutely nothing because of
 | 
				
			||||||
 | 
					    // https://github.com/electron/electron/issues/8841
 | 
				
			||||||
 | 
					    // Whilst this isn't a security issue since without
 | 
				
			||||||
 | 
					    // node integration and with the sandbox, it should be
 | 
				
			||||||
 | 
					    // no worse than opening the site in Chrome, it obviously
 | 
				
			||||||
 | 
					    // means the user has to restart Riot to make it usable
 | 
				
			||||||
 | 
					    // again (often unintuitive because it minimises to the
 | 
				
			||||||
 | 
					    // system tray). We therefore need to be vigilant about
 | 
				
			||||||
 | 
					    // putting target="_blank" on links in Riot (although
 | 
				
			||||||
 | 
					    // we should generally be doing this anyway since links
 | 
				
			||||||
 | 
					    // navigating you away from Riot in the browser is
 | 
				
			||||||
 | 
					    // also annoying).
 | 
				
			||||||
    webContents.on('will-navigate', onWindowOrNavigate);
 | 
					    webContents.on('will-navigate', onWindowOrNavigate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    webContents.on('context-menu', function(ev, params) {
 | 
					    webContents.on('context-menu', function(ev, params) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										837
									
								
								electron_app/yarn.lock
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,837 @@
 | 
				
			|||||||
 | 
					# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
 | 
				
			||||||
 | 
					# yarn lockfile v1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"@types/node@^9.4.0":
 | 
				
			||||||
 | 
					  version "9.6.45"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.45.tgz#a9e5cfd026a3abaaf17e3c0318a470da9f2f178e"
 | 
				
			||||||
 | 
					  integrity sha512-9scD7xI1kpIoMs3gVFMOWsWDyRIQ1AOZwe56i1CQPE6N/P4POYkn9UtW5F66t8C2AIoPtVfOFycQ2r11t3pcyg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ajv@^6.5.5:
 | 
				
			||||||
 | 
					  version "6.10.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1"
 | 
				
			||||||
 | 
					  integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    fast-deep-equal "^2.0.1"
 | 
				
			||||||
 | 
					    fast-json-stable-stringify "^2.0.0"
 | 
				
			||||||
 | 
					    json-schema-traverse "^0.4.1"
 | 
				
			||||||
 | 
					    uri-js "^4.2.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					applescript@^1.0.0:
 | 
				
			||||||
 | 
					  version "1.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/applescript/-/applescript-1.0.0.tgz#bb87af568cad034a4e48c4bdaf6067a3a2701317"
 | 
				
			||||||
 | 
					  integrity sha1-u4evVoytA0pOSMS9r2Bno6JwExc=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					asn1@~0.2.3:
 | 
				
			||||||
 | 
					  version "0.2.4"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
 | 
				
			||||||
 | 
					  integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    safer-buffer "~2.1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					assert-plus@1.0.0, assert-plus@^1.0.0:
 | 
				
			||||||
 | 
					  version "1.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
 | 
				
			||||||
 | 
					  integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					asynckit@^0.4.0:
 | 
				
			||||||
 | 
					  version "0.4.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
 | 
				
			||||||
 | 
					  integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					auto-launch@^5.0.1:
 | 
				
			||||||
 | 
					  version "5.0.5"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/auto-launch/-/auto-launch-5.0.5.tgz#d14bd002b1ef642f85e991a6195ff5300c8ad3c0"
 | 
				
			||||||
 | 
					  integrity sha512-ppdF4mihhYzMYLuCcx9H/c5TUOCev8uM7en53zWVQhyYAJrurd2bFZx3qQVeJKF2jrc7rsPRNN5cD+i23l6PdA==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    applescript "^1.0.0"
 | 
				
			||||||
 | 
					    mkdirp "^0.5.1"
 | 
				
			||||||
 | 
					    path-is-absolute "^1.0.0"
 | 
				
			||||||
 | 
					    untildify "^3.0.2"
 | 
				
			||||||
 | 
					    winreg "1.2.4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					aws-sign2@~0.7.0:
 | 
				
			||||||
 | 
					  version "0.7.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
 | 
				
			||||||
 | 
					  integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					aws4@^1.8.0:
 | 
				
			||||||
 | 
					  version "1.8.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
 | 
				
			||||||
 | 
					  integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bcrypt-pbkdf@^1.0.0:
 | 
				
			||||||
 | 
					  version "1.0.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
 | 
				
			||||||
 | 
					  integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    tweetnacl "^0.14.3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bignumber.js@^2.1.0:
 | 
				
			||||||
 | 
					  version "2.4.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8"
 | 
				
			||||||
 | 
					  integrity sha1-g4qZLan51zfg9LLbC+YrsJ3Qxeg=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bmp-js@0.0.3:
 | 
				
			||||||
 | 
					  version "0.0.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.0.3.tgz#64113e9c7cf1202b376ed607bf30626ebe57b18a"
 | 
				
			||||||
 | 
					  integrity sha1-ZBE+nHzxICs3btYHvzBibr5XsYo=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					buffer-equal@0.0.1:
 | 
				
			||||||
 | 
					  version "0.0.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b"
 | 
				
			||||||
 | 
					  integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					caseless@~0.12.0:
 | 
				
			||||||
 | 
					  version "0.12.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
 | 
				
			||||||
 | 
					  integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					combined-stream@^1.0.6, combined-stream@~1.0.6:
 | 
				
			||||||
 | 
					  version "1.0.7"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
 | 
				
			||||||
 | 
					  integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    delayed-stream "~1.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					conf@^2.0.0:
 | 
				
			||||||
 | 
					  version "2.2.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/conf/-/conf-2.2.0.tgz#ee282efafc1450b61e205372041ad7d866802d9a"
 | 
				
			||||||
 | 
					  integrity sha512-93Kz74FOMo6aWRVpAZsonOdl2I57jKtHrNmxhumehFQw4X8Sk37SohNY11PG7Q8Okta+UnrVaI006WLeyp8/XA==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    dot-prop "^4.1.0"
 | 
				
			||||||
 | 
					    env-paths "^1.0.0"
 | 
				
			||||||
 | 
					    make-dir "^1.0.0"
 | 
				
			||||||
 | 
					    pkg-up "^2.0.0"
 | 
				
			||||||
 | 
					    write-file-atomic "^2.3.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					core-util-is@1.0.2:
 | 
				
			||||||
 | 
					  version "1.0.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
 | 
				
			||||||
 | 
					  integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dashdash@^1.12.0:
 | 
				
			||||||
 | 
					  version "1.14.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
 | 
				
			||||||
 | 
					  integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    assert-plus "^1.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					deep-equal@^1.0.1:
 | 
				
			||||||
 | 
					  version "1.0.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
 | 
				
			||||||
 | 
					  integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					define-properties@^1.1.2:
 | 
				
			||||||
 | 
					  version "1.1.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
 | 
				
			||||||
 | 
					  integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    object-keys "^1.0.12"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					delayed-stream@~1.0.0:
 | 
				
			||||||
 | 
					  version "1.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
 | 
				
			||||||
 | 
					  integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dom-walk@^0.1.0:
 | 
				
			||||||
 | 
					  version "0.1.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
 | 
				
			||||||
 | 
					  integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dot-prop@^4.1.0:
 | 
				
			||||||
 | 
					  version "4.2.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
 | 
				
			||||||
 | 
					  integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    is-obj "^1.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ecc-jsbn@~0.1.1:
 | 
				
			||||||
 | 
					  version "0.1.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
 | 
				
			||||||
 | 
					  integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    jsbn "~0.1.0"
 | 
				
			||||||
 | 
					    safer-buffer "^2.1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					electron-store@^2.0.0:
 | 
				
			||||||
 | 
					  version "2.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/electron-store/-/electron-store-2.0.0.tgz#1035cca2a95409d1f54c7466606345852450d64a"
 | 
				
			||||||
 | 
					  integrity sha512-1WCFYHsYvZBqDsoaS0Relnz0rd81ZkBAI0Fgx7Nq2UWU77rSNs1qxm4S6uH7TCZ0bV3LQpJFk7id/is/ZgoOPA==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    conf "^2.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					electron-window-state@^4.1.0:
 | 
				
			||||||
 | 
					  version "4.1.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/electron-window-state/-/electron-window-state-4.1.1.tgz#6b34fdc31b38514dfec8b7c8f7b5d4addb67632d"
 | 
				
			||||||
 | 
					  integrity sha1-azT9wxs4UU3+yLfI97XUrdtnYy0=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    deep-equal "^1.0.1"
 | 
				
			||||||
 | 
					    jsonfile "^2.2.3"
 | 
				
			||||||
 | 
					    mkdirp "^0.5.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					env-paths@^1.0.0:
 | 
				
			||||||
 | 
					  version "1.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0"
 | 
				
			||||||
 | 
					  integrity sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					es-abstract@^1.5.0:
 | 
				
			||||||
 | 
					  version "1.13.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9"
 | 
				
			||||||
 | 
					  integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    es-to-primitive "^1.2.0"
 | 
				
			||||||
 | 
					    function-bind "^1.1.1"
 | 
				
			||||||
 | 
					    has "^1.0.3"
 | 
				
			||||||
 | 
					    is-callable "^1.1.4"
 | 
				
			||||||
 | 
					    is-regex "^1.0.4"
 | 
				
			||||||
 | 
					    object-keys "^1.0.12"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					es-to-primitive@^1.2.0:
 | 
				
			||||||
 | 
					  version "1.2.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377"
 | 
				
			||||||
 | 
					  integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    is-callable "^1.1.4"
 | 
				
			||||||
 | 
					    is-date-object "^1.0.1"
 | 
				
			||||||
 | 
					    is-symbol "^1.0.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					es6-promise@^3.0.2:
 | 
				
			||||||
 | 
					  version "3.3.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613"
 | 
				
			||||||
 | 
					  integrity sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exif-parser@^0.1.9:
 | 
				
			||||||
 | 
					  version "0.1.12"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922"
 | 
				
			||||||
 | 
					  integrity sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extend@~3.0.2:
 | 
				
			||||||
 | 
					  version "3.0.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
 | 
				
			||||||
 | 
					  integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extsprintf@1.3.0:
 | 
				
			||||||
 | 
					  version "1.3.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
 | 
				
			||||||
 | 
					  integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extsprintf@^1.2.0:
 | 
				
			||||||
 | 
					  version "1.4.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
 | 
				
			||||||
 | 
					  integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fast-deep-equal@^2.0.1:
 | 
				
			||||||
 | 
					  version "2.0.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
 | 
				
			||||||
 | 
					  integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fast-json-stable-stringify@^2.0.0:
 | 
				
			||||||
 | 
					  version "2.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
 | 
				
			||||||
 | 
					  integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					file-type@^3.1.0:
 | 
				
			||||||
 | 
					  version "3.9.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9"
 | 
				
			||||||
 | 
					  integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					find-up@^2.1.0:
 | 
				
			||||||
 | 
					  version "2.1.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
 | 
				
			||||||
 | 
					  integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    locate-path "^2.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for-each@^0.3.3:
 | 
				
			||||||
 | 
					  version "0.3.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
 | 
				
			||||||
 | 
					  integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    is-callable "^1.1.3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					forever-agent@~0.6.1:
 | 
				
			||||||
 | 
					  version "0.6.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
 | 
				
			||||||
 | 
					  integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					form-data@~2.3.2:
 | 
				
			||||||
 | 
					  version "2.3.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
 | 
				
			||||||
 | 
					  integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    asynckit "^0.4.0"
 | 
				
			||||||
 | 
					    combined-stream "^1.0.6"
 | 
				
			||||||
 | 
					    mime-types "^2.1.12"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function-bind@^1.0.2, function-bind@^1.1.1:
 | 
				
			||||||
 | 
					  version "1.1.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
 | 
				
			||||||
 | 
					  integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					getpass@^0.1.1:
 | 
				
			||||||
 | 
					  version "0.1.7"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
 | 
				
			||||||
 | 
					  integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    assert-plus "^1.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					global@~4.3.0:
 | 
				
			||||||
 | 
					  version "4.3.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
 | 
				
			||||||
 | 
					  integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    min-document "^2.19.0"
 | 
				
			||||||
 | 
					    process "~0.5.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					graceful-fs@^4.1.11, graceful-fs@^4.1.6:
 | 
				
			||||||
 | 
					  version "4.1.15"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
 | 
				
			||||||
 | 
					  integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					har-schema@^2.0.0:
 | 
				
			||||||
 | 
					  version "2.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
 | 
				
			||||||
 | 
					  integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					har-validator@~5.1.0:
 | 
				
			||||||
 | 
					  version "5.1.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
 | 
				
			||||||
 | 
					  integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    ajv "^6.5.5"
 | 
				
			||||||
 | 
					    har-schema "^2.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					has-symbols@^1.0.0:
 | 
				
			||||||
 | 
					  version "1.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
 | 
				
			||||||
 | 
					  integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					has@^1.0.1, has@^1.0.3:
 | 
				
			||||||
 | 
					  version "1.0.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
 | 
				
			||||||
 | 
					  integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    function-bind "^1.1.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					http-signature@~1.2.0:
 | 
				
			||||||
 | 
					  version "1.2.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
 | 
				
			||||||
 | 
					  integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    assert-plus "^1.0.0"
 | 
				
			||||||
 | 
					    jsprim "^1.2.2"
 | 
				
			||||||
 | 
					    sshpk "^1.7.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					imurmurhash@^0.1.4:
 | 
				
			||||||
 | 
					  version "0.1.4"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
 | 
				
			||||||
 | 
					  integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ip-regex@^1.0.1:
 | 
				
			||||||
 | 
					  version "1.0.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd"
 | 
				
			||||||
 | 
					  integrity sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					is-callable@^1.1.3, is-callable@^1.1.4:
 | 
				
			||||||
 | 
					  version "1.1.4"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
 | 
				
			||||||
 | 
					  integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					is-date-object@^1.0.1:
 | 
				
			||||||
 | 
					  version "1.0.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
 | 
				
			||||||
 | 
					  integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					is-function@^1.0.1:
 | 
				
			||||||
 | 
					  version "1.0.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5"
 | 
				
			||||||
 | 
					  integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					is-obj@^1.0.0:
 | 
				
			||||||
 | 
					  version "1.0.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
 | 
				
			||||||
 | 
					  integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					is-regex@^1.0.4:
 | 
				
			||||||
 | 
					  version "1.0.4"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
 | 
				
			||||||
 | 
					  integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    has "^1.0.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					is-symbol@^1.0.2:
 | 
				
			||||||
 | 
					  version "1.0.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38"
 | 
				
			||||||
 | 
					  integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    has-symbols "^1.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					is-typedarray@~1.0.0:
 | 
				
			||||||
 | 
					  version "1.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
 | 
				
			||||||
 | 
					  integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					isstream@~0.1.2:
 | 
				
			||||||
 | 
					  version "0.1.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
 | 
				
			||||||
 | 
					  integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jimp@^0.2.28:
 | 
				
			||||||
 | 
					  version "0.2.28"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.2.28.tgz#dd529a937190f42957a7937d1acc3a7762996ea2"
 | 
				
			||||||
 | 
					  integrity sha1-3VKak3GQ9ClXp5N9Gsw6d2KZbqI=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    bignumber.js "^2.1.0"
 | 
				
			||||||
 | 
					    bmp-js "0.0.3"
 | 
				
			||||||
 | 
					    es6-promise "^3.0.2"
 | 
				
			||||||
 | 
					    exif-parser "^0.1.9"
 | 
				
			||||||
 | 
					    file-type "^3.1.0"
 | 
				
			||||||
 | 
					    jpeg-js "^0.2.0"
 | 
				
			||||||
 | 
					    load-bmfont "^1.2.3"
 | 
				
			||||||
 | 
					    mime "^1.3.4"
 | 
				
			||||||
 | 
					    mkdirp "0.5.1"
 | 
				
			||||||
 | 
					    pixelmatch "^4.0.0"
 | 
				
			||||||
 | 
					    pngjs "^3.0.0"
 | 
				
			||||||
 | 
					    read-chunk "^1.0.1"
 | 
				
			||||||
 | 
					    request "^2.65.0"
 | 
				
			||||||
 | 
					    stream-to-buffer "^0.1.0"
 | 
				
			||||||
 | 
					    tinycolor2 "^1.1.2"
 | 
				
			||||||
 | 
					    url-regex "^3.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jpeg-js@^0.2.0:
 | 
				
			||||||
 | 
					  version "0.2.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.2.0.tgz#53e448ec9d263e683266467e9442d2c5a2ef5482"
 | 
				
			||||||
 | 
					  integrity sha1-U+RI7J0mPmgyZkZ+lELSxaLvVII=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jsbn@~0.1.0:
 | 
				
			||||||
 | 
					  version "0.1.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
 | 
				
			||||||
 | 
					  integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					json-schema-traverse@^0.4.1:
 | 
				
			||||||
 | 
					  version "0.4.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
 | 
				
			||||||
 | 
					  integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					json-schema@0.2.3:
 | 
				
			||||||
 | 
					  version "0.2.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
 | 
				
			||||||
 | 
					  integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					json-stringify-safe@~5.0.1:
 | 
				
			||||||
 | 
					  version "5.0.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
 | 
				
			||||||
 | 
					  integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jsonfile@^2.2.3:
 | 
				
			||||||
 | 
					  version "2.4.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
 | 
				
			||||||
 | 
					  integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug=
 | 
				
			||||||
 | 
					  optionalDependencies:
 | 
				
			||||||
 | 
					    graceful-fs "^4.1.6"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jsprim@^1.2.2:
 | 
				
			||||||
 | 
					  version "1.4.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
 | 
				
			||||||
 | 
					  integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    assert-plus "1.0.0"
 | 
				
			||||||
 | 
					    extsprintf "1.3.0"
 | 
				
			||||||
 | 
					    json-schema "0.2.3"
 | 
				
			||||||
 | 
					    verror "1.10.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					load-bmfont@^1.2.3:
 | 
				
			||||||
 | 
					  version "1.4.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.0.tgz#75f17070b14a8c785fe7f5bee2e6fd4f98093b6b"
 | 
				
			||||||
 | 
					  integrity sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    buffer-equal "0.0.1"
 | 
				
			||||||
 | 
					    mime "^1.3.4"
 | 
				
			||||||
 | 
					    parse-bmfont-ascii "^1.0.3"
 | 
				
			||||||
 | 
					    parse-bmfont-binary "^1.0.5"
 | 
				
			||||||
 | 
					    parse-bmfont-xml "^1.1.4"
 | 
				
			||||||
 | 
					    phin "^2.9.1"
 | 
				
			||||||
 | 
					    xhr "^2.0.1"
 | 
				
			||||||
 | 
					    xtend "^4.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					locate-path@^2.0.0:
 | 
				
			||||||
 | 
					  version "2.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
 | 
				
			||||||
 | 
					  integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    p-locate "^2.0.0"
 | 
				
			||||||
 | 
					    path-exists "^3.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					make-dir@^1.0.0:
 | 
				
			||||||
 | 
					  version "1.3.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
 | 
				
			||||||
 | 
					  integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    pify "^3.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mime-db@~1.38.0:
 | 
				
			||||||
 | 
					  version "1.38.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad"
 | 
				
			||||||
 | 
					  integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mime-types@^2.1.12, mime-types@~2.1.19:
 | 
				
			||||||
 | 
					  version "2.1.22"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd"
 | 
				
			||||||
 | 
					  integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    mime-db "~1.38.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mime@^1.3.4:
 | 
				
			||||||
 | 
					  version "1.6.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
 | 
				
			||||||
 | 
					  integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					min-document@^2.19.0:
 | 
				
			||||||
 | 
					  version "2.19.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
 | 
				
			||||||
 | 
					  integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    dom-walk "^0.1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					minimist@0.0.8:
 | 
				
			||||||
 | 
					  version "0.0.8"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
 | 
				
			||||||
 | 
					  integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					minimist@^1.2.0:
 | 
				
			||||||
 | 
					  version "1.2.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
 | 
				
			||||||
 | 
					  integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mkdirp@0.5.1, mkdirp@^0.5.1:
 | 
				
			||||||
 | 
					  version "0.5.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
 | 
				
			||||||
 | 
					  integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    minimist "0.0.8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					oauth-sign@~0.9.0:
 | 
				
			||||||
 | 
					  version "0.9.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
 | 
				
			||||||
 | 
					  integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object-keys@^1.0.12:
 | 
				
			||||||
 | 
					  version "1.1.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.0.tgz#11bd22348dd2e096a045ab06f6c85bcc340fa032"
 | 
				
			||||||
 | 
					  integrity sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					p-limit@^1.1.0:
 | 
				
			||||||
 | 
					  version "1.3.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
 | 
				
			||||||
 | 
					  integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    p-try "^1.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					p-locate@^2.0.0:
 | 
				
			||||||
 | 
					  version "2.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
 | 
				
			||||||
 | 
					  integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    p-limit "^1.1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					p-try@^1.0.0:
 | 
				
			||||||
 | 
					  version "1.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
 | 
				
			||||||
 | 
					  integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parse-bmfont-ascii@^1.0.3:
 | 
				
			||||||
 | 
					  version "1.0.6"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz#11ac3c3ff58f7c2020ab22769079108d4dfa0285"
 | 
				
			||||||
 | 
					  integrity sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parse-bmfont-binary@^1.0.5:
 | 
				
			||||||
 | 
					  version "1.0.6"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz#d038b476d3e9dd9db1e11a0b0e53a22792b69006"
 | 
				
			||||||
 | 
					  integrity sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parse-bmfont-xml@^1.1.4:
 | 
				
			||||||
 | 
					  version "1.1.4"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz#015319797e3e12f9e739c4d513872cd2fa35f389"
 | 
				
			||||||
 | 
					  integrity sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    xml-parse-from-string "^1.0.0"
 | 
				
			||||||
 | 
					    xml2js "^0.4.5"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parse-headers@^2.0.0:
 | 
				
			||||||
 | 
					  version "2.0.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.2.tgz#9545e8a4c1ae5eaea7d24992bca890281ed26e34"
 | 
				
			||||||
 | 
					  integrity sha512-/LypJhzFmyBIDYP9aDVgeyEb5sQfbfY5mnDq4hVhlQ69js87wXfmEI5V3xI6vvXasqebp0oCytYFLxsBVfCzSg==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    for-each "^0.3.3"
 | 
				
			||||||
 | 
					    string.prototype.trim "^1.1.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path-exists@^3.0.0:
 | 
				
			||||||
 | 
					  version "3.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
 | 
				
			||||||
 | 
					  integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path-is-absolute@^1.0.0:
 | 
				
			||||||
 | 
					  version "1.0.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
 | 
				
			||||||
 | 
					  integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					performance-now@^2.1.0:
 | 
				
			||||||
 | 
					  version "2.1.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
 | 
				
			||||||
 | 
					  integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					phin@^2.9.1:
 | 
				
			||||||
 | 
					  version "2.9.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/phin/-/phin-2.9.3.tgz#f9b6ac10a035636fb65dfc576aaaa17b8743125c"
 | 
				
			||||||
 | 
					  integrity sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pify@^3.0.0:
 | 
				
			||||||
 | 
					  version "3.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
 | 
				
			||||||
 | 
					  integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pixelmatch@^4.0.0:
 | 
				
			||||||
 | 
					  version "4.0.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854"
 | 
				
			||||||
 | 
					  integrity sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    pngjs "^3.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pkg-up@^2.0.0:
 | 
				
			||||||
 | 
					  version "2.0.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
 | 
				
			||||||
 | 
					  integrity sha1-yBmscoBZpGHKscOImivjxJoATX8=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    find-up "^2.1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					png-to-ico@^1.0.2:
 | 
				
			||||||
 | 
					  version "1.0.7"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/png-to-ico/-/png-to-ico-1.0.7.tgz#9346b5f4d6fd7e94cb08fd49eeb585f501c3e5f2"
 | 
				
			||||||
 | 
					  integrity sha512-heHiZjPFhVgLiuSG4C4wwKN9YPGLpPJvOfXRyI+cEJf0vPutjJ4XDaeI2f/hzTFs+2juihDw3pP8R5JtTuQTGg==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    "@types/node" "^9.4.0"
 | 
				
			||||||
 | 
					    jimp "^0.2.28"
 | 
				
			||||||
 | 
					    minimist "^1.2.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pngjs@^3.0.0:
 | 
				
			||||||
 | 
					  version "3.4.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
 | 
				
			||||||
 | 
					  integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					process@~0.5.1:
 | 
				
			||||||
 | 
					  version "0.5.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
 | 
				
			||||||
 | 
					  integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					psl@^1.1.24:
 | 
				
			||||||
 | 
					  version "1.1.31"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184"
 | 
				
			||||||
 | 
					  integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					punycode@^1.4.1:
 | 
				
			||||||
 | 
					  version "1.4.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
 | 
				
			||||||
 | 
					  integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					punycode@^2.1.0:
 | 
				
			||||||
 | 
					  version "2.1.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
 | 
				
			||||||
 | 
					  integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qs@~6.5.2:
 | 
				
			||||||
 | 
					  version "6.5.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
 | 
				
			||||||
 | 
					  integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					read-chunk@^1.0.1:
 | 
				
			||||||
 | 
					  version "1.0.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194"
 | 
				
			||||||
 | 
					  integrity sha1-X2jKswfmY/GZk1J9m1icrORmEZQ=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					request@^2.65.0:
 | 
				
			||||||
 | 
					  version "2.88.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
 | 
				
			||||||
 | 
					  integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    aws-sign2 "~0.7.0"
 | 
				
			||||||
 | 
					    aws4 "^1.8.0"
 | 
				
			||||||
 | 
					    caseless "~0.12.0"
 | 
				
			||||||
 | 
					    combined-stream "~1.0.6"
 | 
				
			||||||
 | 
					    extend "~3.0.2"
 | 
				
			||||||
 | 
					    forever-agent "~0.6.1"
 | 
				
			||||||
 | 
					    form-data "~2.3.2"
 | 
				
			||||||
 | 
					    har-validator "~5.1.0"
 | 
				
			||||||
 | 
					    http-signature "~1.2.0"
 | 
				
			||||||
 | 
					    is-typedarray "~1.0.0"
 | 
				
			||||||
 | 
					    isstream "~0.1.2"
 | 
				
			||||||
 | 
					    json-stringify-safe "~5.0.1"
 | 
				
			||||||
 | 
					    mime-types "~2.1.19"
 | 
				
			||||||
 | 
					    oauth-sign "~0.9.0"
 | 
				
			||||||
 | 
					    performance-now "^2.1.0"
 | 
				
			||||||
 | 
					    qs "~6.5.2"
 | 
				
			||||||
 | 
					    safe-buffer "^5.1.2"
 | 
				
			||||||
 | 
					    tough-cookie "~2.4.3"
 | 
				
			||||||
 | 
					    tunnel-agent "^0.6.0"
 | 
				
			||||||
 | 
					    uuid "^3.3.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					safe-buffer@^5.0.1, safe-buffer@^5.1.2:
 | 
				
			||||||
 | 
					  version "5.1.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
 | 
				
			||||||
 | 
					  integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
 | 
				
			||||||
 | 
					  version "2.1.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
 | 
				
			||||||
 | 
					  integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sax@>=0.6.0:
 | 
				
			||||||
 | 
					  version "1.2.4"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
 | 
				
			||||||
 | 
					  integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					signal-exit@^3.0.2:
 | 
				
			||||||
 | 
					  version "3.0.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
 | 
				
			||||||
 | 
					  integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sshpk@^1.7.0:
 | 
				
			||||||
 | 
					  version "1.16.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
 | 
				
			||||||
 | 
					  integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    asn1 "~0.2.3"
 | 
				
			||||||
 | 
					    assert-plus "^1.0.0"
 | 
				
			||||||
 | 
					    bcrypt-pbkdf "^1.0.0"
 | 
				
			||||||
 | 
					    dashdash "^1.12.0"
 | 
				
			||||||
 | 
					    ecc-jsbn "~0.1.1"
 | 
				
			||||||
 | 
					    getpass "^0.1.1"
 | 
				
			||||||
 | 
					    jsbn "~0.1.0"
 | 
				
			||||||
 | 
					    safer-buffer "^2.0.2"
 | 
				
			||||||
 | 
					    tweetnacl "~0.14.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					stream-to-buffer@^0.1.0:
 | 
				
			||||||
 | 
					  version "0.1.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz#26799d903ab2025c9bd550ac47171b00f8dd80a9"
 | 
				
			||||||
 | 
					  integrity sha1-JnmdkDqyAlyb1VCsRxcbAPjdgKk=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    stream-to "~0.2.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					stream-to@~0.2.0:
 | 
				
			||||||
 | 
					  version "0.2.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/stream-to/-/stream-to-0.2.2.tgz#84306098d85fdb990b9fa300b1b3ccf55e8ef01d"
 | 
				
			||||||
 | 
					  integrity sha1-hDBgmNhf25kLn6MAsbPM9V6O8B0=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string.prototype.trim@^1.1.2:
 | 
				
			||||||
 | 
					  version "1.1.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea"
 | 
				
			||||||
 | 
					  integrity sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    define-properties "^1.1.2"
 | 
				
			||||||
 | 
					    es-abstract "^1.5.0"
 | 
				
			||||||
 | 
					    function-bind "^1.0.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tinycolor2@^1.1.2:
 | 
				
			||||||
 | 
					  version "1.4.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8"
 | 
				
			||||||
 | 
					  integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tough-cookie@~2.4.3:
 | 
				
			||||||
 | 
					  version "2.4.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
 | 
				
			||||||
 | 
					  integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    psl "^1.1.24"
 | 
				
			||||||
 | 
					    punycode "^1.4.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tunnel-agent@^0.6.0:
 | 
				
			||||||
 | 
					  version "0.6.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
 | 
				
			||||||
 | 
					  integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    safe-buffer "^5.0.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tweetnacl@^0.14.3, tweetnacl@~0.14.0:
 | 
				
			||||||
 | 
					  version "0.14.5"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
 | 
				
			||||||
 | 
					  integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					untildify@^3.0.2:
 | 
				
			||||||
 | 
					  version "3.0.3"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.3.tgz#1e7b42b140bcfd922b22e70ca1265bfe3634c7c9"
 | 
				
			||||||
 | 
					  integrity sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uri-js@^4.2.2:
 | 
				
			||||||
 | 
					  version "4.2.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
 | 
				
			||||||
 | 
					  integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    punycode "^2.1.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					url-regex@^3.0.0:
 | 
				
			||||||
 | 
					  version "3.2.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/url-regex/-/url-regex-3.2.0.tgz#dbad1e0c9e29e105dd0b1f09f6862f7fdb482724"
 | 
				
			||||||
 | 
					  integrity sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    ip-regex "^1.0.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uuid@^3.3.2:
 | 
				
			||||||
 | 
					  version "3.3.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
 | 
				
			||||||
 | 
					  integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					verror@1.10.0:
 | 
				
			||||||
 | 
					  version "1.10.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
 | 
				
			||||||
 | 
					  integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    assert-plus "^1.0.0"
 | 
				
			||||||
 | 
					    core-util-is "1.0.2"
 | 
				
			||||||
 | 
					    extsprintf "^1.2.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					winreg@1.2.4:
 | 
				
			||||||
 | 
					  version "1.2.4"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.4.tgz#ba065629b7a925130e15779108cf540990e98d1b"
 | 
				
			||||||
 | 
					  integrity sha1-ugZWKbepJRMOFXeRCM9UCZDpjRs=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					write-file-atomic@^2.3.0:
 | 
				
			||||||
 | 
					  version "2.4.2"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.2.tgz#a7181706dfba17855d221140a9c06e15fcdd87b9"
 | 
				
			||||||
 | 
					  integrity sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    graceful-fs "^4.1.11"
 | 
				
			||||||
 | 
					    imurmurhash "^0.1.4"
 | 
				
			||||||
 | 
					    signal-exit "^3.0.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					xhr@^2.0.1:
 | 
				
			||||||
 | 
					  version "2.5.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd"
 | 
				
			||||||
 | 
					  integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    global "~4.3.0"
 | 
				
			||||||
 | 
					    is-function "^1.0.1"
 | 
				
			||||||
 | 
					    parse-headers "^2.0.0"
 | 
				
			||||||
 | 
					    xtend "^4.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					xml-parse-from-string@^1.0.0:
 | 
				
			||||||
 | 
					  version "1.0.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28"
 | 
				
			||||||
 | 
					  integrity sha1-qQKekp09vN7RafPG4oI42VpdWig=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					xml2js@^0.4.5:
 | 
				
			||||||
 | 
					  version "0.4.19"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7"
 | 
				
			||||||
 | 
					  integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    sax ">=0.6.0"
 | 
				
			||||||
 | 
					    xmlbuilder "~9.0.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					xmlbuilder@~9.0.1:
 | 
				
			||||||
 | 
					  version "9.0.7"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
 | 
				
			||||||
 | 
					  integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					xtend@^4.0.0:
 | 
				
			||||||
 | 
					  version "4.0.1"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
 | 
				
			||||||
 | 
					  integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68=
 | 
				
			||||||
@ -9,7 +9,7 @@ var webpack_config = require('./webpack.config');
 | 
				
			|||||||
 * to build everything; however it's the easiest way to load our dependencies
 | 
					 * to build everything; however it's the easiest way to load our dependencies
 | 
				
			||||||
 * from node_modules.
 | 
					 * from node_modules.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * If you run karma in multi-run mode (with `npm run test-multi`), it will watch
 | 
					 * If you run karma in multi-run mode (with `yarn test-multi`), it will watch
 | 
				
			||||||
 * the tests for changes, and webpack will rebuild using a cache. This is much quicker
 | 
					 * the tests for changes, and webpack will rebuild using a cache. This is much quicker
 | 
				
			||||||
 * than a clean rebuild.
 | 
					 * than a clean rebuild.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@ -32,9 +32,12 @@ const olm_entry = webpack_config.entry['olm'];
 | 
				
			|||||||
// 'preprocessors' config below)
 | 
					// 'preprocessors' config below)
 | 
				
			||||||
delete webpack_config['entry'];
 | 
					delete webpack_config['entry'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// make sure we're flagged as development to avoid wasting time optimising
 | 
				
			||||||
 | 
					webpack_config.mode = 'development';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// add ./test as a search path for js
 | 
					// add ./test as a search path for js
 | 
				
			||||||
webpack_config.module.loaders.unshift({
 | 
					webpack_config.module.rules.unshift({
 | 
				
			||||||
    test: /\.js$/, loader: "babel",
 | 
					    test: /\.js$/, use: "babel-loader",
 | 
				
			||||||
    include: [path.resolve('./src'), path.resolve('./test')],
 | 
					    include: [path.resolve('./src'), path.resolve('./test')],
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -46,8 +49,9 @@ webpack_config.module.noParse.push(/sinon\/pkg\/sinon\.js$/);
 | 
				
			|||||||
// ?
 | 
					// ?
 | 
				
			||||||
webpack_config.resolve.alias['sinon'] = 'sinon/pkg/sinon.js';
 | 
					webpack_config.resolve.alias['sinon'] = 'sinon/pkg/sinon.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
webpack_config.resolve.root = [
 | 
					webpack_config.resolve.modules = [
 | 
				
			||||||
    path.resolve('./test'),
 | 
					    path.resolve('./test'),
 | 
				
			||||||
 | 
					    "node_modules"
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
webpack_config.devtool = 'inline-source-map';
 | 
					webpack_config.devtool = 'inline-source-map';
 | 
				
			||||||
@ -70,14 +74,21 @@ module.exports = function (config) {
 | 
				
			|||||||
            // This isn't required by any of the tests, but it stops karma
 | 
					            // This isn't required by any of the tests, but it stops karma
 | 
				
			||||||
            // logging warnings when it serves a 404 for them.
 | 
					            // logging warnings when it serves a 404 for them.
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                pattern: 'src/skins/vector/img/*',
 | 
					                pattern: 'node_modules/matrix-react-sdk/res/img/*',
 | 
				
			||||||
 | 
					                watched: false, included: false, served: true, nocache: false,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                pattern: 'res/**',
 | 
				
			||||||
                watched: false, included: false, served: true, nocache: false,
 | 
					                watched: false, included: false, served: true, nocache: false,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        proxies: {
 | 
					        proxies: {
 | 
				
			||||||
            // redirect img links to the karma server. See above.
 | 
					            // redirect img links to the karma server. See above.
 | 
				
			||||||
            "/img/": "/base/src/skins/vector/img/",
 | 
					            "/img/": "/base/node_modules/matrix-react-sdk/res/img/",
 | 
				
			||||||
 | 
					            "/themes/": "/base/res/themes/",
 | 
				
			||||||
 | 
					            "/welcome.html": "/base/res/welcome.html",
 | 
				
			||||||
 | 
					            "/welcome/": "/base/res/welcome/",
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // preprocess matching files before serving them to the browser
 | 
					        // preprocess matching files before serving them to the browser
 | 
				
			||||||
@ -89,7 +100,7 @@ module.exports = function (config) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // test results reporter to use
 | 
					        // test results reporter to use
 | 
				
			||||||
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
 | 
					        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
 | 
				
			||||||
        reporters: ['logcapture', 'spec', 'junit', 'summary'],
 | 
					        reporters: ['logcapture', 'spec', 'summary'],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        specReporter: {
 | 
					        specReporter: {
 | 
				
			||||||
            suppressErrorSummary: false, // do print error summary
 | 
					            suppressErrorSummary: false, // do print error summary
 | 
				
			||||||
@ -127,10 +138,10 @@ module.exports = function (config) {
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        customLaunchers: {
 | 
					        customLaunchers: {
 | 
				
			||||||
            'ChromeHeadless': {
 | 
					            'VectorChromeHeadless': {
 | 
				
			||||||
                base: 'Chrome',
 | 
					                base: 'Chrome',
 | 
				
			||||||
                flags: [
 | 
					                flags: [
 | 
				
			||||||
                    // '--no-sandbox',
 | 
					                    '--no-sandbox',
 | 
				
			||||||
                    // See https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md
 | 
					                    // See https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md
 | 
				
			||||||
                    '--headless',
 | 
					                    '--headless',
 | 
				
			||||||
                    '--disable-gpu',
 | 
					                    '--disable-gpu',
 | 
				
			||||||
@ -148,10 +159,6 @@ module.exports = function (config) {
 | 
				
			|||||||
        // how many browser should be started simultaneous
 | 
					        // how many browser should be started simultaneous
 | 
				
			||||||
        concurrency: Infinity,
 | 
					        concurrency: Infinity,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        junitReporter: {
 | 
					 | 
				
			||||||
            outputDir: 'karma-reports',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        webpack: webpack_config,
 | 
					        webpack: webpack_config,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        webpackMiddleware: {
 | 
					        webpackMiddleware: {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										19
									
								
								origin_migrator/dest/browser-matrix.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										6
									
								
								origin_migrator/dest/dest.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<script src="browser-matrix.min.js"></script>
 | 
				
			||||||
 | 
					<script src="dest.js"></script>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										125
									
								
								origin_migrator/dest/dest.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,125 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2018 New Vector Ltd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const SOURCE_ORIGIN = 'file://';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const IndexedDBCryptoStore = window.matrixcs.IndexedDBCryptoStore;
 | 
				
			||||||
 | 
					const cryptoStore = new IndexedDBCryptoStore(window.indexedDB, 'matrix-js-sdk:crypto');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let accountStored = 0;
 | 
				
			||||||
 | 
					let sessionsStored = 0;
 | 
				
			||||||
 | 
					let inboundGroupSessionsStored = 0;
 | 
				
			||||||
 | 
					let deviceDataStored = 0;
 | 
				
			||||||
 | 
					let roomsStored = 0;
 | 
				
			||||||
 | 
					let localStorageKeysStored = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const promises = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function onMessage(e) {
 | 
				
			||||||
 | 
					    if (e.origin !== SOURCE_ORIGIN) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const data = e.data.data; // bleh, naming clash
 | 
				
			||||||
 | 
					    switch (e.data.cmd) {
 | 
				
			||||||
 | 
					        case 'init':
 | 
				
			||||||
 | 
					            // start with clean stores before we migrate data in
 | 
				
			||||||
 | 
					            window.localStorage.clear();
 | 
				
			||||||
 | 
					            await cryptoStore.deleteAllData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            e.source.postMessage({
 | 
				
			||||||
 | 
					                cmd: 'initOK',
 | 
				
			||||||
 | 
					            }, SOURCE_ORIGIN);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'storeAccount':
 | 
				
			||||||
 | 
					            promises.push(cryptoStore.doTxn(
 | 
				
			||||||
 | 
					                'readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT],
 | 
				
			||||||
 | 
					                (txn) => {
 | 
				
			||||||
 | 
					                    cryptoStore.storeAccount(txn, data);
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            ).then(() => {
 | 
				
			||||||
 | 
					                ++accountStored;
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'storeSessions':
 | 
				
			||||||
 | 
					            promises.push(cryptoStore.doTxn(
 | 
				
			||||||
 | 
					                'readwrite', [IndexedDBCryptoStore.STORE_SESSIONS],
 | 
				
			||||||
 | 
					                (txn) => {
 | 
				
			||||||
 | 
					                    for (const sess of data) {
 | 
				
			||||||
 | 
					                        cryptoStore.storeEndToEndSession(sess.deviceKey, sess.sessionId, sess, txn);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            ).then(() => {
 | 
				
			||||||
 | 
					                sessionsStored += data.length;
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'storeInboundGroupSessions':
 | 
				
			||||||
 | 
					            promises.push(cryptoStore.doTxn(
 | 
				
			||||||
 | 
					                'readwrite', [IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS],
 | 
				
			||||||
 | 
					                (txn) => {
 | 
				
			||||||
 | 
					                    for (const sess of data) {
 | 
				
			||||||
 | 
					                        cryptoStore.addEndToEndInboundGroupSession(
 | 
				
			||||||
 | 
					                            sess.senderKey, sess.sessionId, sess.sessionData, txn,
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            ).then(() => {
 | 
				
			||||||
 | 
					                inboundGroupSessionsStored += data.length;
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'storeDeviceData':
 | 
				
			||||||
 | 
					            promises.push(cryptoStore.doTxn(
 | 
				
			||||||
 | 
					                'readwrite', [IndexedDBCryptoStore.STORE_DEVICE_DATA],
 | 
				
			||||||
 | 
					                (txn) => {
 | 
				
			||||||
 | 
					                    cryptoStore.storeEndToEndDeviceData(data, txn);
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            ).then(() => {
 | 
				
			||||||
 | 
					                ++deviceDataStored;
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'storeRooms':
 | 
				
			||||||
 | 
					            promises.push(cryptoStore.doTxn(
 | 
				
			||||||
 | 
					                'readwrite', [IndexedDBCryptoStore.STORE_ROOMS],
 | 
				
			||||||
 | 
					                (txn) => {
 | 
				
			||||||
 | 
					                    for (const [roomId, roomInfo] of Object.entries(data)) {
 | 
				
			||||||
 | 
					                        cryptoStore.storeEndToEndRoom(roomId, roomInfo, txn);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            ).then(() => {
 | 
				
			||||||
 | 
					                ++roomsStored;
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'storeLocalStorage':
 | 
				
			||||||
 | 
					            window.localStorage.setItem(data.key, data.val);
 | 
				
			||||||
 | 
					            ++localStorageKeysStored;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'getSummary':
 | 
				
			||||||
 | 
					            await Promise.all(promises);
 | 
				
			||||||
 | 
					            e.source.postMessage({
 | 
				
			||||||
 | 
					                cmd: 'summary',
 | 
				
			||||||
 | 
					                data: {
 | 
				
			||||||
 | 
					                    accountStored,
 | 
				
			||||||
 | 
					                    sessionsStored,
 | 
				
			||||||
 | 
					                    inboundGroupSessionsStored,
 | 
				
			||||||
 | 
					                    deviceDataStored,
 | 
				
			||||||
 | 
					                    roomsStored,
 | 
				
			||||||
 | 
					                    localStorageKeysStored,
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            }, SOURCE_ORIGIN);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					window.addEventListener('message', onMessage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										7
									
								
								origin_migrator/source.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<script src="dest/browser-matrix.min.js"></script>
 | 
				
			||||||
 | 
					<script src="source.js"></script>
 | 
				
			||||||
 | 
					<iframe name="dest" src="vector://vector/origin_migrator_dest/dest.html" onload="doMigrate()"></iframe>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										210
									
								
								origin_migrator/source.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,210 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2018 New Vector Ltd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const TARGET_ORIGIN = 'vector://vector';
 | 
				
			||||||
 | 
					const BATCH_SIZE = 500;
 | 
				
			||||||
 | 
					let destFrame;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let initResolver = null;
 | 
				
			||||||
 | 
					let getSummaryResolver = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onMessage(e) {
 | 
				
			||||||
 | 
					    if (e.origin !== TARGET_ORIGIN) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (e.data.cmd === 'initOK' && initResolver) {
 | 
				
			||||||
 | 
					        initResolver();
 | 
				
			||||||
 | 
					        initResolver = null;
 | 
				
			||||||
 | 
					    } else if (e.data.cmd === 'summary' && getSummaryResolver) {
 | 
				
			||||||
 | 
					        getSummaryResolver(e.data.data);
 | 
				
			||||||
 | 
					        getSummaryResolver = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function initDestFrame() {
 | 
				
			||||||
 | 
					    return new Promise(resolve => {
 | 
				
			||||||
 | 
					        initResolver = resolve;
 | 
				
			||||||
 | 
					        destFrame.postMessage({
 | 
				
			||||||
 | 
					            cmd: 'init', 
 | 
				
			||||||
 | 
					        }, TARGET_ORIGIN);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function getSummary() {
 | 
				
			||||||
 | 
					    return new Promise(resolve => {
 | 
				
			||||||
 | 
					        getSummaryResolver = resolve;
 | 
				
			||||||
 | 
					        destFrame.postMessage({
 | 
				
			||||||
 | 
					            cmd: 'getSummary', 
 | 
				
			||||||
 | 
					        }, TARGET_ORIGIN);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function doMigrate() {
 | 
				
			||||||
 | 
					    let accountSent = 0;
 | 
				
			||||||
 | 
					    let sessionsSent = 0;
 | 
				
			||||||
 | 
					    let inboundGroupSessionsSent = 0;
 | 
				
			||||||
 | 
					    let deviceDataSent = 0;
 | 
				
			||||||
 | 
					    let roomsSent = 0;
 | 
				
			||||||
 | 
					    let localStorageKeysSent = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!window.ipcRenderer) {
 | 
				
			||||||
 | 
					        console.error("ipcRenderer not found");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (window.localStorage.getItem('mx_user_id') === null) {
 | 
				
			||||||
 | 
					        window.ipcRenderer.send("origin_migration_nodata");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    destFrame = window.parent.frames.dest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await initDestFrame();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const IndexedDBCryptoStore = window.matrixcs.IndexedDBCryptoStore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const cryptoStore = new IndexedDBCryptoStore(window.indexedDB, 'matrix-js-sdk:crypto');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await cryptoStore.doTxn(
 | 
				
			||||||
 | 
					        'readonly', [IndexedDBCryptoStore.STORE_ACCOUNT],
 | 
				
			||||||
 | 
					        (txn) => {
 | 
				
			||||||
 | 
					            cryptoStore.getAccount(txn, (account) => {
 | 
				
			||||||
 | 
					                destFrame.postMessage({
 | 
				
			||||||
 | 
					                    cmd: 'storeAccount',
 | 
				
			||||||
 | 
					                    data: account,
 | 
				
			||||||
 | 
					                }, TARGET_ORIGIN);
 | 
				
			||||||
 | 
					                ++accountSent;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await cryptoStore.doTxn(
 | 
				
			||||||
 | 
					        'readonly', [IndexedDBCryptoStore.STORE_SESSIONS],
 | 
				
			||||||
 | 
					        (txn) => {
 | 
				
			||||||
 | 
					            let sessBatch = [];
 | 
				
			||||||
 | 
					            cryptoStore.getAllEndToEndSessions(txn, (sessInfo) => {
 | 
				
			||||||
 | 
					                if (sessInfo) {
 | 
				
			||||||
 | 
					                    ++sessionsSent;
 | 
				
			||||||
 | 
					                    sessBatch.push(sessInfo);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (sessBatch.length >= BATCH_SIZE || sessInfo === null) {
 | 
				
			||||||
 | 
					                    destFrame.postMessage({
 | 
				
			||||||
 | 
					                        cmd: 'storeSessions',
 | 
				
			||||||
 | 
					                        data: sessBatch,
 | 
				
			||||||
 | 
					                    }, TARGET_ORIGIN);
 | 
				
			||||||
 | 
					                    sessBatch = [];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await cryptoStore.doTxn(
 | 
				
			||||||
 | 
					        'readonly', [IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS],
 | 
				
			||||||
 | 
					        (txn) => {
 | 
				
			||||||
 | 
					            let sessBatch = [];
 | 
				
			||||||
 | 
					            cryptoStore.getAllEndToEndInboundGroupSessions(txn, (sessInfo) => {
 | 
				
			||||||
 | 
					                if (sessInfo) {
 | 
				
			||||||
 | 
					                    ++inboundGroupSessionsSent;
 | 
				
			||||||
 | 
					                    sessBatch.push(sessInfo);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (sessBatch.length >= BATCH_SIZE || sessInfo === null) {
 | 
				
			||||||
 | 
					                    destFrame.postMessage({
 | 
				
			||||||
 | 
					                        cmd: 'storeInboundGroupSessions',
 | 
				
			||||||
 | 
					                        data: sessBatch,
 | 
				
			||||||
 | 
					                    }, TARGET_ORIGIN);
 | 
				
			||||||
 | 
					                    sessBatch = [];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await cryptoStore.doTxn(
 | 
				
			||||||
 | 
					        'readonly', [IndexedDBCryptoStore.STORE_DEVICE_DATA],
 | 
				
			||||||
 | 
					        (txn) => {
 | 
				
			||||||
 | 
					            cryptoStore.getEndToEndDeviceData(txn, (deviceData) => {
 | 
				
			||||||
 | 
					                destFrame.postMessage({
 | 
				
			||||||
 | 
					                    cmd: 'storeDeviceData',
 | 
				
			||||||
 | 
					                    data: deviceData,
 | 
				
			||||||
 | 
					                }, TARGET_ORIGIN);
 | 
				
			||||||
 | 
					                ++deviceDataSent;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await cryptoStore.doTxn(
 | 
				
			||||||
 | 
					        'readonly', [IndexedDBCryptoStore.STORE_ROOMS],
 | 
				
			||||||
 | 
					        (txn) => {
 | 
				
			||||||
 | 
					            cryptoStore.getEndToEndRooms(txn, (rooms) => {
 | 
				
			||||||
 | 
					                destFrame.postMessage({
 | 
				
			||||||
 | 
					                    cmd: 'storeRooms',
 | 
				
			||||||
 | 
					                    data: rooms,
 | 
				
			||||||
 | 
					                }, TARGET_ORIGIN);
 | 
				
			||||||
 | 
					                ++roomsSent;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // we don't bother migrating;
 | 
				
			||||||
 | 
					    // * sync data (we can just initialsync again)
 | 
				
			||||||
 | 
					    // * logs
 | 
				
			||||||
 | 
					    // * key requests (worst case they'll just be re-sent)
 | 
				
			||||||
 | 
					    // * sessions needing backup (feature isn't available on Electron)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (let i = 0; i < window.localStorage.length; ++i) {
 | 
				
			||||||
 | 
					        const key = window.localStorage.key(i);
 | 
				
			||||||
 | 
					        const val = window.localStorage.getItem(key);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        destFrame.postMessage({
 | 
				
			||||||
 | 
					            cmd: 'storeLocalStorage',
 | 
				
			||||||
 | 
					            data: { key, val },
 | 
				
			||||||
 | 
					        }, TARGET_ORIGIN);
 | 
				
			||||||
 | 
					        ++localStorageKeysSent;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const summary = await getSummary();
 | 
				
			||||||
 | 
					    let success = false;
 | 
				
			||||||
 | 
					    if (
 | 
				
			||||||
 | 
					        summary.accountStored === accountSent &&
 | 
				
			||||||
 | 
					        summary.sessionsStored === sessionsSent &&
 | 
				
			||||||
 | 
					        summary.inboundGroupSessionsStored === inboundGroupSessionsSent &&
 | 
				
			||||||
 | 
					        summary.deviceDataStored === deviceDataSent &&
 | 
				
			||||||
 | 
					        summary.roomsStored === roomsSent &&
 | 
				
			||||||
 | 
					        summary.localStorageKeysStored === localStorageKeysSent
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        success = true;
 | 
				
			||||||
 | 
					        window.localStorage.clear();
 | 
				
			||||||
 | 
					        await cryptoStore.deleteAllData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // we don't bother migrating them, but also blow away the sync & logs db,
 | 
				
			||||||
 | 
					        // otherwise they'll just hang about taking up space
 | 
				
			||||||
 | 
					        await new Promise(resolve => {
 | 
				
			||||||
 | 
					            const req = window.indexedDB.deleteDatabase('matrix-js-sdk:riot-web-sync');
 | 
				
			||||||
 | 
					            req.onsuccess = resolve;
 | 
				
			||||||
 | 
					            req.onerror = resolve;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        await new Promise(resolve => {
 | 
				
			||||||
 | 
					            const req = window.indexedDB.deleteDatabase('logs');
 | 
				
			||||||
 | 
					            req.onsuccess = resolve;
 | 
				
			||||||
 | 
					            req.onerror = resolve;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    window.ipcRenderer.send("origin_migration_complete", success, {
 | 
				
			||||||
 | 
					        accountSent, sessionsSent, inboundGroupSessionsSent,
 | 
				
			||||||
 | 
					        deviceDataSent, roomsSent, localStorageKeysSent,
 | 
				
			||||||
 | 
					    }, summary);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					window.addEventListener('message', onMessage);
 | 
				
			||||||
							
								
								
									
										9512
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
							
								
								
									
										209
									
								
								package.json
									
									
									
									
									
								
							
							
						
						@ -2,7 +2,7 @@
 | 
				
			|||||||
  "name": "riot-web",
 | 
					  "name": "riot-web",
 | 
				
			||||||
  "productName": "Riot",
 | 
					  "productName": "Riot",
 | 
				
			||||||
  "main": "electron_app/src/electron-main.js",
 | 
					  "main": "electron_app/src/electron-main.js",
 | 
				
			||||||
  "version": "0.13.5",
 | 
					  "version": "1.5.0",
 | 
				
			||||||
  "description": "A feature-rich client for Matrix.org",
 | 
					  "description": "A feature-rich client for Matrix.org",
 | 
				
			||||||
  "author": "New Vector Ltd.",
 | 
					  "author": "New Vector Ltd.",
 | 
				
			||||||
  "repository": {
 | 
					  "repository": {
 | 
				
			||||||
@ -30,141 +30,142 @@
 | 
				
			|||||||
    "reskindex:watch": "reskindex -h src/header -w",
 | 
					    "reskindex:watch": "reskindex -h src/header -w",
 | 
				
			||||||
    "i18n": "matrix-gen-i18n",
 | 
					    "i18n": "matrix-gen-i18n",
 | 
				
			||||||
    "prunei18n": "matrix-prune-i18n",
 | 
					    "prunei18n": "matrix-prune-i18n",
 | 
				
			||||||
 | 
					    "diff-i18n": "cp src/i18n/strings/en_EN.json src/i18n/strings/en_EN_orig.json && yarn i18n && node scripts/compare-file.js src/i18n/strings/en_EN_orig.json src/i18n/strings/en_EN.json",
 | 
				
			||||||
    "build:res": "node scripts/copy-res.js",
 | 
					    "build:res": "node scripts/copy-res.js",
 | 
				
			||||||
    "build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
 | 
					    "build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
 | 
				
			||||||
    "build:compile": "npm run reskindex && babel --source-maps -d lib src",
 | 
					    "build:compile": "yarn reskindex && babel --source-maps -d lib src",
 | 
				
			||||||
    "build:bundle": "cross-env NODE_ENV=production webpack -p --progress --bail",
 | 
					    "build:bundle": "cross-env NODE_ENV=production webpack -p --progress --bail --mode production",
 | 
				
			||||||
    "build:bundle:dev": "webpack --optimize-occurence-order --progress --bail",
 | 
					    "build:bundle:dev": "webpack --progress --bail --mode development",
 | 
				
			||||||
    "build:electron": "npm run clean && npm run build && npm run install:electron && build -wml --ia32 --x64",
 | 
					    "build:electron": "yarn clean && yarn build && yarn install:electron && electron-builder -wml --ia32 --x64",
 | 
				
			||||||
    "build": "npm run reskindex && npm run build:res && npm run build:bundle",
 | 
					    "build:electron:linux": "yarn build && electron-builder -l --x64",
 | 
				
			||||||
    "build:dev": "npm run reskindex && npm run build:res && npm run build:bundle:dev",
 | 
					    "build:electron:macos": "yarn build && electron-builder -m --x64",
 | 
				
			||||||
 | 
					    "build:electron:windows": "yarn build && electron-builder -w --ia32 --x64",
 | 
				
			||||||
 | 
					    "build:react-sdk": "node scripts/yarn-sub.js matrix-react-sdk build",
 | 
				
			||||||
 | 
					    "build:js-sdk": "node scripts/yarn-sub.js matrix-js-sdk start:init",
 | 
				
			||||||
 | 
					    "build": "yarn build:js-sdk && yarn build:react-sdk && yarn reskindex && yarn build:res && yarn build:bundle",
 | 
				
			||||||
 | 
					    "build:dev": "yarn build:js-sdk && yarn build:react-sdk && yarn reskindex && yarn build:res && yarn build:bundle:dev",
 | 
				
			||||||
    "dist": "scripts/package.sh",
 | 
					    "dist": "scripts/package.sh",
 | 
				
			||||||
    "install:electron": "install-app-deps",
 | 
					    "install:electron": "electron-builder install-app-deps",
 | 
				
			||||||
    "electron": "npm run install:electron && electron .",
 | 
					    "electron": "yarn install:electron && electron .",
 | 
				
			||||||
    "start:res": "node scripts/copy-res.js -w",
 | 
					    "start:res": "node scripts/copy-res.js -w",
 | 
				
			||||||
    "start:js": "webpack-dev-server --output-filename=bundles/_dev_/[name].js --output-chunk-file=bundles/_dev_/[name].js -w --progress",
 | 
					    "start:js": "webpack-dev-server --host=0.0.0.0 --output-filename=bundles/_dev_/[name].js --output-chunk-filename=bundles/_dev_/[name].js -w --progress --mode development",
 | 
				
			||||||
    "start:js:prod": "cross-env NODE_ENV=production webpack-dev-server -w --progress",
 | 
					    "start:js:prod": "cross-env NODE_ENV=production webpack-dev-server -w --progress --mode production",
 | 
				
			||||||
    "start": "parallelshell \"npm run reskindex:watch\" \"npm run start:res\" \"npm run start:js\"",
 | 
					    "start:js-sdk": "node scripts/yarn-sub.js matrix-js-sdk start:watch",
 | 
				
			||||||
    "start:prod": "parallelshell \"npm run reskindex:watch\" \"npm run start:res\" \"npm run start:js:prod\"",
 | 
					    "start:js-sdk:prod": "cross-env NODE_ENV=production node scripts/yarn-sub.js matrix-js-sdk start:watch",
 | 
				
			||||||
 | 
					    "start:react-sdk": "node scripts/yarn-sub.js matrix-react-sdk start:all",
 | 
				
			||||||
 | 
					    "start:react-sdk:prod": "cross-env NODE_ENV=production node scripts/yarn-sub.js matrix-react-sdk start:all",
 | 
				
			||||||
 | 
					    "start": "yarn build:js-sdk && yarn build:react-sdk && concurrently --kill-others-on-fail --prefix \"{time} [{name}]\" -n js-sdk,react-sdk,reskindex,res,riot-js \"yarn start:js-sdk\" \"yarn start:react-sdk\" \"yarn reskindex:watch\" \"yarn start:res\" \"yarn start:js\"",
 | 
				
			||||||
 | 
					    "start:prod": "yarn build:js-sdk && yarn build:react-sdk && concurrently --kill-others-on-fail --prefix \"{time} [{name}]\" -n js-sdk,react-sdk,reskindex,res,riot-js \"yarn start:js-sdk:prod\" \"yarn start:react-sdk:prod\" \"yarn reskindex:watch\" \"yarn start:res\" \"yarn start:js:prod\"",
 | 
				
			||||||
    "lint": "eslint src/",
 | 
					    "lint": "eslint src/",
 | 
				
			||||||
    "lintall": "eslint src/ test/",
 | 
					    "lintall": "eslint src/ test/",
 | 
				
			||||||
    "clean": "rimraf lib webapp electron_app/dist",
 | 
					    "clean": "rimraf lib webapp electron_app/dist",
 | 
				
			||||||
    "prepublish": "npm run clean && npm run build:compile",
 | 
					    "prepare": "yarn clean && yarn build:compile",
 | 
				
			||||||
    "test": "karma start --single-run=true --autoWatch=false --browsers ChromeHeadless",
 | 
					    "test": "karma start --single-run=true --autoWatch=false --browsers VectorChromeHeadless",
 | 
				
			||||||
    "test-multi": "karma start"
 | 
					    "test-multi": "karma start"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "babel-polyfill": "^6.5.0",
 | 
					    "babel-polyfill": "^6.26.0",
 | 
				
			||||||
    "babel-runtime": "^6.11.6",
 | 
					    "babel-runtime": "^6.26.0",
 | 
				
			||||||
    "bluebird": "^3.5.0",
 | 
					    "bluebird": "^3.5.2",
 | 
				
			||||||
    "browser-request": "^0.3.3",
 | 
					    "browser-request": "^0.3.3",
 | 
				
			||||||
    "classnames": "^2.1.2",
 | 
					 | 
				
			||||||
    "draft-js": "^0.11.0-alpha",
 | 
					    "draft-js": "^0.11.0-alpha",
 | 
				
			||||||
    "extract-text-webpack-plugin": "^0.9.1",
 | 
					    "extract-text-webpack-plugin": "^4.0.0-beta.0",
 | 
				
			||||||
    "favico.js": "^0.3.10",
 | 
					    "favico.js": "^0.3.10",
 | 
				
			||||||
    "filesize": "3.5.6",
 | 
					    "gemini-scrollbar": "github:matrix-org/gemini-scrollbar#91e1e566",
 | 
				
			||||||
    "flux": "2.1.1",
 | 
					    "gfm.css": "^1.1.2",
 | 
				
			||||||
    "gemini-scrollbar": "matrix-org/gemini-scrollbar#b302279",
 | 
					    "highlight.js": "^9.13.1",
 | 
				
			||||||
    "gfm.css": "^1.1.1",
 | 
					    "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
 | 
				
			||||||
    "highlight.js": "^9.0.0",
 | 
					    "matrix-react-sdk": "github:matrix-org/matrix-react-sdk#develop",
 | 
				
			||||||
    "linkifyjs": "^2.1.3",
 | 
					    "modernizr": "^3.6.0",
 | 
				
			||||||
    "matrix-js-sdk": "0.9.2",
 | 
					    "olm": "https://packages.matrix.org/npm/olm/olm-3.1.4.tgz",
 | 
				
			||||||
    "matrix-react-sdk": "0.11.4",
 | 
					    "prop-types": "^15.7.2",
 | 
				
			||||||
    "modernizr": "^3.1.0",
 | 
					    "react": "^16.9.0",
 | 
				
			||||||
    "pako": "^1.0.5",
 | 
					    "react-dom": "^16.9.0",
 | 
				
			||||||
    "prop-types": "^15.5.10",
 | 
					    "sanitize-html": "^1.19.1",
 | 
				
			||||||
    "react": "^15.6.0",
 | 
					    "ua-parser-js": "^0.7.19",
 | 
				
			||||||
    "react-beautiful-dnd": "^4.0.1",
 | 
					    "url": "^0.11.0"
 | 
				
			||||||
    "react-dom": "^15.6.0",
 | 
					 | 
				
			||||||
    "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef",
 | 
					 | 
				
			||||||
    "sanitize-html": "^1.11.1",
 | 
					 | 
				
			||||||
    "text-encoding-utf-8": "^1.0.1",
 | 
					 | 
				
			||||||
    "ua-parser-js": "^0.7.10",
 | 
					 | 
				
			||||||
    "url": "^0.11.0",
 | 
					 | 
				
			||||||
    "velocity-vector": "vector-im/velocity#059e3b2"
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "autoprefixer": "^6.6.0",
 | 
					    "autoprefixer": "^6.6.0",
 | 
				
			||||||
    "babel-cli": "^6.5.2",
 | 
					    "babel-cli": "^6.26.0",
 | 
				
			||||||
    "babel-core": "^6.14.0",
 | 
					    "babel-core": "^6.26.3",
 | 
				
			||||||
    "babel-eslint": "^6.1.0",
 | 
					    "babel-eslint": "^8.1.1",
 | 
				
			||||||
    "babel-loader": "^6.2.5",
 | 
					    "babel-loader": "^7.1.5",
 | 
				
			||||||
    "babel-plugin-add-module-exports": "^0.2.1",
 | 
					    "babel-plugin-add-module-exports": "^0.2.1",
 | 
				
			||||||
 | 
					    "babel-plugin-syntax-dynamic-import": "^6.18.0",
 | 
				
			||||||
    "babel-plugin-transform-async-to-bluebird": "^1.1.1",
 | 
					    "babel-plugin-transform-async-to-bluebird": "^1.1.1",
 | 
				
			||||||
    "babel-plugin-transform-class-properties": "^6.16.0",
 | 
					    "babel-plugin-transform-builtin-extend": "^1.1.2",
 | 
				
			||||||
    "babel-plugin-transform-object-rest-spread": "^6.16.0",
 | 
					    "babel-plugin-transform-class-properties": "^6.24.1",
 | 
				
			||||||
    "babel-plugin-transform-runtime": "^6.15.0",
 | 
					    "babel-plugin-transform-object-rest-spread": "^6.26.0",
 | 
				
			||||||
    "babel-preset-es2015": "^6.16.0",
 | 
					    "babel-plugin-transform-runtime": "^6.23.0",
 | 
				
			||||||
    "babel-preset-es2016": "^6.16.0",
 | 
					    "babel-preset-es2015": "^6.24.1",
 | 
				
			||||||
    "babel-preset-es2017": "^6.16.0",
 | 
					    "babel-preset-es2016": "^6.24.1",
 | 
				
			||||||
    "babel-preset-react": "^6.16.0",
 | 
					    "babel-preset-es2017": "^6.24.1",
 | 
				
			||||||
    "babel-preset-stage-2": "^6.17.0",
 | 
					    "babel-preset-react": "^6.24.1",
 | 
				
			||||||
    "chokidar": "^1.6.1",
 | 
					    "babel-preset-stage-2": "^6.24.1",
 | 
				
			||||||
 | 
					    "chokidar": "^2.0.4",
 | 
				
			||||||
 | 
					    "concurrently": "^4.0.1",
 | 
				
			||||||
    "cpx": "^1.3.2",
 | 
					    "cpx": "^1.3.2",
 | 
				
			||||||
    "cross-env": "^4.0.0",
 | 
					    "cross-env": "^4.0.0",
 | 
				
			||||||
    "css-raw-loader": "^0.1.1",
 | 
					    "css-loader": "^2.1.0",
 | 
				
			||||||
    "electron-builder": "^11.2.4",
 | 
					    "electron-builder": "^21.2.0",
 | 
				
			||||||
    "electron-builder-squirrel-windows": "^11.2.1",
 | 
					    "electron-builder-squirrel-windows": "^21.2.0",
 | 
				
			||||||
    "electron-devtools-installer": "^2.2.0",
 | 
					    "electron-devtools-installer": "^2.2.4",
 | 
				
			||||||
    "emojione": "^2.2.7",
 | 
					    "electron-notarize": "^0.1.1",
 | 
				
			||||||
    "eslint": "^3.14.0",
 | 
					    "eslint": "^5.8.0",
 | 
				
			||||||
    "eslint-config-google": "^0.7.1",
 | 
					    "eslint-config-google": "^0.7.1",
 | 
				
			||||||
    "eslint-plugin-babel": "^4.1.1",
 | 
					    "eslint-plugin-babel": "^4.1.2",
 | 
				
			||||||
    "eslint-plugin-flowtype": "^2.30.0",
 | 
					    "eslint-plugin-flowtype": "^2.50.3",
 | 
				
			||||||
    "eslint-plugin-react": "^7.4.0",
 | 
					    "eslint-plugin-react": "^7.11.1",
 | 
				
			||||||
    "expect": "^1.16.0",
 | 
					    "expect": "^1.16.0",
 | 
				
			||||||
 | 
					    "file-loader": "^3.0.1",
 | 
				
			||||||
    "fs-extra": "^0.30.0",
 | 
					    "fs-extra": "^0.30.0",
 | 
				
			||||||
    "html-webpack-plugin": "^2.24.0",
 | 
					    "html-webpack-plugin": "^3.2.0",
 | 
				
			||||||
    "json-loader": "^0.5.3",
 | 
					    "json-loader": "^0.5.3",
 | 
				
			||||||
    "karma": "^1.7.0",
 | 
					    "karma": "^3.1.2",
 | 
				
			||||||
    "karma-chrome-launcher": "^0.2.3",
 | 
					    "karma-chrome-launcher": "^2.2.0",
 | 
				
			||||||
    "karma-cli": "^0.1.2",
 | 
					    "karma-cli": "^1.0.1",
 | 
				
			||||||
    "karma-junit-reporter": "^0.4.1",
 | 
					 | 
				
			||||||
    "karma-logcapture-reporter": "0.0.1",
 | 
					    "karma-logcapture-reporter": "0.0.1",
 | 
				
			||||||
    "karma-mocha": "^0.2.2",
 | 
					    "karma-mocha": "^1.3.0",
 | 
				
			||||||
    "karma-sourcemap-loader": "^0.3.7",
 | 
					    "karma-sourcemap-loader": "^0.3.7",
 | 
				
			||||||
    "karma-spec-reporter": "0.0.31",
 | 
					    "karma-spec-reporter": "0.0.31",
 | 
				
			||||||
    "karma-summary-reporter": "^1.3.3",
 | 
					    "karma-summary-reporter": "^1.5.1",
 | 
				
			||||||
    "karma-webpack": "^1.7.0",
 | 
					    "karma-webpack": "4.0.0-beta.0",
 | 
				
			||||||
    "matrix-mock-request": "^1.2.0",
 | 
					    "loader-utils": "^1.2.3",
 | 
				
			||||||
    "matrix-react-test-utils": "^0.2.0",
 | 
					    "matrix-mock-request": "^1.2.3",
 | 
				
			||||||
 | 
					    "matrix-react-test-utils": "^0.2.2",
 | 
				
			||||||
    "minimist": "^1.2.0",
 | 
					    "minimist": "^1.2.0",
 | 
				
			||||||
    "mkdirp": "^0.5.1",
 | 
					    "mkdirp": "^0.5.1",
 | 
				
			||||||
    "mocha": "^2.4.5",
 | 
					    "mocha": "^5.2.0",
 | 
				
			||||||
    "parallelshell": "^3.0.2",
 | 
					 | 
				
			||||||
    "postcss-extend": "^1.0.5",
 | 
					    "postcss-extend": "^1.0.5",
 | 
				
			||||||
    "postcss-import": "^9.0.0",
 | 
					    "postcss-import": "^11.1.0",
 | 
				
			||||||
    "postcss-loader": "^1.2.2",
 | 
					    "postcss-loader": "^2.1.6",
 | 
				
			||||||
    "postcss-mixins": "^5.4.1",
 | 
					    "postcss-mixins": "^6.2.0",
 | 
				
			||||||
    "postcss-nested": "^1.0.0",
 | 
					    "postcss-nested": "^3.0.0",
 | 
				
			||||||
    "postcss-scss": "^0.4.0",
 | 
					    "postcss-scss": "^1.0.6",
 | 
				
			||||||
    "postcss-simple-vars": "^3.0.0",
 | 
					    "postcss-simple-vars": "^4.1.0",
 | 
				
			||||||
    "postcss-strip-inline-comments": "^0.1.5",
 | 
					    "postcss-strip-inline-comments": "^0.1.5",
 | 
				
			||||||
    "react-addons-perf": "^15.4.0",
 | 
					 | 
				
			||||||
    "react-addons-test-utils": "^15.6.0",
 | 
					 | 
				
			||||||
    "rimraf": "^2.4.3",
 | 
					    "rimraf": "^2.4.3",
 | 
				
			||||||
    "source-map-loader": "^0.1.5",
 | 
					    "shell-escape": "^0.2.0",
 | 
				
			||||||
    "webpack": "^1.12.14",
 | 
					    "source-map-loader": "^0.2.4",
 | 
				
			||||||
    "webpack-dev-server": "^1.16.2"
 | 
					    "webpack": "^4.23.1",
 | 
				
			||||||
  },
 | 
					    "webpack-cli": "^3.1.2",
 | 
				
			||||||
  "optionalDependencies": {
 | 
					    "webpack-dev-server": "^3.1.11"
 | 
				
			||||||
    "olm": "https://matrix.org/packages/npm/olm/olm-2.2.1.tgz"
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "build": {
 | 
					  "build": {
 | 
				
			||||||
    "appId": "im.riot.app",
 | 
					    "appId": "im.riot.app",
 | 
				
			||||||
    "category": "Network",
 | 
					    "electronVersion": "6.0.11",
 | 
				
			||||||
    "electronVersion": "1.7.9",
 | 
					 | 
				
			||||||
    "//asar=false": "https://github.com/electron-userland/electron-builder/issues/675",
 | 
					 | 
				
			||||||
    "asar": false,
 | 
					 | 
				
			||||||
    "dereference": true,
 | 
					 | 
				
			||||||
    "//files": "We bundle everything, so we only need to include webapp/",
 | 
					 | 
				
			||||||
    "files": [
 | 
					    "files": [
 | 
				
			||||||
      "node_modules/**",
 | 
					      "node_modules/**",
 | 
				
			||||||
      "src/**",
 | 
					      "src/**"
 | 
				
			||||||
      "img/**"
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "extraResources": [
 | 
					    "extraResources": [
 | 
				
			||||||
      "webapp/**/*"
 | 
					      {
 | 
				
			||||||
 | 
					        "from": "electron_app/img",
 | 
				
			||||||
 | 
					        "to": "img"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "webapp/**/*",
 | 
				
			||||||
 | 
					      "origin_migrator/**/*"
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "linux": {
 | 
					    "linux": {
 | 
				
			||||||
      "target": "deb",
 | 
					      "target": "deb",
 | 
				
			||||||
@ -174,13 +175,23 @@
 | 
				
			|||||||
        "StartupWMClass": "riot"
 | 
					        "StartupWMClass": "riot"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "deb": {
 | 
				
			||||||
 | 
					      "afterInstall": "electron_app/build/linux/after-install.tpl"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "mac": {
 | 
				
			||||||
 | 
					      "category": "public.app-category.social-networking",
 | 
				
			||||||
 | 
					      "darkModeSupport": true
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "win": {
 | 
					    "win": {
 | 
				
			||||||
      "target": "squirrel"
 | 
					      "target": {
 | 
				
			||||||
 | 
					        "target": "squirrel"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "directories": {
 | 
					    "directories": {
 | 
				
			||||||
      "buildResources": "electron_app/build",
 | 
					      "buildResources": "electron_app/build",
 | 
				
			||||||
      "output": "electron_app/dist",
 | 
					      "output": "electron_app/dist",
 | 
				
			||||||
      "app": "electron_app"
 | 
					      "app": "electron_app"
 | 
				
			||||||
    }
 | 
					    },
 | 
				
			||||||
 | 
					    "afterSign": "scripts/electron_afterSign.js"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										20
									
								
								release.sh
									
									
									
									
									
								
							
							
						
						@ -1,18 +1,27 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					#!/bin/bash
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Script to perform a release of vector-web.
 | 
					# Script to perform a release of riot-web.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Requires github-changelog-generator; to install, do
 | 
					# Requires github-changelog-generator; to install, do
 | 
				
			||||||
#   pip install git+https://github.com/matrix-org/github-changelog-generator.git
 | 
					#   pip install git+https://github.com/matrix-org/github-changelog-generator.git
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set -e
 | 
					set -e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					orig_args=$@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# chomp any args starting with '-' as these need to go
 | 
				
			||||||
 | 
					# through to the release script and otherwise we'll get
 | 
				
			||||||
 | 
					# confused about what the version arg is.
 | 
				
			||||||
 | 
					while [[ "$1" == -* ]]; do
 | 
				
			||||||
 | 
					    shift
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cd `dirname $0`
 | 
					cd `dirname $0`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
for i in matrix-js-sdk matrix-react-sdk
 | 
					for i in matrix-js-sdk matrix-react-sdk
 | 
				
			||||||
do
 | 
					do
 | 
				
			||||||
    depver=`cat package.json | jq -r .dependencies[\"$i\"]`
 | 
					    depver=`cat package.json | jq -r .dependencies[\"$i\"]`
 | 
				
			||||||
    latestver=`npm show $i version`
 | 
					    latestver=`yarn info -s $i version`
 | 
				
			||||||
    if [ "$depver" != "$latestver" ]
 | 
					    if [ "$depver" != "$latestver" ]
 | 
				
			||||||
    then
 | 
					    then
 | 
				
			||||||
        echo "The latest version of $i is $latestver but package.json depends on $depver"
 | 
					        echo "The latest version of $i is $latestver but package.json depends on $depver"
 | 
				
			||||||
@ -29,13 +38,12 @@ done
 | 
				
			|||||||
# bump Electron's package.json first
 | 
					# bump Electron's package.json first
 | 
				
			||||||
release="${1#v}"
 | 
					release="${1#v}"
 | 
				
			||||||
tag="v${release}"
 | 
					tag="v${release}"
 | 
				
			||||||
echo "electron npm version"
 | 
					echo "electron yarn version"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cd electron_app
 | 
					cd electron_app
 | 
				
			||||||
npm version --no-git-tag-version "$release"
 | 
					yarn version --no-git-tag-version --new-version "$release"
 | 
				
			||||||
git commit package.json -m "$tag"
 | 
					git commit package.json -m "$tag"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
cd ..
 | 
					cd ..
 | 
				
			||||||
 | 
					
 | 
				
			||||||
exec ./node_modules/matrix-js-sdk/release.sh -z "$@"
 | 
					exec ./node_modules/matrix-js-sdk/release.sh -u vector-im -z "$orig_args"
 | 
				
			||||||
 | 
				
			|||||||
@ -1 +1 @@
 | 
				
			|||||||
signing_id: packages@riot.im
 | 
					signing_id: releases@riot.im
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								res/flags/AD.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 2.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AE.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 1015 B  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AF.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 2.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AG.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 4.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AI.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 4.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AL.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 3.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AM.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 654 B  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AO.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 2.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AQ.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 3.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AR.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 1.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AS.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 3.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AT.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 655 B  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AU.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 5.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AW.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 1.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AX.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 1.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/AZ.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 1.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BA.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 3.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BB.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 2.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BD.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 2.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BE.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 558 B  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BF.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 1.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BG.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 659 B  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BH.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 1.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BI.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 5.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BJ.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 811 B  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BL.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 566 B  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BM.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 5.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BN.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 5.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BO.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 668 B  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BQ.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 672 B  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BR.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 4.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BS.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 2.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BT.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 4.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BV.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 1.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BW.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 669 B  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BY.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 2.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/BZ.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 5.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/CA.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 2.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/CC.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 3.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/CD.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 3.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/CF.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 2.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/CG.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 1.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/CH.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 1.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								res/flags/CI.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 568 B  |