From 20abb2c2dfd15eb339d9730589cf65fada4299cb Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 21 Apr 2017 13:01:10 +0100
Subject: [PATCH 001/147] Add Forward Message button to m.room.message events
Conform this file to eslint
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
.../views/context_menus/MessageContextMenu.js | 64 ++++++++++++-------
1 file changed, 41 insertions(+), 23 deletions(-)
diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js
index db416b8a..4a6c9788 100644
--- a/src/components/views/context_menus/MessageContextMenu.js
+++ b/src/components/views/context_menus/MessageContextMenu.js
@@ -16,13 +16,13 @@ limitations under the License.
'use strict';
-var React = require('react');
+const React = require('react');
-var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
-var dis = require('matrix-react-sdk/lib/dispatcher');
-var sdk = require('matrix-react-sdk');
-var Modal = require('matrix-react-sdk/lib/Modal');
-var Resend = require("matrix-react-sdk/lib/Resend");
+const MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
+const dis = require('matrix-react-sdk/lib/dispatcher');
+const sdk = require('matrix-react-sdk');
+const Modal = require('matrix-react-sdk/lib/Modal');
+const Resend = require("matrix-react-sdk/lib/Resend");
import * as UserSettingsStore from 'matrix-react-sdk/lib/UserSettingsStore';
module.exports = React.createClass({
@@ -45,7 +45,7 @@ module.exports = React.createClass({
},
onViewSourceClick: function() {
- var ViewSource = sdk.getComponent('structures.ViewSource');
+ const ViewSource = sdk.getComponent('structures.ViewSource');
Modal.createDialog(ViewSource, {
content: this.props.mxEvent.event,
}, 'mx_Dialog_viewsource');
@@ -70,12 +70,12 @@ module.exports = React.createClass({
MatrixClientPeg.get().redactEvent(
this.props.mxEvent.getRoomId(), this.props.mxEvent.getId()
).catch(function(e) {
- var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
+ const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
// display error message stating you couldn't delete this.
- var code = e.errcode || e.statusCode;
+ const code = e.errcode || e.statusCode;
Modal.createDialog(ErrorDialog, {
title: "Error",
- description: "You cannot delete this message. (" + code + ")"
+ description: "You cannot delete this message. (" + code + ")",
});
}).done();
},
@@ -88,6 +88,14 @@ module.exports = React.createClass({
if (this.props.onFinished) this.props.onFinished();
},
+ onForwardClick: function() {
+ dis.dispatch({
+ action: 'forward_message',
+ content: this.props.mxEvent.getContent(),
+ });
+ this.closeMenu();
+ },
+
closeMenu: function() {
if (this.props.onFinished) this.props.onFinished();
},
@@ -99,7 +107,7 @@ module.exports = React.createClass({
if (this.props.onFinished) this.props.onFinished();
},
- onQuoteClick: function () {
+ onQuoteClick: function() {
console.log(this.props.mxEvent);
dis.dispatch({
action: 'quote',
@@ -108,15 +116,16 @@ module.exports = React.createClass({
},
render: function() {
- var eventStatus = this.props.mxEvent.status;
- var resendButton;
- var viewSourceButton;
- var viewClearSourceButton;
- var redactButton;
- var cancelButton;
- var permalinkButton;
- var unhidePreviewButton;
- var externalURLButton;
+ const eventStatus = this.props.mxEvent.status;
+ let resendButton;
+ let redactButton;
+ let cancelButton;
+ let forwardButton;
+ let viewSourceButton;
+ let viewClearSourceButton;
+ let unhidePreviewButton;
+ let permalinkButton;
+ let externalURLButton;
if (eventStatus === 'not_sent') {
resendButton = (
@@ -142,6 +151,14 @@ module.exports = React.createClass({
);
}
+ if (this.props.mxEvent.getType() === 'm.room.message') {
+ forwardButton = (
+
+ Forward Message
+
+ );
+ }
+
viewSourceButton = (
View Source
@@ -162,7 +179,7 @@ module.exports = React.createClass({
Unhide Preview
- )
+ );
}
}
@@ -185,7 +202,7 @@ module.exports = React.createClass({
externalURLButton = (
Source URL
+ rel="noopener" target="_blank" onClick={ this.closeMenu }>Source URL
);
}
@@ -196,6 +213,7 @@ module.exports = React.createClass({
{resendButton}
{redactButton}
{cancelButton}
+ {forwardButton}
{viewSourceButton}
{viewClearSourceButton}
{unhidePreviewButton}
@@ -204,5 +222,5 @@ module.exports = React.createClass({
{externalURLButton}
);
- }
+ },
});
From 77ce58b59d8e382568cf436f5eeaef56d6a495f6 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 21 Apr 2017 12:58:43 +0100
Subject: [PATCH 002/147] add .idea to .gitignore so I don't accidentally push
my IDE config
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index c28df64c..c9e9b250 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,4 @@
npm-debug.log
electron/dist
electron/pub
+/.idea
From 92b52a61e71f808a65afc0e4d93aa9a08f5a022b Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Mon, 24 Apr 2017 18:33:25 +0100
Subject: [PATCH 003/147] don't show forward option for things we cannot
decrypt
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
src/components/views/context_menus/MessageContextMenu.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js
index 4a6c9788..5de8d18d 100644
--- a/src/components/views/context_menus/MessageContextMenu.js
+++ b/src/components/views/context_menus/MessageContextMenu.js
@@ -151,7 +151,8 @@ module.exports = React.createClass({
);
}
- if (this.props.mxEvent.getType() === 'm.room.message') {
+ if (this.props.mxEvent.getType() === 'm.room.message'
+ && this.props.mxEvent.getContent().msgtype !== 'm.bad.encrypted') {
forwardButton = (
Forward Message
From 9124c1475aecbe6dd6713e3ec5e2c80c5528c3c9 Mon Sep 17 00:00:00 2001
From: turt2live
Date: Mon, 24 Apr 2017 12:48:32 -0600
Subject: [PATCH 004/147] Change redact -> remove to improve clarity
Addresses #2814
Non-technical users may not understand what 'redact' means and can more easily understand what 'Remove' does. See discussion on vector-im/riot-web#2814 for more information.
Signed-off-by: Travis Ralston
---
src/components/views/context_menus/MessageContextMenu.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js
index db416b8a..5a7356a1 100644
--- a/src/components/views/context_menus/MessageContextMenu.js
+++ b/src/components/views/context_menus/MessageContextMenu.js
@@ -129,7 +129,7 @@ module.exports = React.createClass({
if (!eventStatus && !this.props.mxEvent.isRedacted()) { // sent and not redacted
redactButton = (
- Redact
+ Remove
);
}
From 0a1ebc2487cf3f85f017b93f21088215136342a2 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Mon, 24 Apr 2017 22:43:02 +0100
Subject: [PATCH 005/147] Don't show for anything that doesn't have a msgtype
and body otherwise the server will just reject it anyway
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
.../views/context_menus/MessageContextMenu.js | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js
index 5de8d18d..002ec5bc 100644
--- a/src/components/views/context_menus/MessageContextMenu.js
+++ b/src/components/views/context_menus/MessageContextMenu.js
@@ -151,13 +151,17 @@ module.exports = React.createClass({
);
}
- if (this.props.mxEvent.getType() === 'm.room.message'
- && this.props.mxEvent.getContent().msgtype !== 'm.bad.encrypted') {
- forwardButton = (
-
- Forward Message
-
- );
+ if (this.props.mxEvent.getType() === 'm.room.message') {
+ const content = this.props.mxEvent.getContent();
+ if (content.msgtype // truthy check msgtype
+ && content.msgtype !== 'm.bad.encrypted'
+ && content.hasOwnProperty('body')) {
+ forwardButton = (
+
+ Forward Message
+
+ );
+ }
}
viewSourceButton = (
From bbda658b7f7e0dd4b173b2b4ed02484ff9eba170 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Sat, 13 May 2017 12:37:13 +0100
Subject: [PATCH 006/147] make Electron tray icon mimic the Favico.js one DRY:
moved Favicon stuff into the base platform
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
electron_app/src/tray.js | 16 ++++----
src/vector/platform/VectorBasePlatform.js | 47 ++++++++++++++++++++++-
src/vector/platform/WebPlatform.js | 44 ---------------------
3 files changed, 55 insertions(+), 52 deletions(-)
diff --git a/electron_app/src/tray.js b/electron_app/src/tray.js
index 2ccdf40c..ab3a8e1c 100644
--- a/electron_app/src/tray.js
+++ b/electron_app/src/tray.js
@@ -15,12 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-const path = require('path');
-const electron = require('electron');
-
-const app = electron.app;
-const Tray = electron.Tray;
-const MenuItem = electron.MenuItem;
+const {app, Tray, Menu, nativeImage} = require('electron');
let trayIcon = null;
@@ -44,7 +39,7 @@ exports.create = function (win, config) {
}
};
- const contextMenu = electron.Menu.buildFromTemplate([
+ const contextMenu = Menu.buildFromTemplate([
{
label: 'Show/Hide ' + config.brand,
click: toggleWin
@@ -64,4 +59,11 @@ exports.create = function (win, config) {
trayIcon.setToolTip(config.brand);
trayIcon.setContextMenu(contextMenu);
trayIcon.on('click', toggleWin);
+
+ win.webContents.on('page-favicon-updated', function(ev, favicons) {
+ try {
+ const img = nativeImage.createFromDataURL(favicons[0]);
+ trayIcon.setImage(img);
+ } catch (e) {console.error(e);}
+ });
};
diff --git a/src/vector/platform/VectorBasePlatform.js b/src/vector/platform/VectorBasePlatform.js
index 1466b76a..00c9c47c 100644
--- a/src/vector/platform/VectorBasePlatform.js
+++ b/src/vector/platform/VectorBasePlatform.js
@@ -17,12 +17,57 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import BasePlatform from 'matrix-react-sdk/lib/BasePlatform'
+import BasePlatform from 'matrix-react-sdk/lib/BasePlatform';
+import Favico from 'favico.js';
/**
* Vector-specific extensions to the BasePlatform template
*/
export default class VectorBasePlatform extends BasePlatform {
+ constructor() {
+ super();
+
+ // The 'animations' are really low framerate and look terrible.
+ // Also it re-starts the animationb every time you set the badge,
+ // and we set the state each time, even if the value hasn't changed,
+ // so we'd need to fix that if enabling the animation.
+ this.favicon = new Favico({animation: 'none'});
+ this._updateFavicon();
+ }
+
+ _updateFavicon() {
+ try {
+ // This needs to be in in a try block as it will throw
+ // if there are more than 100 badge count changes in
+ // its internal queue
+ let bgColor = "#d00",
+ notif = this.notificationCount;
+
+ if (this.errorDidOccur) {
+ notif = notif || "×";
+ bgColor = "#f00";
+ }
+
+ this.favicon.badge(notif, {
+ bgColor: bgColor,
+ });
+ } catch (e) {
+ console.warn(`Failed to set badge count: ${e.message}`);
+ }
+ }
+
+ setNotificationCount(count: number) {
+ if (this.notificationCount === count) return;
+ super.setNotificationCount(count);
+ this._updateFavicon();
+ }
+
+ setErrorStatus(errorDidOccur: boolean) {
+ if (this.errorDidOccur === errorDidOccur) return;
+ super.setErrorStatus(errorDidOccur);
+ this._updateFavicon();
+ }
+
/**
* Check for the availability of an update to the version of the
* app that's currently running.
diff --git a/src/vector/platform/WebPlatform.js b/src/vector/platform/WebPlatform.js
index 72ca19f0..204317ba 100644
--- a/src/vector/platform/WebPlatform.js
+++ b/src/vector/platform/WebPlatform.js
@@ -18,7 +18,6 @@ limitations under the License.
*/
import VectorBasePlatform from './VectorBasePlatform';
-import Favico from 'favico.js';
import request from 'browser-request';
import dis from 'matrix-react-sdk/lib/dispatcher.js';
import q from 'q';
@@ -27,49 +26,6 @@ import url from 'url';
import UAParser from 'ua-parser-js';
export default class WebPlatform extends VectorBasePlatform {
- constructor() {
- super();
- this.runningVersion = null;
- // The 'animations' are really low framerate and look terrible.
- // Also it re-starts the animationb every time you set the badge,
- // and we set the state each time, even if the value hasn't changed,
- // so we'd need to fix that if enabling the animation.
- this.favicon = new Favico({animation: 'none'});
- this._updateFavicon();
- }
-
- _updateFavicon() {
- try {
- // This needs to be in in a try block as it will throw
- // if there are more than 100 badge count changes in
- // its internal queue
- let bgColor = "#d00",
- notif = this.notificationCount;
-
- if (this.errorDidOccur) {
- notif = notif || "×";
- bgColor = "#f00";
- }
-
- this.favicon.badge(notif, {
- bgColor: bgColor,
- });
- } catch (e) {
- console.warn(`Failed to set badge count: ${e.message}`);
- }
- }
-
- setNotificationCount(count: number) {
- if (this.notificationCount === count) return;
- super.setNotificationCount(count);
- this._updateFavicon();
- }
-
- setErrorStatus(errorDidOccur: boolean) {
- if (this.errorDidOccur === errorDidOccur) return;
- super.setErrorStatus(errorDidOccur);
- this._updateFavicon();
- }
/**
* Returns true if the platform supports displaying
From 8927afca036cda1f0cc2b1c0cac23f4510fa351d Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Sat, 13 May 2017 12:37:27 +0100
Subject: [PATCH 007/147] re-add electron node modules to gitignore
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
.gitignore | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index 6dd2b988..6072f0ff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,7 +5,7 @@
/key.pem
/lib
/node_modules
-/electron/node_modules
+/electron_app/node_modules
/packages/
/webapp
/.npmrc
From 6aae97b81204e20ef463ecbfa903af7658dbd6de Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Sat, 13 May 2017 12:39:55 +0100
Subject: [PATCH 008/147] Update tray tooltip based on document.title
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
electron_app/src/tray.js | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/electron_app/src/tray.js b/electron_app/src/tray.js
index ab3a8e1c..b0a657a0 100644
--- a/electron_app/src/tray.js
+++ b/electron_app/src/tray.js
@@ -66,4 +66,8 @@ exports.create = function (win, config) {
trayIcon.setImage(img);
} catch (e) {console.error(e);}
});
+
+ win.webContents.on('page-title-updated', function(ev, title) {
+ trayIcon.setToolTip(title);
+ });
};
From 808240eef9bfef0a4e685933bd986b8347bead1e Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Sat, 13 May 2017 12:40:17 +0100
Subject: [PATCH 009/147] shouldn't need this try-catch
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
electron_app/src/tray.js | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/electron_app/src/tray.js b/electron_app/src/tray.js
index b0a657a0..75104042 100644
--- a/electron_app/src/tray.js
+++ b/electron_app/src/tray.js
@@ -61,10 +61,7 @@ exports.create = function (win, config) {
trayIcon.on('click', toggleWin);
win.webContents.on('page-favicon-updated', function(ev, favicons) {
- try {
- const img = nativeImage.createFromDataURL(favicons[0]);
- trayIcon.setImage(img);
- } catch (e) {console.error(e);}
+ trayIcon.setImage(nativeImage.createFromDataURL(favicons[0]));
});
win.webContents.on('page-title-updated', function(ev, title) {
From aa7728cad39f388f607cea1eb810eec5ea33a4f2 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Sat, 13 May 2017 12:41:13 +0100
Subject: [PATCH 010/147] tidy up tray.js - it made my eyes hurt
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
electron_app/src/tray.js | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/electron_app/src/tray.js b/electron_app/src/tray.js
index 75104042..7198356c 100644
--- a/electron_app/src/tray.js
+++ b/electron_app/src/tray.js
@@ -21,15 +21,15 @@ let trayIcon = null;
exports.hasTray = function hasTray() {
return (trayIcon !== null);
-}
+};
-exports.create = function (win, config) {
+exports.create = function(win, config) {
// no trays on darwin
if (process.platform === 'darwin' || trayIcon) {
return;
}
- const toggleWin = function () {
+ const toggleWin = function() {
if (win.isVisible() && !win.isMinimized()) {
win.hide();
} else {
@@ -42,17 +42,17 @@ exports.create = function (win, config) {
const contextMenu = Menu.buildFromTemplate([
{
label: 'Show/Hide ' + config.brand,
- click: toggleWin
+ click: toggleWin,
},
{
- type: 'separator'
+ type: 'separator',
},
{
label: 'Quit',
- click: function () {
+ click: function() {
app.quit();
- }
- }
+ },
+ },
]);
trayIcon = new Tray(config.icon_path);
From cef26a5b20601904ae104cf1688f9721edfb83c8 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@googlemail.com>
Date: Mon, 15 May 2017 21:14:01 +0100
Subject: [PATCH 011/147] fix #3894
---
scripts/package.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/package.sh b/scripts/package.sh
index cffb6d28..23d0925b 100755
--- a/scripts/package.sh
+++ b/scripts/package.sh
@@ -21,7 +21,7 @@ npm run build$dev
cp config.sample.json webapp/
mkdir -p dist
-cp -r webapp vector-$version
+cp -r webapp riot-$version
# if $version looks like semver with leading v, strip it before writing to file
if [[ ${version} =~ ^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+(-.+)?$ ]]; then
From 3cead032c2fe1a0b0034c2a3b2c06248ebc2c564 Mon Sep 17 00:00:00 2001
From: David Baker
Date: Tue, 16 May 2017 16:27:58 +0100
Subject: [PATCH 012/147] Revert "Merge pull request #3804 from
vector-im/dbkr/left_panel_for_newbies_2"
This reverts commit e6133820a2f70f94e693f6352da71c03ef5a079a, reversing
changes made to d1db602b3a3e735430016af2fc837841feafdb43.
---
src/components/structures/BottomLeftMenu.js | 127 +++++++++++++++---
src/components/structures/RoomSubList.js | 19 ++-
.../structures/RoomSubListHeader.js | 44 +++---
src/skins/vector/css/_components.scss | 1 -
.../views/elements/_RoleButton.scss | 33 -----
.../views/rooms/_RoomList.scss | 23 ----
.../css/vector-web/structures/_LeftPanel.scss | 34 +++--
7 files changed, 170 insertions(+), 111 deletions(-)
delete mode 100644 src/skins/vector/css/matrix-react-sdk/views/elements/_RoleButton.scss
diff --git a/src/components/structures/BottomLeftMenu.js b/src/components/structures/BottomLeftMenu.js
index 63dfac60..f378cac6 100644
--- a/src/components/structures/BottomLeftMenu.js
+++ b/src/components/structures/BottomLeftMenu.js
@@ -1,6 +1,5 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
-Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -15,8 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import React from 'react';
-import sdk from 'matrix-react-sdk';
+'use strict';
+
+var React = require('react');
+var ReactDOM = require('react-dom');
+var sdk = require('matrix-react-sdk')
+var dis = require('matrix-react-sdk/lib/dispatcher');
+var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
module.exports = React.createClass({
displayName: 'BottomLeftMenu',
@@ -26,28 +30,121 @@ module.exports = React.createClass({
teamToken: React.PropTypes.string,
},
+ getInitialState: function() {
+ return({
+ directoryHover : false,
+ roomsHover : false,
+ homeHover: false,
+ peopleHover : false,
+ settingsHover : false,
+ });
+ },
+
+ // Room events
+ onDirectoryClick: function() {
+ dis.dispatch({ action: 'view_room_directory' });
+ },
+
+ onDirectoryMouseEnter: function() {
+ this.setState({ directoryHover: true });
+ },
+
+ onDirectoryMouseLeave: function() {
+ this.setState({ directoryHover: false });
+ },
+
+ onRoomsClick: function() {
+ dis.dispatch({ action: 'view_create_room' });
+ },
+
+ onRoomsMouseEnter: function() {
+ this.setState({ roomsHover: true });
+ },
+
+ onRoomsMouseLeave: function() {
+ this.setState({ roomsHover: false });
+ },
+
+ // Home button events
+ onHomeClick: function() {
+ dis.dispatch({ action: 'view_home_page' });
+ },
+
+ onHomeMouseEnter: function() {
+ this.setState({ homeHover: true });
+ },
+
+ onHomeMouseLeave: function() {
+ this.setState({ homeHover: false });
+ },
+
+ // People events
+ onPeopleClick: function() {
+ dis.dispatch({ action: 'view_create_chat' });
+ },
+
+ onPeopleMouseEnter: function() {
+ this.setState({ peopleHover: true });
+ },
+
+ onPeopleMouseLeave: function() {
+ this.setState({ peopleHover: false });
+ },
+
+ // Settings events
+ onSettingsClick: function() {
+ dis.dispatch({ action: 'view_user_settings' });
+ },
+
+ onSettingsMouseEnter: function() {
+ this.setState({ settingsHover: true });
+ },
+
+ onSettingsMouseLeave: function() {
+ this.setState({ settingsHover: false });
+ },
+
+ // Get the label/tooltip to show
+ getLabel: function(label, show) {
+ if (show) {
+ var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
+ return ;
+ }
+ },
+
render: function() {
- const HomeButton = sdk.getComponent('elements.HomeButton');
- const StartChatButton = sdk.getComponent('elements.StartChatButton');
- const RoomDirectoryButton = sdk.getComponent('elements.RoomDirectoryButton');
- const CreateRoomButton = sdk.getComponent('elements.CreateRoomButton');
- const SettingsButton = sdk.getComponent('elements.SettingsButton');
+ var TintableSvg = sdk.getComponent('elements.TintableSvg');
var homeButton;
if (this.props.teamToken) {
- homeButton = ;
+ homeButton = (
+
+
+ { this.getLabel("Welcome page", this.state.homeHover) }
+
+ );
}
return (
{ homeButton }
-
-
-
-
-
-
+
+
+ { this.getLabel("Start chat", this.state.peopleHover) }
+
+
+
+ { this.getLabel("Room directory", this.state.directoryHover) }
+
+
+
+ { this.getLabel("Create new room", this.state.roomsHover) }
+
+
+
+ { this.getLabel("Settings", this.state.settingsHover) }
+
);
diff --git a/src/components/structures/RoomSubList.js b/src/components/structures/RoomSubList.js
index ab6c4422..c315ae46 100644
--- a/src/components/structures/RoomSubList.js
+++ b/src/components/structures/RoomSubList.js
@@ -1,5 +1,4 @@
/*
-Copyright 2017 Vector Creations Ltd
Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
@@ -84,8 +83,6 @@ var RoomSubList = React.createClass({
incomingCall: React.PropTypes.object,
onShowMoreRooms: React.PropTypes.func,
searchFilter: React.PropTypes.string,
- emptyContent: React.PropTypes.node, // content shown if the list is empty
- headerItems: React.PropTypes.node, // content shown in the sublist header
},
getInitialState: function() {
@@ -472,15 +469,16 @@ var RoomSubList = React.createClass({
render: function() {
var connectDropTarget = this.props.connectDropTarget;
+ var RoomDropTarget = sdk.getComponent('rooms.RoomDropTarget');
var TruncatedList = sdk.getComponent('elements.TruncatedList');
var label = this.props.collapsed ? null : this.props.label;
- let content;
- if (this.state.sortedList.length == 0) {
- content = this.props.emptyContent;
- } else {
- content = this.makeRoomTiles();
+ //console.log("render: " + JSON.stringify(this.state.sortedList));
+
+ var target;
+ if (this.state.sortedList.length == 0 && this.props.editable) {
+ target = ;
}
var roomCount = this.props.list.length > 0 ? this.props.list.length : '';
@@ -500,7 +498,8 @@ var RoomSubList = React.createClass({
if (!this.state.hidden) {
subList =
- { content }
+ { target }
+ { this.makeRoomTiles() }
;
}
else {
@@ -522,7 +521,6 @@ var RoomSubList = React.createClass({
roomNotificationCount={ this.roomNotificationCount() }
onClick={ this.onClick }
onHeaderClick={ this.props.onHeaderClick }
- headerItems={this.props.headerItems}
/>
{ subList }
@@ -544,7 +542,6 @@ var RoomSubList = React.createClass({
roomNotificationCount={ this.roomNotificationCount() }
onClick={ this.onClick }
onHeaderClick={ this.props.onHeaderClick }
- headerItems={this.props.headerItems}
/>
: undefined }
{ (this.props.showSpinner && !this.state.hidden) ? : undefined }
diff --git a/src/components/structures/RoomSubListHeader.js b/src/components/structures/RoomSubListHeader.js
index 74094ae0..ad9aff5f 100644
--- a/src/components/structures/RoomSubListHeader.js
+++ b/src/components/structures/RoomSubListHeader.js
@@ -14,11 +14,16 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import React from 'react';
-import classNames from 'classnames';
-import sdk from 'matrix-react-sdk';
-import { formatCount } from 'matrix-react-sdk/lib/utils/FormattingUtils';
-import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton';
+'use strict';
+
+var React = require('react');
+var ReactDOM = require('react-dom');
+var classNames = require('classnames');
+var sdk = require('matrix-react-sdk')
+var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils');
+var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs');
+var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
+var ConstantTimeDispatcher = require('matrix-react-sdk/lib/ConstantTimeDispatcher');
module.exports = React.createClass({
displayName: 'RoomSubListHeader',
@@ -37,7 +42,6 @@ module.exports = React.createClass({
hidden: React.PropTypes.bool,
onClick: React.PropTypes.func,
onHeaderClick: React.PropTypes.func,
- headerItems: React.PropTypes.node, // content shown in the sublist header
},
getDefaultProps: function() {
@@ -59,34 +63,35 @@ module.exports = React.createClass({
// },
render: function() {
- const TintableSvg = sdk.getComponent("elements.TintableSvg");
+ var TintableSvg = sdk.getComponent("elements.TintableSvg");
- const subListNotifications = this.props.roomNotificationCount;
- const subListNotifCount = subListNotifications[0];
- const subListNotifHighlight = subListNotifications[1];
+ var subListNotifications = this.props.roomNotificationCount;
+ var subListNotifCount = subListNotifications[0];
+ var subListNotifHighlight = subListNotifications[1];
- const chevronClasses = classNames({
+ var chevronClasses = classNames({
'mx_RoomSubList_chevron': true,
'mx_RoomSubList_chevronRight': this.props.hidden,
'mx_RoomSubList_chevronDown': !this.props.hidden,
});
- const badgeClasses = classNames({
+ var badgeClasses = classNames({
'mx_RoomSubList_badge': true,
'mx_RoomSubList_badgeHighlight': subListNotifHighlight,
});
- let badge;
+ var badge;
if (subListNotifCount > 0) {
- badge = { formatCount(subListNotifCount) }
;
- } else if (subListNotifHighlight) {
+ badge = { FormattingUtils.formatCount(subListNotifCount) }
;
+ }
+ else if (subListNotifHighlight) {
badge = !
;
}
// When collapsed, allow a long hover on the header to show user
// the full tag name and room count
- let title;
- const roomCount = this.props.roomCount;
+ var title;
+ var roomCount = this.props.roomCount;
if (this.props.collapsed) {
title = this.props.label;
if (roomCount !== '') {
@@ -94,9 +99,9 @@ module.exports = React.createClass({
}
}
- let incomingCall;
+ var incomingCall;
if (this.props.isIncomingCallRoom) {
- const IncomingCallBox = sdk.getComponent("voip.IncomingCallBox");
+ var IncomingCallBox = sdk.getComponent("voip.IncomingCallBox");
incomingCall = ;
}
@@ -104,7 +109,6 @@ module.exports = React.createClass({
{ this.props.collapsed ? '' : this.props.label }
- {this.props.headerItems}
{ roomCount }
{ badge }
diff --git a/src/skins/vector/css/_components.scss b/src/skins/vector/css/_components.scss
index 5b23bb82..df3c4600 100644
--- a/src/skins/vector/css/_components.scss
+++ b/src/skins/vector/css/_components.scss
@@ -27,7 +27,6 @@
@import "./matrix-react-sdk/views/elements/_MemberEventListSummary.scss";
@import "./matrix-react-sdk/views/elements/_ProgressBar.scss";
@import "./matrix-react-sdk/views/elements/_RichText.scss";
-@import "./matrix-react-sdk/views/elements/_RoleButton.scss";
@import "./matrix-react-sdk/views/login/_InteractiveAuthEntryComponents.scss";
@import "./matrix-react-sdk/views/login/_ServerConfig.scss";
@import "./matrix-react-sdk/views/messages/_MEmoteBody.scss";
diff --git a/src/skins/vector/css/matrix-react-sdk/views/elements/_RoleButton.scss b/src/skins/vector/css/matrix-react-sdk/views/elements/_RoleButton.scss
deleted file mode 100644
index 094e0b9b..00000000
--- a/src/skins/vector/css/matrix-react-sdk/views/elements/_RoleButton.scss
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-Copyright 2107 Vector Creations 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.
-*/
-
-.mx_RoleButton {
- margin-left: 4px;
- margin-right: 4px;
- cursor: pointer;
- display: inline-block;
-}
-
-.mx_RoleButton object {
- pointer-events: none;
-}
-
-.mx_RoleButton_tooltip {
- display: inline-block;
- position: relative;
- top: -25px;
- left: 6px;
-}
diff --git a/src/skins/vector/css/matrix-react-sdk/views/rooms/_RoomList.scss b/src/skins/vector/css/matrix-react-sdk/views/rooms/_RoomList.scss
index 35787ca0..110dcd5b 100644
--- a/src/skins/vector/css/matrix-react-sdk/views/rooms/_RoomList.scss
+++ b/src/skins/vector/css/matrix-react-sdk/views/rooms/_RoomList.scss
@@ -1,6 +1,5 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
-Copyright 2107 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -38,25 +37,3 @@ limitations under the License.
.mx_RoomList_scrollbar .gm-scrollbar.-vertical {
z-index: 6;
}
-
-.mx_RoomList_emptySubListTip {
- font-size: 13px;
- margin-left: 18px;
- margin-right: 18px;
- margin-top: 8px;
- margin-bottom: 7px;
- padding: 5px;
- border: 1px dashed $accent-color;
- color: $primary-fg-color;
- background-color: $droptarget-bg-color;
- border-radius: 4px;
-}
-
-.mx_RoomList_emptySubListTip .mx_RoleButton {
- vertical-align: -3px;
-}
-
-.mx_RoomList_headerButtons {
- position: absolute;
- right: 60px;
-}
diff --git a/src/skins/vector/css/vector-web/structures/_LeftPanel.scss b/src/skins/vector/css/vector-web/structures/_LeftPanel.scss
index f171591c..d3bbce1b 100644
--- a/src/skins/vector/css/vector-web/structures/_LeftPanel.scss
+++ b/src/skins/vector/css/vector-web/structures/_LeftPanel.scss
@@ -64,25 +64,43 @@ limitations under the License.
pointer-events: none;
}
-.collapsed .mx_RoleButton {
+.mx_LeftPanel .mx_BottomLeftMenu_homePage,
+.mx_LeftPanel .mx_BottomLeftMenu_directory,
+.mx_LeftPanel .mx_BottomLeftMenu_createRoom,
+.mx_LeftPanel .mx_BottomLeftMenu_people,
+.mx_LeftPanel .mx_BottomLeftMenu_settings {
+ display: inline-block;
+ cursor: pointer;
+}
+
+.collapsed .mx_BottomLeftMenu_homePage,
+.collapsed .mx_BottomLeftMenu_directory,
+.collapsed .mx_BottomLeftMenu_createRoom,
+.collapsed .mx_BottomLeftMenu_people,
+.collapsed .mx_BottomLeftMenu_settings {
margin-right: 0px ! important;
padding-top: 3px ! important;
padding-bottom: 3px ! important;
}
-.mx_BottomLeftMenu_options .mx_RoleButton {
- margin-left: 0px;
+.mx_LeftPanel .mx_BottomLeftMenu_homePage,
+.mx_LeftPanel .mx_BottomLeftMenu_directory,
+.mx_LeftPanel .mx_BottomLeftMenu_createRoom,
+.mx_LeftPanel .mx_BottomLeftMenu_people {
margin-right: 10px;
}
-.mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings {
+.mx_LeftPanel .mx_BottomLeftMenu_settings {
float: right;
}
-.mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings .mx_RoleButton {
- margin-right: 0px;
-}
-
.mx_LeftPanel.collapsed .mx_BottomLeftMenu_settings {
float: none;
}
+
+.mx_LeftPanel .mx_BottomLeftMenu_tooltip {
+ display: inline-block;
+ position: relative;
+ top: -25px;
+ left: 6px;
+}
From 03476705b1cccf03070bdc55af5139450dd1c1cc Mon Sep 17 00:00:00 2001
From: David Baker
Date: Tue, 16 May 2017 16:35:06 +0100
Subject: [PATCH 013/147] Revert "better solution to incomingcallbox weirdness"
This reverts commit be527874730d959fa980e81c897a658a03952aad.
---
src/components/structures/RoomSubListHeader.js | 2 +-
.../css/matrix-react-sdk/views/voip/_IncomingCallbox.scss | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/components/structures/RoomSubListHeader.js b/src/components/structures/RoomSubListHeader.js
index ad9aff5f..eb73f721 100644
--- a/src/components/structures/RoomSubListHeader.js
+++ b/src/components/structures/RoomSubListHeader.js
@@ -112,8 +112,8 @@ module.exports = React.createClass({
{ roomCount }
{ badge }
+ { incomingCall }
- { incomingCall }
);
},
diff --git a/src/skins/vector/css/matrix-react-sdk/views/voip/_IncomingCallbox.scss b/src/skins/vector/css/matrix-react-sdk/views/voip/_IncomingCallbox.scss
index 64eac25d..e63814f5 100644
--- a/src/skins/vector/css/matrix-react-sdk/views/voip/_IncomingCallbox.scss
+++ b/src/skins/vector/css/matrix-react-sdk/views/voip/_IncomingCallbox.scss
@@ -25,6 +25,8 @@ limitations under the License.
margin-top: -3px;
margin-left: -20px;
width: 200px;
+ font-weight: initial;
+ text-transform: initial;
}
.mx_IncomingCallBox_chevron {
From 9399b7ddf0cf7b272e527b9086fc6fe68db2e66d Mon Sep 17 00:00:00 2001
From: David Baker
Date: Tue, 16 May 2017 16:35:17 +0100
Subject: [PATCH 014/147] Revert "fix incoming call box"
This reverts commit b3431bb75008b068a2a1805803b91d0ff2616571.
---
src/components/structures/RoomSubList.js | 1 -
src/components/structures/RoomSubListHeader.js | 1 -
.../vector/css/matrix-react-sdk/structures/_RoomView.scss | 4 ++--
.../css/matrix-react-sdk/views/voip/_IncomingCallbox.scss | 2 --
4 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/components/structures/RoomSubList.js b/src/components/structures/RoomSubList.js
index c315ae46..f741a30f 100644
--- a/src/components/structures/RoomSubList.js
+++ b/src/components/structures/RoomSubList.js
@@ -516,7 +516,6 @@ var RoomSubList = React.createClass({
roomCount={ roomCount }
collapsed={ this.props.collapsed }
hidden={ this.state.hidden }
- incomingCall={ this.props.incomingCall }
isIncomingCallRoom={ isIncomingCallRoom }
roomNotificationCount={ this.roomNotificationCount() }
onClick={ this.onClick }
diff --git a/src/components/structures/RoomSubListHeader.js b/src/components/structures/RoomSubListHeader.js
index eb73f721..5618b39b 100644
--- a/src/components/structures/RoomSubListHeader.js
+++ b/src/components/structures/RoomSubListHeader.js
@@ -36,7 +36,6 @@ module.exports = React.createClass({
React.PropTypes.number
]),
collapsed: React.PropTypes.bool.isRequired, // is LeftPanel collapsed?
- incomingCall: React.PropTypes.object,
isIncomingCallRoom: React.PropTypes.bool,
roomNotificationCount: React.PropTypes.array,
hidden: React.PropTypes.bool,
diff --git a/src/skins/vector/css/matrix-react-sdk/structures/_RoomView.scss b/src/skins/vector/css/matrix-react-sdk/structures/_RoomView.scss
index e251ecd1..3d5fe029 100644
--- a/src/skins/vector/css/matrix-react-sdk/structures/_RoomView.scss
+++ b/src/skins/vector/css/matrix-react-sdk/structures/_RoomView.scss
@@ -172,7 +172,7 @@ hr.mx_RoomView_myReadMarker {
max-height: 0px;
background-color: $primary-bg-color;
- z-index: 5;
+ z-index: 1000;
overflow: hidden;
-webkit-transition: all .2s ease-out;
@@ -260,4 +260,4 @@ hr.mx_RoomView_myReadMarker {
.mx_RoomView_ongoingConfCallNotification a {
color: $accent-fg-color ! important;
-}
+}
\ No newline at end of file
diff --git a/src/skins/vector/css/matrix-react-sdk/views/voip/_IncomingCallbox.scss b/src/skins/vector/css/matrix-react-sdk/views/voip/_IncomingCallbox.scss
index e63814f5..64eac25d 100644
--- a/src/skins/vector/css/matrix-react-sdk/views/voip/_IncomingCallbox.scss
+++ b/src/skins/vector/css/matrix-react-sdk/views/voip/_IncomingCallbox.scss
@@ -25,8 +25,6 @@ limitations under the License.
margin-top: -3px;
margin-left: -20px;
width: 200px;
- font-weight: initial;
- text-transform: initial;
}
.mx_IncomingCallBox_chevron {
From fdf326c9f0651c9766d55bc5aeddd60d5e0372d1 Mon Sep 17 00:00:00 2001
From: David Baker
Date: Tue, 16 May 2017 17:13:39 +0100
Subject: [PATCH 015/147] Revert "Cancel quick-search on Escape, clearing it
and returning focus to composer."
This reverts commit 52a119244b2ff221c32c082166e77f9913833573.
---
src/components/structures/SearchBox.js | 4 ----
1 file changed, 4 deletions(-)
diff --git a/src/components/structures/SearchBox.js b/src/components/structures/SearchBox.js
index d0868b69..d79617c0 100644
--- a/src/components/structures/SearchBox.js
+++ b/src/components/structures/SearchBox.js
@@ -100,10 +100,6 @@ module.exports = React.createClass({
}
switch (ev.keyCode) {
- case KeyCode.ESCAPE:
- this._clearSearch();
- dis.dispatch({action: 'focus_composer'});
- break;
case KeyCode.KEY_K:
if (ctrlCmdOnly) {
if (this.refs.search) {
From 844ea390c87eab83c9f287313d32e727c958a6fb Mon Sep 17 00:00:00 2001
From: David Baker
Date: Tue, 16 May 2017 17:13:55 +0100
Subject: [PATCH 016/147] Revert "clear the searchbox after quick-search"
This reverts commit ddd12edc064bdd81fffbad941e199eaa065e3ae0.
---
src/components/structures/RoomSubList.js | 3 +--
src/components/structures/SearchBox.js | 6 +++++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/components/structures/RoomSubList.js b/src/components/structures/RoomSubList.js
index f741a30f..a1291eeb 100644
--- a/src/components/structures/RoomSubList.js
+++ b/src/components/structures/RoomSubList.js
@@ -165,11 +165,10 @@ var RoomSubList = React.createClass({
}
},
- onRoomTileClick(roomId, ev) {
+ onRoomTileClick(roomId) {
dis.dispatch({
action: 'view_room',
room_id: roomId,
- clear_search: (ev && (ev.keyCode == 13 || ev.keyCode == 32)),
});
},
diff --git a/src/components/structures/SearchBox.js b/src/components/structures/SearchBox.js
index d79617c0..a3848dcc 100644
--- a/src/components/structures/SearchBox.js
+++ b/src/components/structures/SearchBox.js
@@ -48,14 +48,18 @@ module.exports = React.createClass({
},
onAction: function(payload) {
+ // Disabling this as I find it really really annoying, and was used to the
+ // previous behaviour - see https://github.com/vector-im/riot-web/issues/3348
+/*
switch (payload.action) {
// Clear up the text field when a room is selected.
case 'view_room':
- if (payload.clear_search && this.refs.search) {
+ if (this.refs.search) {
this._clearSearch();
}
break;
}
+*/
},
onChange: function() {
From 9fc9de3af53e6457a6f83e1305c1f2247ab95421 Mon Sep 17 00:00:00 2001
From: David Baker
Date: Tue, 16 May 2017 17:21:49 +0100
Subject: [PATCH 017/147] Revert "Merge pull request #3654 from
vector-im/matthew/quick-search"
This reverts commit 8f20fcfa6b6828421d1278b169df663e80d2a743, reversing
changes made to 751f715e77a73fa704298dd1dbad0035eb7a75e8.
---
package.json | 3 +-
src/components/structures/LeftPanel.js | 94 +----------
src/components/structures/RoomSubList.js | 147 ++++++++++--------
.../structures/RoomSubListHeader.js | 120 --------------
src/components/structures/SearchBox.js | 31 ----
5 files changed, 86 insertions(+), 309 deletions(-)
delete mode 100644 src/components/structures/RoomSubListHeader.js
diff --git a/package.json b/package.json
index a1f06b00..644e9309 100644
--- a/package.json
+++ b/package.json
@@ -61,6 +61,7 @@
"favico.js": "^0.3.10",
"filesize": "3.5.6",
"flux": "~2.0.3",
+ "gemini-scrollbar": "matrix-org/gemini-scrollbar#b302279",
"gfm.css": "^1.1.1",
"highlight.js": "^9.0.0",
"linkifyjs": "^2.1.3",
@@ -73,7 +74,7 @@
"react-dnd": "^2.1.4",
"react-dnd-html5-backend": "^2.1.2",
"react-dom": "^15.4.0",
- "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#39d858c",
+ "react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef",
"sanitize-html": "^1.11.1",
"ua-parser-js": "^0.7.10",
"url": "^0.11.0"
diff --git a/src/components/structures/LeftPanel.js b/src/components/structures/LeftPanel.js
index 2d97313a..a9df37a8 100644
--- a/src/components/structures/LeftPanel.js
+++ b/src/components/structures/LeftPanel.js
@@ -19,11 +19,9 @@ limitations under the License.
var React = require('react');
var DragDropContext = require('react-dnd').DragDropContext;
var HTML5Backend = require('react-dnd-html5-backend');
-var KeyCode = require('matrix-react-sdk/lib/KeyCode');
var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher');
-
var VectorConferenceHandler = require('../../VectorConferenceHandler');
var CallHandler = require("matrix-react-sdk/lib/CallHandler");
@@ -42,10 +40,6 @@ var LeftPanel = React.createClass({
};
},
- componentWillMount: function() {
- this.focusedElement = null;
- },
-
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
},
@@ -68,91 +62,6 @@ var LeftPanel = React.createClass({
}
},
- _onFocus: function(ev) {
- this.focusedElement = ev.target;
- },
-
- _onBlur: function(ev) {
- this.focusedElement = null;
- },
-
- _onKeyDown: function(ev) {
- if (!this.focusedElement) return;
- let handled = false;
-
- switch (ev.keyCode) {
- case KeyCode.UP:
- this._onMoveFocus(true);
- handled = true;
- break;
- case KeyCode.DOWN:
- this._onMoveFocus(false);
- handled = true;
- break;
- }
-
- if (handled) {
- ev.stopPropagation();
- ev.preventDefault();
- }
- },
-
- _onMoveFocus: function(up) {
- var element = this.focusedElement;
-
- // unclear why this isn't needed
- // var descending = (up == this.focusDirection) ? this.focusDescending : !this.focusDescending;
- // this.focusDirection = up;
-
- var descending = false; // are we currently descending or ascending through the DOM tree?
- var classes;
-
- do {
- var child = up ? element.lastElementChild : element.firstElementChild;
- var sibling = up ? element.previousElementSibling : element.nextElementSibling;
-
- if (descending) {
- if (child) {
- element = child;
- }
- else if (sibling) {
- element = sibling;
- }
- else {
- descending = false;
- element = element.parentElement;
- }
- }
- else {
- if (sibling) {
- element = sibling;
- descending = true;
- }
- else {
- element = element.parentElement;
- }
- }
-
- if (element) {
- classes = element.classList;
- if (classes.contains("mx_LeftPanel")) { // we hit the top
- element = up ? element.lastElementChild : element.firstElementChild;
- descending = true;
- }
- }
-
- } while(element && !(
- classes.contains("mx_RoomTile") ||
- classes.contains("mx_SearchBox_search") ||
- classes.contains("mx_RoomSubList_ellipsis")));
-
- if (element) {
- element.focus();
- this.focusedElement = element;
- this.focusedDescending = descending;
- }
- },
-
_recheckCallElement: function(selectedRoomId) {
// if we aren't viewing a room with an ongoing call, but there is an
// active call, show the call element - we need to do this to make
@@ -211,8 +120,7 @@ var LeftPanel = React.createClass({
}
return (
-
+
{ collapseButton }
{ callPreview }
diff --git a/src/components/structures/RoomSubList.js b/src/components/structures/RoomSubList.js
index a1291eeb..6490e456 100644
--- a/src/components/structures/RoomSubList.js
+++ b/src/components/structures/RoomSubList.js
@@ -27,11 +27,9 @@ var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs');
var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils');
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
-var ConstantTimeDispatcher = require('matrix-react-sdk/lib/ConstantTimeDispatcher');
-var RoomSubListHeader = require('./RoomSubListHeader.js');
import Modal from 'matrix-react-sdk/lib/Modal';
-// turn this on for drag & drop console debugging galore
+// turn this on for drop & drag console debugging galore
var debug = false;
const TRUNCATE_AT = 10;
@@ -74,12 +72,14 @@ var RoomSubList = React.createClass({
order: React.PropTypes.string.isRequired,
+ // undefined if no room is selected (eg we are showing settings)
+ selectedRoom: React.PropTypes.string,
+
startAsHidden: React.PropTypes.bool,
showSpinner: React.PropTypes.bool, // true to show a spinner if 0 elements when expanded
collapsed: React.PropTypes.bool.isRequired, // is LeftPanel collapsed?
onHeaderClick: React.PropTypes.func,
alwaysShowHeader: React.PropTypes.bool,
- selectedRoom: React.PropTypes.string,
incomingCall: React.PropTypes.object,
onShowMoreRooms: React.PropTypes.func,
searchFilter: React.PropTypes.string,
@@ -101,31 +101,13 @@ var RoomSubList = React.createClass({
},
componentWillMount: function() {
- constantTimeDispatcher.register("RoomSubList.sort", this.props.tagName, this.onSort);
- constantTimeDispatcher.register("RoomSubList.refreshHeader", this.props.tagName, this.onRefresh);
this.sortList(this.applySearchFilter(this.props.list, this.props.searchFilter), this.props.order);
- this._fixUndefinedOrder(this.props.list);
- },
-
- componentWillUnmount: function() {
- constantTimeDispatcher.unregister("RoomSubList.sort", this.props.tagName, this.onSort);
- constantTimeDispatcher.unregister("RoomSubList.refreshHeader", this.props.tagName, this.onRefresh);
},
componentWillReceiveProps: function(newProps) {
// order the room list appropriately before we re-render
//if (debug) console.log("received new props, list = " + newProps.list);
this.sortList(this.applySearchFilter(newProps.list, newProps.searchFilter), newProps.order);
- this._fixUndefinedOrder(newProps.list);
- },
-
- onSort: function() {
- this.sortList(this.applySearchFilter(this.props.list, this.props.searchFilter), this.props.order);
- // we deliberately don't waste time trying to fix undefined ordering here
- },
-
- onRefresh: function() {
- this.forceUpdate();
},
applySearchFilter: function(list, filter) {
@@ -138,7 +120,7 @@ var RoomSubList = React.createClass({
// The header is collapsable if it is hidden or not stuck
// The dataset elements are added in the RoomList _initAndPositionStickyHeaders method
isCollapsableOnClick: function() {
- var stuck = this.refs.header.refs.header.dataset.stuck;
+ var stuck = this.refs.header.dataset.stuck;
if (this.state.hidden || stuck === undefined || stuck === "none") {
return true;
} else {
@@ -161,7 +143,7 @@ var RoomSubList = React.createClass({
this.props.onHeaderClick(isHidden);
} else {
// The header is stuck, so the click is to be interpreted as a scroll to the header
- this.props.onHeaderClick(this.state.hidden, this.refs.header.refs.header.dataset.originalPosition);
+ this.props.onHeaderClick(this.state.hidden, this.refs.header.dataset.originalPosition);
}
},
@@ -230,6 +212,9 @@ var RoomSubList = React.createClass({
if (order === "manual") comparator = this.manualComparator;
if (order === "recent") comparator = this.recentsComparator;
+ // Fix undefined orders here, and make sure the backend gets updated as well
+ this._fixUndefinedOrder(list);
+
//if (debug) console.log("sorting list for sublist " + this.props.label + " with length " + list.length + ", this.props.list = " + this.props.list);
this.setState({ sortedList: list.sort(comparator) });
},
@@ -264,9 +249,10 @@ var RoomSubList = React.createClass({
if (badges) {
result[0] += notificationCount;
+ if (highlight) {
+ result[1] = true;
+ }
}
-
- result[1] |= highlight;
}
return result;
}, [0, false]);
@@ -374,6 +360,7 @@ var RoomSubList = React.createClass({
var self = this;
var DNDRoomTile = sdk.getComponent("rooms.DNDRoomTile");
return this.state.sortedList.map(function(room) {
+ var selected = room.roomId == self.props.selectedRoom;
// XXX: is it evil to pass in self as a prop to RoomTile?
return (
0 || self.props.label === 'Invites' }
isInvite={ self.props.label === 'Invites' }
refreshSubList={ self._updateSubListCount }
incomingCall={ null }
@@ -391,6 +380,70 @@ var RoomSubList = React.createClass({
});
},
+ _getHeaderJsx: function() {
+ var TintableSvg = sdk.getComponent("elements.TintableSvg");
+
+ var subListNotifications = this.roomNotificationCount();
+ var subListNotifCount = subListNotifications[0];
+ var subListNotifHighlight = subListNotifications[1];
+
+ var roomCount = this.props.list.length > 0 ? this.props.list.length : '';
+
+ var chevronClasses = classNames({
+ 'mx_RoomSubList_chevron': true,
+ 'mx_RoomSubList_chevronRight': this.state.hidden,
+ 'mx_RoomSubList_chevronDown': !this.state.hidden,
+ });
+
+ var badgeClasses = classNames({
+ 'mx_RoomSubList_badge': true,
+ 'mx_RoomSubList_badgeHighlight': subListNotifHighlight,
+ });
+
+ var badge;
+ if (subListNotifCount > 0) {
+ badge = { FormattingUtils.formatCount(subListNotifCount) }
;
+ }
+
+ // When collapsed, allow a long hover on the header to show user
+ // the full tag name and room count
+ var title;
+ if (this.props.collapsed) {
+ title = this.props.label;
+ if (roomCount !== '') {
+ title += " [" + roomCount + "]";
+ }
+ }
+
+ var incomingCall;
+ if (this.props.incomingCall) {
+ var self = this;
+ // Check if the incoming call is for this section
+ var incomingCallRoom = this.props.list.filter(function(room) {
+ return self.props.incomingCall.roomId === room.roomId;
+ });
+
+ if (incomingCallRoom.length === 1) {
+ var IncomingCallBox = sdk.getComponent("voip.IncomingCallBox");
+ incomingCall = ;
+ }
+ }
+
+ var tabindex = this.props.searchFilter === "" ? "0" : "-1";
+
+ return (
+
+
+ { this.props.collapsed ? '' : this.props.label }
+ { roomCount }
+
+ { badge }
+ { incomingCall }
+
+
+ );
+ },
+
_createOverflowTile: function(overflowCount, totalCount) {
var content =
;
@@ -446,7 +499,7 @@ var RoomSubList = React.createClass({
// gets triggered and another list is passed in. Doing it one at a time means that
// we always correctly calculate the highest order for the list - stops multiple
// rooms getting the same order. This is only really relevant for the first time this
- // is run with historical room tag data, after that there should only be one undefined
+ // is run with historical room tag data, after that there should only be undefined
// in the list at a time anyway.
for (let i = 0; i < list.length; i++) {
if (list[i].tags[self.props.tagName] && list[i].tags[self.props.tagName].order === undefined) {
@@ -480,16 +533,6 @@ var RoomSubList = React.createClass({
target = ;
}
- var roomCount = this.props.list.length > 0 ? this.props.list.length : '';
-
- var isIncomingCallRoom;
- if (this.props.incomingCall) {
- // Check if the incoming call is for this section
- isIncomingCallRoom = this.props.list.find(room=>{
- return this.props.incomingCall.roomId === room.roomId;
- }) ? true : false;
- }
-
if (this.state.sortedList.length > 0 || this.props.editable) {
var subList;
var classes = "mx_RoomSubList";
@@ -508,18 +551,7 @@ var RoomSubList = React.createClass({
return connectDropTarget(
-
+ { this._getHeaderJsx() }
{ subList }
);
@@ -528,20 +560,7 @@ var RoomSubList = React.createClass({
var Loader = sdk.getComponent("elements.Spinner");
return (
- { this.props.alwaysShowHeader ?
-
- : undefined }
+ { this.props.alwaysShowHeader ? this._getHeaderJsx() : undefined }
{ (this.props.showSpinner && !this.state.hidden) ? : undefined }
);
diff --git a/src/components/structures/RoomSubListHeader.js b/src/components/structures/RoomSubListHeader.js
deleted file mode 100644
index 5618b39b..00000000
--- a/src/components/structures/RoomSubListHeader.js
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
-Copyright 2017 Vector Creations 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.
-*/
-
-'use strict';
-
-var React = require('react');
-var ReactDOM = require('react-dom');
-var classNames = require('classnames');
-var sdk = require('matrix-react-sdk')
-var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils');
-var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs');
-var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
-var ConstantTimeDispatcher = require('matrix-react-sdk/lib/ConstantTimeDispatcher');
-
-module.exports = React.createClass({
- displayName: 'RoomSubListHeader',
-
- propTypes: {
- label: React.PropTypes.string.isRequired,
- tagName: React.PropTypes.string,
- roomCount: React.PropTypes.oneOfType([
- React.PropTypes.string,
- React.PropTypes.number
- ]),
- collapsed: React.PropTypes.bool.isRequired, // is LeftPanel collapsed?
- isIncomingCallRoom: React.PropTypes.bool,
- roomNotificationCount: React.PropTypes.array,
- hidden: React.PropTypes.bool,
- onClick: React.PropTypes.func,
- onHeaderClick: React.PropTypes.func,
- },
-
- getDefaultProps: function() {
- return {
- onHeaderClick: function() {}, // NOP
- };
- },
-
- componentWillMount: function() {
- // constantTimeDispatcher.register("RoomSubList.refreshHeader", this.props.tagName, this.onRefresh);
- },
-
- componentWillUnmount: function() {
- // constantTimeDispatcher.unregister("RoomSubList.refreshHeader", this.props.tagName, this.onRefresh);
- },
-
- // onRefresh: function() {
- // this.forceUpdate();
- // },
-
- render: function() {
- var TintableSvg = sdk.getComponent("elements.TintableSvg");
-
- var subListNotifications = this.props.roomNotificationCount;
- var subListNotifCount = subListNotifications[0];
- var subListNotifHighlight = subListNotifications[1];
-
- var chevronClasses = classNames({
- 'mx_RoomSubList_chevron': true,
- 'mx_RoomSubList_chevronRight': this.props.hidden,
- 'mx_RoomSubList_chevronDown': !this.props.hidden,
- });
-
- var badgeClasses = classNames({
- 'mx_RoomSubList_badge': true,
- 'mx_RoomSubList_badgeHighlight': subListNotifHighlight,
- });
-
- var badge;
- if (subListNotifCount > 0) {
- badge = { FormattingUtils.formatCount(subListNotifCount) }
;
- }
- else if (subListNotifHighlight) {
- badge = !
;
- }
-
- // When collapsed, allow a long hover on the header to show user
- // the full tag name and room count
- var title;
- var roomCount = this.props.roomCount;
- if (this.props.collapsed) {
- title = this.props.label;
- if (roomCount !== '') {
- title += " [" + roomCount + "]";
- }
- }
-
- var incomingCall;
- if (this.props.isIncomingCallRoom) {
- var IncomingCallBox = sdk.getComponent("voip.IncomingCallBox");
- incomingCall = ;
- }
-
- return (
-
-
- { this.props.collapsed ? '' : this.props.label }
- { roomCount }
-
- { badge }
- { incomingCall }
-
-
- );
- },
-});
-
diff --git a/src/components/structures/SearchBox.js b/src/components/structures/SearchBox.js
index a3848dcc..729e7ef7 100644
--- a/src/components/structures/SearchBox.js
+++ b/src/components/structures/SearchBox.js
@@ -21,7 +21,6 @@ var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher');
var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc');
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
-var KeyCode = require('matrix-react-sdk/lib/KeyCode');
module.exports = React.createClass({
displayName: 'SearchBox',
@@ -39,12 +38,10 @@ module.exports = React.createClass({
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
- document.addEventListener('keydown', this._onKeyDown);
},
componentWillUnmount: function() {
dis.unregister(this.dispatcherRef);
- document.removeEventListener('keydown', this._onKeyDown);
},
onAction: function(payload) {
@@ -93,34 +90,6 @@ module.exports = React.createClass({
this.onChange();
},
- _onKeyDown: function(ev) {
- let handled = false;
- const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
- let ctrlCmdOnly;
- if (isMac) {
- ctrlCmdOnly = ev.metaKey && !ev.altKey && !ev.ctrlKey && !ev.shiftKey;
- } else {
- ctrlCmdOnly = ev.ctrlKey && !ev.altKey && !ev.metaKey && !ev.shiftKey;
- }
-
- switch (ev.keyCode) {
- case KeyCode.KEY_K:
- if (ctrlCmdOnly) {
- if (this.refs.search) {
- this.refs.search.focus();
- this.refs.search.select();
- }
- handled = true;
- }
- break;
- }
-
- if (handled) {
- ev.stopPropagation();
- ev.preventDefault();
- }
- },
-
render: function() {
var TintableSvg = sdk.getComponent('elements.TintableSvg');
From 39b6c7c65d08942e197cf5f7c5f110d8f641b774 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 17 May 2017 09:53:33 +0100
Subject: [PATCH 018/147] ignore electron_app subdirs properly, missed these
too :L
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
.gitignore | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.gitignore b/.gitignore
index 6072f0ff..7f753927 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,12 +6,11 @@
/lib
/node_modules
/electron_app/node_modules
+/electron_app/dist
/packages/
/webapp
/.npmrc
.DS_Store
npm-debug.log
-electron/dist
-electron/pub
/config.json
/src/component-index.js
From 826a571b602783c33e9177d9026147c27c675e91 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 17 May 2017 10:05:50 +0100
Subject: [PATCH 019/147] apply same image to the window/taskbar too; as per
request LETS MAKE IT CLEAR WE ARE NEEDY AND WANT ATTENTION
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
electron_app/src/tray.js | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/electron_app/src/tray.js b/electron_app/src/tray.js
index 7198356c..98ffb9f4 100644
--- a/electron_app/src/tray.js
+++ b/electron_app/src/tray.js
@@ -61,7 +61,14 @@ exports.create = function(win, config) {
trayIcon.on('click', toggleWin);
win.webContents.on('page-favicon-updated', function(ev, favicons) {
- trayIcon.setImage(nativeImage.createFromDataURL(favicons[0]));
+ if (favicons && favicons.length > 0 && favicons[0].startsWith('data:')) {
+ const image = nativeImage.createFromDataURL(favicons[0]);
+ trayIcon.setImage(image);
+ win.setIcon(image);
+ } else {
+ trayIcon.setImage(config.icon_path);
+ win.setIcon(config.icon_path);
+ }
});
win.webContents.on('page-title-updated', function(ev, title) {
From 9352e5d78ea1b003ec74939d4299106f2fa4103b Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 17 May 2017 10:39:43 +0100
Subject: [PATCH 020/147] Lets make it abundantly clear that we want attention.
FLASH FLASH FLASH also improve favicon updating to not change if we're same
as previous not sure how intensive the nativeImage stuff is but cheap
efficiency
For FLASH FLASH I moved the setBadgeCount stuff RPC -> IPC
should be more reliable now, its in electron-main
Win only:
if mainWindow is set and is not in focus make it FLASH
clear flash if notification gets cleared elsewhere
debounce focus handler so we don't set a million of them
if the app is backgrounded a while
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
electron_app/src/electron-main.js | 21 ++++++++++++++++++++-
electron_app/src/tray.js | 21 +++++++++++++++------
src/vector/platform/ElectronPlatform.js | 14 +++-----------
3 files changed, 38 insertions(+), 18 deletions(-)
diff --git a/electron_app/src/electron-main.js b/electron_app/src/electron-main.js
index 32e305d8..b632708f 100644
--- a/electron_app/src/electron-main.js
+++ b/electron_app/src/electron-main.js
@@ -155,12 +155,31 @@ function startAutoUpdate(update_base_url) {
// no other way to catch this error).
// Assuming we generally run from the console when developing,
// this is far preferable.
-process.on('uncaughtException', function (error) {
+process.on('uncaughtException', function(error) {
console.log("Unhandled exception", error);
});
electron.ipcMain.on('install_update', installUpdate);
+let focusHandlerAttached = false;
+electron.ipcMain.on('setBadgeCount', function(ev, count) {
+ electron.app.setBadgeCount(count);
+ if (process.platform === 'win32' && mainWindow && !mainWindow.isFocused()) {
+ if (count > 0) {
+ if (!focusHandlerAttached) {
+ mainWindow.once('focus', () => {
+ mainWindow.flashFrame(false);
+ focusHandlerAttached = false;
+ });
+ focusHandlerAttached = true;
+ }
+ mainWindow.flashFrame(true);
+ } else {
+ mainWindow.flashFrame(false);
+ }
+ }
+});
+
electron.app.commandLine.appendSwitch('--enable-usermedia-screen-capturing');
const shouldQuit = electron.app.makeSingleInstance((commandLine, workingDirectory) => {
diff --git a/electron_app/src/tray.js b/electron_app/src/tray.js
index 98ffb9f4..5409194d 100644
--- a/electron_app/src/tray.js
+++ b/electron_app/src/tray.js
@@ -60,15 +60,24 @@ exports.create = function(win, config) {
trayIcon.setContextMenu(contextMenu);
trayIcon.on('click', toggleWin);
+ let lastFavicon = null;
win.webContents.on('page-favicon-updated', function(ev, favicons) {
+ let newFavicon = config.icon_path;
if (favicons && favicons.length > 0 && favicons[0].startsWith('data:')) {
- const image = nativeImage.createFromDataURL(favicons[0]);
- trayIcon.setImage(image);
- win.setIcon(image);
- } else {
- trayIcon.setImage(config.icon_path);
- win.setIcon(config.icon_path);
+ newFavicon = favicons[0];
}
+
+ // No need to change, shortcut
+ if (newFavicon === lastFavicon) return;
+ lastFavicon = newFavicon;
+
+ // if its not default we have to construct into nativeImage
+ if (newFavicon !== config.icon_path) {
+ newFavicon = nativeImage.createFromDataURL(favicons[0]);
+ }
+
+ trayIcon.setImage(newFavicon);
+ win.setIcon(newFavicon);
});
win.webContents.on('page-title-updated', function(ev, title) {
diff --git a/src/vector/platform/ElectronPlatform.js b/src/vector/platform/ElectronPlatform.js
index 82ef0b51..5710e66e 100644
--- a/src/vector/platform/ElectronPlatform.js
+++ b/src/vector/platform/ElectronPlatform.js
@@ -20,7 +20,7 @@ limitations under the License.
import VectorBasePlatform from './VectorBasePlatform';
import dis from 'matrix-react-sdk/lib/dispatcher';
import q from 'q';
-import electron, {remote} from 'electron';
+import electron, {remote, ipcRenderer} from 'electron';
remote.autoUpdater.on('update-downloaded', onUpdateDownloaded);
@@ -58,16 +58,8 @@ export default class ElectronPlatform extends VectorBasePlatform {
setNotificationCount(count: number) {
if (this.notificationCount === count) return;
super.setNotificationCount(count);
- // this sometimes throws because electron is made of fail:
- // https://github.com/electron/electron/issues/7351
- // For now, let's catch the error, but I suspect it may
- // continue to fail and we might just have to accept that
- // electron's remote RPC is a non-starter for now and use IPC
- try {
- remote.app.setBadgeCount(count);
- } catch (e) {
- console.error('Failed to set notification count', e);
- }
+
+ ipcRenderer.send('setBadgeCount', count);
}
supportsNotifications(): boolean {
From 089740a840ae0fbca5a8055c29c49eb7f1bb8a1b Mon Sep 17 00:00:00 2001
From: Luke Barnard
Date: Wed, 17 May 2017 14:25:43 +0100
Subject: [PATCH 021/147] CSS for putting country dd on same line as phone
input
(For login and registration)
---
.../matrix-react-sdk/structures/login/_Login.scss | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/skins/vector/css/matrix-react-sdk/structures/login/_Login.scss b/src/skins/vector/css/matrix-react-sdk/structures/login/_Login.scss
index 35370464..2501b1b1 100644
--- a/src/skins/vector/css/matrix-react-sdk/structures/login/_Login.scss
+++ b/src/skins/vector/css/matrix-react-sdk/structures/login/_Login.scss
@@ -231,8 +231,22 @@ limitations under the License.
border-bottom-right-radius: 0px;
}
+.mx_Login_phoneSection {
+ display:flex;
+}
+
.mx_Login_phoneCountry {
margin-bottom: 14px;
+ width: 145px;
+
+ /* To override mx_Login_field_prefix */
+ text-align: left;
+ padding: 0px;
+}
+
+.mx_Login_field_prefix .mx_Dropdown_input {
+ /* To use prefix border instead of dropdown border */
+ border: 0;
}
.mx_Login_phoneCountry .mx_Dropdown_option {
From 15ab1732a2e417eaf398f0a6ea69e314d1f19ea5 Mon Sep 17 00:00:00 2001
From: Richard van der Hoff
Date: Wed, 17 May 2017 14:43:21 +0100
Subject: [PATCH 022/147] Reduce rageshake log size to 1MB
... 50MB turned out to be quite a lot.
---
src/vector/rageshake.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/vector/rageshake.js b/src/vector/rageshake.js
index 0b977949..0138d624 100644
--- a/src/vector/rageshake.js
+++ b/src/vector/rageshake.js
@@ -37,8 +37,12 @@ import q from "q";
// actually timestamps. We then purge the remaining logs. We also do this
// purge on startup to prevent logs from accumulating.
+// the frequency with which we flush to indexeddb
const FLUSH_RATE_MS = 30 * 1000;
+// the length of log data we keep in indexeddb (and include in the reports)
+const MAX_LOG_SIZE = 1024 * 1024 * 1; // 1 MB
+
// A class which monkey-patches the global console and stores log lines.
class ConsoleLogger {
constructor() {
@@ -232,7 +236,6 @@ class IndexedDBLogStore {
* is a big string with all the new-line delimited logs.
*/
async consume() {
- const MAX_LOG_SIZE = 1024 * 1024 * 50; // 50 MB
const db = this.db;
// Returns: a string representing the concatenated logs for this ID.
From fac8906102be707b1a0b3bdec8f5e6788e5fe4d3 Mon Sep 17 00:00:00 2001
From: David Baker
Date: Wed, 17 May 2017 16:11:34 +0100
Subject: [PATCH 023/147] Add script to fetch correct dep branches
Fetch branches of js-sdk and react-sdk that match the current
branch name, if they exist. This will mostly be used in the
automated tests.
---
scripts/fetch-develop.deps.sh | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100755 scripts/fetch-develop.deps.sh
diff --git a/scripts/fetch-develop.deps.sh b/scripts/fetch-develop.deps.sh
new file mode 100755
index 00000000..c5756a86
--- /dev/null
+++ b/scripts/fetch-develop.deps.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# Fetches the js-sdk and matrix-react-sdk dependencies for development
+# or testing purposes
+# If there exists a branch of that dependency with the same name as
+# the branch the current checkout is on, use that branch. Otherwise,
+# use develop.
+
+curbranch=`git rev-parse --abbrev-ref HEAD`
+
+cd node_modules
+
+function dodep() {
+ org=$1
+ repo=$2
+ rm -rf $repo || true
+ git clone https://github.com/$org/$repo.git $repo
+ pushd $repo
+ git checkout $curbranch || git checkout develop
+ echo "$repo set to branch "`git rev-parse --abbrev-ref HEAD`
+ popd
+}
+
+dodep matrix-org matrix-js-sdk
+dodep matrix-org matrix-react-sdk
From 94ac4bf490a02f026c5f47d6e8174360c215ade4 Mon Sep 17 00:00:00 2001
From: David Baker
Date: Wed, 17 May 2017 16:17:08 +0100
Subject: [PATCH 024/147] Use fetch dep script in jenkins script
---
scripts/fetch-develop.deps.sh | 1 +
scripts/jenkins.sh | 10 ++++------
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/scripts/fetch-develop.deps.sh b/scripts/fetch-develop.deps.sh
index c5756a86..4053666f 100755
--- a/scripts/fetch-develop.deps.sh
+++ b/scripts/fetch-develop.deps.sh
@@ -17,6 +17,7 @@ function dodep() {
git clone https://github.com/$org/$repo.git $repo
pushd $repo
git checkout $curbranch || git checkout develop
+ npm install
echo "$repo set to branch "`git rev-parse --abbrev-ref HEAD`
popd
}
diff --git a/scripts/jenkins.sh b/scripts/jenkins.sh
index 312eea45..17f86fe1 100755
--- a/scripts/jenkins.sh
+++ b/scripts/jenkins.sh
@@ -8,10 +8,13 @@ nvm use 6
set -x
+# check out corresponding branches of dependencies
+`dirname $0`/fetch-develop.deps.sh
+
npm install
# apparently npm 3.10.3 on node 6.4.0 doesn't upgrade #develop target with npm install unless explicitly asked.
-npm install matrix-react-sdk matrix-js-sdk olm
+npm install olm
# install olm. A naive 'npm i ./olm/olm-*.tgz' fails because it uses the url
# from our package.json (or even matrix-js-sdk's) in preference.
@@ -23,11 +26,6 @@ npm install matrix-react-sdk matrix-js-sdk olm
#rm -r node_modules/olm
#cp -r olm/package node_modules/olm
-
-# we may be using dev branches of js-sdk and react-sdk, in which case we need to build them
-(cd node_modules/matrix-js-sdk && npm install)
-(cd node_modules/matrix-react-sdk && npm install)
-
# run the mocha tests
npm run test
From 60d33f50a7e30de6f16e610025f40586acbed8be Mon Sep 17 00:00:00 2001
From: David Baker
Date: Wed, 17 May 2017 16:19:19 +0100
Subject: [PATCH 025/147] Create node_modules if it doesn't exist
---
scripts/fetch-develop.deps.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/scripts/fetch-develop.deps.sh b/scripts/fetch-develop.deps.sh
index 4053666f..1a3c0996 100755
--- a/scripts/fetch-develop.deps.sh
+++ b/scripts/fetch-develop.deps.sh
@@ -8,6 +8,7 @@
curbranch=`git rev-parse --abbrev-ref HEAD`
+mkdir -p node_modules
cd node_modules
function dodep() {
From 18afbc5becae4c65906d98e2b48ff511524b34aa Mon Sep 17 00:00:00 2001
From: David Baker
Date: Wed, 17 May 2017 18:14:28 +0100
Subject: [PATCH 026/147] Make dep install script work
---
scripts/fetch-develop.deps.sh | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/scripts/fetch-develop.deps.sh b/scripts/fetch-develop.deps.sh
index 1a3c0996..a8abcef1 100755
--- a/scripts/fetch-develop.deps.sh
+++ b/scripts/fetch-develop.deps.sh
@@ -8,9 +8,6 @@
curbranch=`git rev-parse --abbrev-ref HEAD`
-mkdir -p node_modules
-cd node_modules
-
function dodep() {
org=$1
repo=$2
@@ -18,10 +15,32 @@ function dodep() {
git clone https://github.com/$org/$repo.git $repo
pushd $repo
git checkout $curbranch || git checkout develop
- npm install
echo "$repo set to branch "`git rev-parse --abbrev-ref HEAD`
popd
}
dodep matrix-org matrix-js-sdk
dodep matrix-org matrix-react-sdk
+
+mkdir -p node_modules
+cd node_modules
+
+ln -s ../matrix-js-sdk ./
+pushd matrix-js-sdk
+npm install
+popd
+
+ln -s ../matrix-react-sdk ./
+pushd matrix-react-sdk
+mkdir -p node_modules
+cd node_modules
+ln -s ../../matrix-js-sdk matrix-js-sdk
+cd ..
+npm install
+popd
+# Link the reskindex binary in place: if we used npm link,
+# npm would do this for us, but we don't because we'd have
+# to define the npm prefix somewhere so it could put the
+# intermediate symlinks there. Instead, we do it ourselves.
+mkdir -p .bin
+ln -s ../matrix-react-sdk/scripts/reskindex.js .bin/reskindex
From b3b44dd99e31ebccf3f4f4472f256eb73235bdb5 Mon Sep 17 00:00:00 2001
From: David Baker
Date: Wed, 17 May 2017 18:20:25 +0100
Subject: [PATCH 027/147] Use fetch dep script for travis
---
.travis.yml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 9720d887..ff58bf37 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,6 +2,5 @@ language: node_js
node_js:
- 6 # node v6, to match jenkins
install:
+ - scripts/fetch-develop.deps.sh
- npm install
- - (cd node_modules/matrix-js-sdk && npm install)
- - (cd node_modules/matrix-react-sdk && npm install)
From c929cb1337f565e44da48da298f4b07c77c3703b Mon Sep 17 00:00:00 2001
From: David Baker
Date: Wed, 17 May 2017 18:21:58 +0100
Subject: [PATCH 028/147] Do I mean bash? Probably
---
scripts/fetch-develop.deps.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/fetch-develop.deps.sh b/scripts/fetch-develop.deps.sh
index a8abcef1..50c3af1a 100755
--- a/scripts/fetch-develop.deps.sh
+++ b/scripts/fetch-develop.deps.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
# Fetches the js-sdk and matrix-react-sdk dependencies for development
# or testing purposes
From a9a4b1c44e6a9cebceeb5a039c45a01f2f8c0d9e Mon Sep 17 00:00:00 2001
From: David Baker
Date: Thu, 18 May 2017 11:05:19 +0100
Subject: [PATCH 029/147] Get branch from various CI env vars
So we hopefully get the right branch for PRs from the same repo
(but not forks).
From @t3chguy's comment (tweaked a bit)
---
scripts/fetch-develop.deps.sh | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/scripts/fetch-develop.deps.sh b/scripts/fetch-develop.deps.sh
index 50c3af1a..8048d4bc 100755
--- a/scripts/fetch-develop.deps.sh
+++ b/scripts/fetch-develop.deps.sh
@@ -6,7 +6,22 @@
# the branch the current checkout is on, use that branch. Otherwise,
# use develop.
-curbranch=`git rev-parse --abbrev-ref HEAD`
+# Look in the many different CI env vars for which branch we're
+# building
+if [[ "$TRAVIS" == true ]]; then
+ curbranch="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}"
+else
+ # ghprbSourceBranch for jenkins github pull request builder
+ # GIT_BRANCH for other jenkins builds
+ curbranch="${ghprbSourceBranch:-$GIT_BRANCH}"
+ # Otherwise look at the actual branch we're on
+ if [ -z "$curbranch" ]
+ then
+ curbranch=`git rev-parse --abbrev-ref HEAD`
+ fi
+fi
+
+echo "Determined branch to be $curbranch"
function dodep() {
org=$1
From e879fb0eef08f68c2b4a4ac706da7e19737e5abb Mon Sep 17 00:00:00 2001
From: Luke Barnard
Date: Thu, 18 May 2017 11:25:42 +0100
Subject: [PATCH 030/147] Add square flag pngs /w genflags.sh script
This uses the github.com:googlei18n/region-flags and imagemagick to generate 27x27 flag pngs. The flags have a 1px #e0e0e0 border and transparent padding such that each flag is of the same height (17px including the border).
---
res/flags/AD.png | Bin 0 -> 1143 bytes
res/flags/AE.png | Bin 0 -> 841 bytes
res/flags/AF.png | Bin 0 -> 1144 bytes
res/flags/AG.png | Bin 0 -> 1394 bytes
res/flags/AI.png | Bin 0 -> 1515 bytes
res/flags/AL.png | Bin 0 -> 1262 bytes
res/flags/AM.png | Bin 0 -> 744 bytes
res/flags/AO.png | Bin 0 -> 1070 bytes
res/flags/AQ.png | Bin 0 -> 1405 bytes
res/flags/AR.png | Bin 0 -> 955 bytes
res/flags/AS.png | Bin 0 -> 1651 bytes
res/flags/AT.png | Bin 0 -> 701 bytes
res/flags/AU.png | Bin 0 -> 1719 bytes
res/flags/AW.png | Bin 0 -> 938 bytes
res/flags/AX.png | Bin 0 -> 900 bytes
res/flags/AZ.png | Bin 0 -> 978 bytes
res/flags/BA.png | Bin 0 -> 1271 bytes
res/flags/BB.png | Bin 0 -> 1065 bytes
res/flags/BD.png | Bin 0 -> 1301 bytes
res/flags/BE.png | Bin 0 -> 689 bytes
res/flags/BF.png | Bin 0 -> 954 bytes
res/flags/BG.png | Bin 0 -> 737 bytes
res/flags/BH.png | Bin 0 -> 842 bytes
res/flags/BI.png | Bin 0 -> 1534 bytes
res/flags/BJ.png | Bin 0 -> 777 bytes
res/flags/BL.png | Bin 0 -> 692 bytes
res/flags/BM.png | Bin 0 -> 1601 bytes
res/flags/BN.png | Bin 0 -> 1599 bytes
res/flags/BO.png | Bin 0 -> 733 bytes
res/flags/BQ.png | Bin 0 -> 726 bytes
res/flags/BR.png | Bin 0 -> 1612 bytes
res/flags/BS.png | Bin 0 -> 1110 bytes
res/flags/BT.png | Bin 0 -> 1608 bytes
res/flags/BV.png | Bin 0 -> 866 bytes
res/flags/BW.png | Bin 0 -> 697 bytes
res/flags/BY.png | Bin 0 -> 950 bytes
res/flags/BZ.png | Bin 0 -> 1592 bytes
res/flags/CA.png | Bin 0 -> 1085 bytes
res/flags/CC.png | Bin 0 -> 1637 bytes
res/flags/CD.png | Bin 0 -> 1581 bytes
res/flags/CF.png | Bin 0 -> 1124 bytes
res/flags/CG.png | Bin 0 -> 1539 bytes
res/flags/CH.png | Bin 0 -> 800 bytes
res/flags/CI.png | Bin 0 -> 692 bytes
res/flags/CK.png | Bin 0 -> 1437 bytes
res/flags/CL.png | Bin 0 -> 964 bytes
res/flags/CM.png | Bin 0 -> 908 bytes
res/flags/CN.png | Bin 0 -> 1069 bytes
res/flags/CO.png | Bin 0 -> 726 bytes
res/flags/CR.png | Bin 0 -> 734 bytes
res/flags/CU.png | Bin 0 -> 1204 bytes
res/flags/CV.png | Bin 0 -> 1271 bytes
res/flags/CW.png | Bin 0 -> 970 bytes
res/flags/CX.png | Bin 0 -> 1369 bytes
res/flags/CY.png | Bin 0 -> 1208 bytes
res/flags/CZ.png | Bin 0 -> 1172 bytes
res/flags/DE.png | Bin 0 -> 734 bytes
res/flags/DJ.png | Bin 0 -> 1253 bytes
res/flags/DK.png | Bin 0 -> 797 bytes
res/flags/DM.png | Bin 0 -> 1169 bytes
res/flags/DO.png | Bin 0 -> 946 bytes
res/flags/DZ.png | Bin 0 -> 1095 bytes
res/flags/EC.png | Bin 0 -> 1162 bytes
res/flags/EE.png | Bin 0 -> 723 bytes
res/flags/EG.png | Bin 0 -> 914 bytes
res/flags/EH.png | Bin 0 -> 1203 bytes
res/flags/ER.png | Bin 0 -> 1715 bytes
res/flags/ES.png | Bin 0 -> 1064 bytes
res/flags/ET.png | Bin 0 -> 1321 bytes
res/flags/FI.png | Bin 0 -> 841 bytes
res/flags/FJ.png | Bin 0 -> 1523 bytes
res/flags/FK.png | Bin 0 -> 1634 bytes
res/flags/FM.png | Bin 0 -> 1195 bytes
res/flags/FO.png | Bin 0 -> 834 bytes
res/flags/FR.png | Bin 0 -> 692 bytes
res/flags/GA.png | Bin 0 -> 753 bytes
res/flags/GB.png | Bin 0 -> 1574 bytes
res/flags/GD.png | Bin 0 -> 1393 bytes
res/flags/GE.png | Bin 0 -> 1120 bytes
res/flags/GF.png | Bin 0 -> 1295 bytes
res/flags/GG.png | Bin 0 -> 1001 bytes
res/flags/GH.png | Bin 0 -> 1010 bytes
res/flags/GI.png | Bin 0 -> 1129 bytes
res/flags/GL.png | Bin 0 -> 1216 bytes
res/flags/GM.png | Bin 0 -> 743 bytes
res/flags/GN.png | Bin 0 -> 699 bytes
res/flags/GP.png | Bin 0 -> 1361 bytes
res/flags/GQ.png | Bin 0 -> 1289 bytes
res/flags/GR.png | Bin 0 -> 1157 bytes
res/flags/GS.png | Bin 0 -> 1640 bytes
res/flags/GT.png | Bin 0 -> 949 bytes
res/flags/GU.png | Bin 0 -> 1120 bytes
res/flags/GW.png | Bin 0 -> 972 bytes
res/flags/GY.png | Bin 0 -> 1332 bytes
res/flags/HK.png | Bin 0 -> 1216 bytes
res/flags/HM.png | Bin 0 -> 1719 bytes
res/flags/HN.png | Bin 0 -> 971 bytes
res/flags/HR.png | Bin 0 -> 1096 bytes
res/flags/HT.png | Bin 0 -> 951 bytes
res/flags/HU.png | Bin 0 -> 728 bytes
res/flags/ID.png | Bin 0 -> 685 bytes
res/flags/IE.png | Bin 0 -> 694 bytes
res/flags/IL.png | Bin 0 -> 1006 bytes
res/flags/IM.png | Bin 0 -> 1117 bytes
res/flags/IN.png | Bin 0 -> 914 bytes
res/flags/IO.png | Bin 0 -> 1806 bytes
res/flags/IQ.png | Bin 0 -> 1055 bytes
res/flags/IR.png | Bin 0 -> 1356 bytes
res/flags/IS.png | Bin 0 -> 851 bytes
res/flags/IT.png | Bin 0 -> 694 bytes
res/flags/JE.png | Bin 0 -> 1531 bytes
res/flags/JM.png | Bin 0 -> 1694 bytes
res/flags/JO.png | Bin 0 -> 1240 bytes
res/flags/JP.png | Bin 0 -> 1109 bytes
res/flags/KE.png | Bin 0 -> 1196 bytes
res/flags/KG.png | Bin 0 -> 1282 bytes
res/flags/KH.png | Bin 0 -> 1209 bytes
res/flags/KI.png | Bin 0 -> 1385 bytes
res/flags/KM.png | Bin 0 -> 1399 bytes
res/flags/KN.png | Bin 0 -> 1569 bytes
res/flags/KP.png | Bin 0 -> 1038 bytes
res/flags/KR.png | Bin 0 -> 1456 bytes
res/flags/KW.png | Bin 0 -> 985 bytes
res/flags/KY.png | Bin 0 -> 1604 bytes
res/flags/KZ.png | Bin 0 -> 1346 bytes
res/flags/LA.png | Bin 0 -> 1046 bytes
res/flags/LB.png | Bin 0 -> 1091 bytes
res/flags/LC.png | Bin 0 -> 1139 bytes
res/flags/LI.png | Bin 0 -> 973 bytes
res/flags/LK.png | Bin 0 -> 1635 bytes
res/flags/LR.png | Bin 0 -> 960 bytes
res/flags/LS.png | Bin 0 -> 938 bytes
res/flags/LT.png | Bin 0 -> 745 bytes
res/flags/LU.png | Bin 0 -> 729 bytes
res/flags/LV.png | Bin 0 -> 701 bytes
res/flags/LY.png | Bin 0 -> 891 bytes
res/flags/MA.png | Bin 0 -> 908 bytes
res/flags/MC.png | Bin 0 -> 684 bytes
res/flags/MD.png | Bin 0 -> 1104 bytes
res/flags/ME.png | Bin 0 -> 1267 bytes
res/flags/MF.png | Bin 0 -> 692 bytes
res/flags/MG.png | Bin 0 -> 759 bytes
res/flags/MH.png | Bin 0 -> 1381 bytes
res/flags/MK.png | Bin 0 -> 1282 bytes
res/flags/ML.png | Bin 0 -> 699 bytes
res/flags/MM.png | Bin 0 -> 1288 bytes
res/flags/MN.png | Bin 0 -> 1089 bytes
res/flags/MO.png | Bin 0 -> 1203 bytes
res/flags/MP.png | Bin 0 -> 1445 bytes
res/flags/MQ.png | Bin 0 -> 1744 bytes
res/flags/MR.png | Bin 0 -> 1235 bytes
res/flags/MS.png | Bin 0 -> 1534 bytes
res/flags/MT.png | Bin 0 -> 826 bytes
res/flags/MU.png | Bin 0 -> 759 bytes
res/flags/MV.png | Bin 0 -> 1127 bytes
res/flags/MW.png | Bin 0 -> 1076 bytes
res/flags/MX.png | Bin 0 -> 994 bytes
res/flags/MY.png | Bin 0 -> 1215 bytes
res/flags/MZ.png | Bin 0 -> 1267 bytes
res/flags/NA.png | Bin 0 -> 1442 bytes
res/flags/NC.png | Bin 0 -> 1317 bytes
res/flags/NE.png | Bin 0 -> 970 bytes
res/flags/NF.png | Bin 0 -> 1019 bytes
res/flags/NG.png | Bin 0 -> 682 bytes
res/flags/NI.png | Bin 0 -> 961 bytes
res/flags/NL.png | Bin 0 -> 726 bytes
res/flags/NO.png | Bin 0 -> 866 bytes
res/flags/NP.png | Bin 0 -> 1255 bytes
res/flags/NR.png | Bin 0 -> 941 bytes
res/flags/NU.png | Bin 0 -> 1126 bytes
res/flags/NZ.png | Bin 0 -> 1544 bytes
res/flags/OM.png | Bin 0 -> 989 bytes
res/flags/PA.png | Bin 0 -> 987 bytes
res/flags/PE.png | Bin 0 -> 680 bytes
res/flags/PF.png | Bin 0 -> 1099 bytes
res/flags/PG.png | Bin 0 -> 1490 bytes
res/flags/PH.png | Bin 0 -> 1196 bytes
res/flags/PK.png | Bin 0 -> 1338 bytes
res/flags/PL.png | Bin 0 -> 689 bytes
res/flags/PM.png | Bin 0 -> 1741 bytes
res/flags/PN.png | Bin 0 -> 1684 bytes
res/flags/PR.png | Bin 0 -> 1363 bytes
res/flags/PS.png | Bin 0 -> 1060 bytes
res/flags/PT.png | Bin 0 -> 1138 bytes
res/flags/PW.png | Bin 0 -> 1223 bytes
res/flags/PY.png | Bin 0 -> 924 bytes
res/flags/QA.png | Bin 0 -> 844 bytes
res/flags/RE.png | Bin 0 -> 692 bytes
res/flags/RO.png | Bin 0 -> 699 bytes
res/flags/RS.png | Bin 0 -> 1260 bytes
res/flags/RU.png | Bin 0 -> 734 bytes
res/flags/RW.png | Bin 0 -> 1003 bytes
res/flags/SA.png | Bin 0 -> 1320 bytes
res/flags/SB.png | Bin 0 -> 1612 bytes
res/flags/SC.png | Bin 0 -> 1318 bytes
res/flags/SD.png | Bin 0 -> 1063 bytes
res/flags/SE.png | Bin 0 -> 780 bytes
res/flags/SG.png | Bin 0 -> 1021 bytes
res/flags/SH.png | Bin 0 -> 1433 bytes
res/flags/SI.png | Bin 0 -> 933 bytes
res/flags/SJ.png | Bin 0 -> 866 bytes
res/flags/SK.png | Bin 0 -> 1162 bytes
res/flags/SL.png | Bin 0 -> 726 bytes
res/flags/SM.png | Bin 0 -> 1147 bytes
res/flags/SN.png | Bin 0 -> 963 bytes
res/flags/SO.png | Bin 0 -> 1031 bytes
res/flags/SR.png | Bin 0 -> 1003 bytes
res/flags/SS.png | Bin 0 -> 1236 bytes
res/flags/ST.png | Bin 0 -> 1247 bytes
res/flags/SV.png | Bin 0 -> 942 bytes
res/flags/SX.png | Bin 0 -> 1238 bytes
res/flags/SY.png | Bin 0 -> 1002 bytes
res/flags/SZ.png | Bin 0 -> 1479 bytes
res/flags/TC.png | Bin 0 -> 1448 bytes
res/flags/TD.png | Bin 0 -> 699 bytes
res/flags/TF.png | Bin 0 -> 692 bytes
res/flags/TG.png | Bin 0 -> 1133 bytes
res/flags/TH.png | Bin 0 -> 731 bytes
res/flags/TJ.png | Bin 0 -> 993 bytes
res/flags/TK.png | Bin 0 -> 1225 bytes
res/flags/TL.png | Bin 0 -> 1210 bytes
res/flags/TM.png | Bin 0 -> 1335 bytes
res/flags/TN.png | Bin 0 -> 1153 bytes
res/flags/TO.png | Bin 0 -> 919 bytes
res/flags/TR.png | Bin 0 -> 1239 bytes
res/flags/TT.png | Bin 0 -> 1476 bytes
res/flags/TV.png | Bin 0 -> 1682 bytes
res/flags/TW.png | Bin 0 -> 1029 bytes
res/flags/TZ.png | Bin 0 -> 1507 bytes
res/flags/UA.png | Bin 0 -> 694 bytes
res/flags/UG.png | Bin 0 -> 1053 bytes
res/flags/US.png | Bin 0 -> 1112 bytes
res/flags/UY.png | Bin 0 -> 1085 bytes
res/flags/UZ.png | Bin 0 -> 942 bytes
res/flags/VA.png | Bin 0 -> 977 bytes
res/flags/VC.png | Bin 0 -> 1065 bytes
res/flags/VE.png | Bin 0 -> 1074 bytes
res/flags/VG.png | Bin 0 -> 1612 bytes
res/flags/VI.png | Bin 0 -> 1631 bytes
res/flags/VN.png | Bin 0 -> 1120 bytes
res/flags/VU.png | Bin 0 -> 1387 bytes
res/flags/WF.png | Bin 0 -> 1215 bytes
res/flags/WS.png | Bin 0 -> 1004 bytes
res/flags/YE.png | Bin 0 -> 715 bytes
res/flags/YT.png | Bin 0 -> 1540 bytes
res/flags/ZA.png | Bin 0 -> 1494 bytes
res/flags/ZM.png | Bin 0 -> 991 bytes
res/flags/ZW.png | Bin 0 -> 1116 bytes
res/genflags.sh | 53 ++++++++++++++++++++++++++++++++++++++++++++
scripts/copy-res.js | 1 +
250 files changed, 54 insertions(+)
create mode 100644 res/flags/AD.png
create mode 100644 res/flags/AE.png
create mode 100644 res/flags/AF.png
create mode 100644 res/flags/AG.png
create mode 100644 res/flags/AI.png
create mode 100644 res/flags/AL.png
create mode 100644 res/flags/AM.png
create mode 100644 res/flags/AO.png
create mode 100644 res/flags/AQ.png
create mode 100644 res/flags/AR.png
create mode 100644 res/flags/AS.png
create mode 100644 res/flags/AT.png
create mode 100644 res/flags/AU.png
create mode 100644 res/flags/AW.png
create mode 100644 res/flags/AX.png
create mode 100644 res/flags/AZ.png
create mode 100644 res/flags/BA.png
create mode 100644 res/flags/BB.png
create mode 100644 res/flags/BD.png
create mode 100644 res/flags/BE.png
create mode 100644 res/flags/BF.png
create mode 100644 res/flags/BG.png
create mode 100644 res/flags/BH.png
create mode 100644 res/flags/BI.png
create mode 100644 res/flags/BJ.png
create mode 100644 res/flags/BL.png
create mode 100644 res/flags/BM.png
create mode 100644 res/flags/BN.png
create mode 100644 res/flags/BO.png
create mode 100644 res/flags/BQ.png
create mode 100644 res/flags/BR.png
create mode 100644 res/flags/BS.png
create mode 100644 res/flags/BT.png
create mode 100644 res/flags/BV.png
create mode 100644 res/flags/BW.png
create mode 100644 res/flags/BY.png
create mode 100644 res/flags/BZ.png
create mode 100644 res/flags/CA.png
create mode 100644 res/flags/CC.png
create mode 100644 res/flags/CD.png
create mode 100644 res/flags/CF.png
create mode 100644 res/flags/CG.png
create mode 100644 res/flags/CH.png
create mode 100644 res/flags/CI.png
create mode 100644 res/flags/CK.png
create mode 100644 res/flags/CL.png
create mode 100644 res/flags/CM.png
create mode 100644 res/flags/CN.png
create mode 100644 res/flags/CO.png
create mode 100644 res/flags/CR.png
create mode 100644 res/flags/CU.png
create mode 100644 res/flags/CV.png
create mode 100644 res/flags/CW.png
create mode 100644 res/flags/CX.png
create mode 100644 res/flags/CY.png
create mode 100644 res/flags/CZ.png
create mode 100644 res/flags/DE.png
create mode 100644 res/flags/DJ.png
create mode 100644 res/flags/DK.png
create mode 100644 res/flags/DM.png
create mode 100644 res/flags/DO.png
create mode 100644 res/flags/DZ.png
create mode 100644 res/flags/EC.png
create mode 100644 res/flags/EE.png
create mode 100644 res/flags/EG.png
create mode 100644 res/flags/EH.png
create mode 100644 res/flags/ER.png
create mode 100644 res/flags/ES.png
create mode 100644 res/flags/ET.png
create mode 100644 res/flags/FI.png
create mode 100644 res/flags/FJ.png
create mode 100644 res/flags/FK.png
create mode 100644 res/flags/FM.png
create mode 100644 res/flags/FO.png
create mode 100644 res/flags/FR.png
create mode 100644 res/flags/GA.png
create mode 100644 res/flags/GB.png
create mode 100644 res/flags/GD.png
create mode 100644 res/flags/GE.png
create mode 100644 res/flags/GF.png
create mode 100644 res/flags/GG.png
create mode 100644 res/flags/GH.png
create mode 100644 res/flags/GI.png
create mode 100644 res/flags/GL.png
create mode 100644 res/flags/GM.png
create mode 100644 res/flags/GN.png
create mode 100644 res/flags/GP.png
create mode 100644 res/flags/GQ.png
create mode 100644 res/flags/GR.png
create mode 100644 res/flags/GS.png
create mode 100644 res/flags/GT.png
create mode 100644 res/flags/GU.png
create mode 100644 res/flags/GW.png
create mode 100644 res/flags/GY.png
create mode 100644 res/flags/HK.png
create mode 100644 res/flags/HM.png
create mode 100644 res/flags/HN.png
create mode 100644 res/flags/HR.png
create mode 100644 res/flags/HT.png
create mode 100644 res/flags/HU.png
create mode 100644 res/flags/ID.png
create mode 100644 res/flags/IE.png
create mode 100644 res/flags/IL.png
create mode 100644 res/flags/IM.png
create mode 100644 res/flags/IN.png
create mode 100644 res/flags/IO.png
create mode 100644 res/flags/IQ.png
create mode 100644 res/flags/IR.png
create mode 100644 res/flags/IS.png
create mode 100644 res/flags/IT.png
create mode 100644 res/flags/JE.png
create mode 100644 res/flags/JM.png
create mode 100644 res/flags/JO.png
create mode 100644 res/flags/JP.png
create mode 100644 res/flags/KE.png
create mode 100644 res/flags/KG.png
create mode 100644 res/flags/KH.png
create mode 100644 res/flags/KI.png
create mode 100644 res/flags/KM.png
create mode 100644 res/flags/KN.png
create mode 100644 res/flags/KP.png
create mode 100644 res/flags/KR.png
create mode 100644 res/flags/KW.png
create mode 100644 res/flags/KY.png
create mode 100644 res/flags/KZ.png
create mode 100644 res/flags/LA.png
create mode 100644 res/flags/LB.png
create mode 100644 res/flags/LC.png
create mode 100644 res/flags/LI.png
create mode 100644 res/flags/LK.png
create mode 100644 res/flags/LR.png
create mode 100644 res/flags/LS.png
create mode 100644 res/flags/LT.png
create mode 100644 res/flags/LU.png
create mode 100644 res/flags/LV.png
create mode 100644 res/flags/LY.png
create mode 100644 res/flags/MA.png
create mode 100644 res/flags/MC.png
create mode 100644 res/flags/MD.png
create mode 100644 res/flags/ME.png
create mode 100644 res/flags/MF.png
create mode 100644 res/flags/MG.png
create mode 100644 res/flags/MH.png
create mode 100644 res/flags/MK.png
create mode 100644 res/flags/ML.png
create mode 100644 res/flags/MM.png
create mode 100644 res/flags/MN.png
create mode 100644 res/flags/MO.png
create mode 100644 res/flags/MP.png
create mode 100644 res/flags/MQ.png
create mode 100644 res/flags/MR.png
create mode 100644 res/flags/MS.png
create mode 100644 res/flags/MT.png
create mode 100644 res/flags/MU.png
create mode 100644 res/flags/MV.png
create mode 100644 res/flags/MW.png
create mode 100644 res/flags/MX.png
create mode 100644 res/flags/MY.png
create mode 100644 res/flags/MZ.png
create mode 100644 res/flags/NA.png
create mode 100644 res/flags/NC.png
create mode 100644 res/flags/NE.png
create mode 100644 res/flags/NF.png
create mode 100644 res/flags/NG.png
create mode 100644 res/flags/NI.png
create mode 100644 res/flags/NL.png
create mode 100644 res/flags/NO.png
create mode 100644 res/flags/NP.png
create mode 100644 res/flags/NR.png
create mode 100644 res/flags/NU.png
create mode 100644 res/flags/NZ.png
create mode 100644 res/flags/OM.png
create mode 100644 res/flags/PA.png
create mode 100644 res/flags/PE.png
create mode 100644 res/flags/PF.png
create mode 100644 res/flags/PG.png
create mode 100644 res/flags/PH.png
create mode 100644 res/flags/PK.png
create mode 100644 res/flags/PL.png
create mode 100644 res/flags/PM.png
create mode 100644 res/flags/PN.png
create mode 100644 res/flags/PR.png
create mode 100644 res/flags/PS.png
create mode 100644 res/flags/PT.png
create mode 100644 res/flags/PW.png
create mode 100644 res/flags/PY.png
create mode 100644 res/flags/QA.png
create mode 100644 res/flags/RE.png
create mode 100644 res/flags/RO.png
create mode 100644 res/flags/RS.png
create mode 100644 res/flags/RU.png
create mode 100644 res/flags/RW.png
create mode 100644 res/flags/SA.png
create mode 100644 res/flags/SB.png
create mode 100644 res/flags/SC.png
create mode 100644 res/flags/SD.png
create mode 100644 res/flags/SE.png
create mode 100644 res/flags/SG.png
create mode 100644 res/flags/SH.png
create mode 100644 res/flags/SI.png
create mode 100644 res/flags/SJ.png
create mode 100644 res/flags/SK.png
create mode 100644 res/flags/SL.png
create mode 100644 res/flags/SM.png
create mode 100644 res/flags/SN.png
create mode 100644 res/flags/SO.png
create mode 100644 res/flags/SR.png
create mode 100644 res/flags/SS.png
create mode 100644 res/flags/ST.png
create mode 100644 res/flags/SV.png
create mode 100644 res/flags/SX.png
create mode 100644 res/flags/SY.png
create mode 100644 res/flags/SZ.png
create mode 100644 res/flags/TC.png
create mode 100644 res/flags/TD.png
create mode 100644 res/flags/TF.png
create mode 100644 res/flags/TG.png
create mode 100644 res/flags/TH.png
create mode 100644 res/flags/TJ.png
create mode 100644 res/flags/TK.png
create mode 100644 res/flags/TL.png
create mode 100644 res/flags/TM.png
create mode 100644 res/flags/TN.png
create mode 100644 res/flags/TO.png
create mode 100644 res/flags/TR.png
create mode 100644 res/flags/TT.png
create mode 100644 res/flags/TV.png
create mode 100644 res/flags/TW.png
create mode 100644 res/flags/TZ.png
create mode 100644 res/flags/UA.png
create mode 100644 res/flags/UG.png
create mode 100644 res/flags/US.png
create mode 100644 res/flags/UY.png
create mode 100644 res/flags/UZ.png
create mode 100644 res/flags/VA.png
create mode 100644 res/flags/VC.png
create mode 100644 res/flags/VE.png
create mode 100644 res/flags/VG.png
create mode 100644 res/flags/VI.png
create mode 100644 res/flags/VN.png
create mode 100644 res/flags/VU.png
create mode 100644 res/flags/WF.png
create mode 100644 res/flags/WS.png
create mode 100644 res/flags/YE.png
create mode 100644 res/flags/YT.png
create mode 100644 res/flags/ZA.png
create mode 100644 res/flags/ZM.png
create mode 100644 res/flags/ZW.png
create mode 100755 res/genflags.sh
diff --git a/res/flags/AD.png b/res/flags/AD.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e777b98227af5bb2cf1994491f8fbe8841922a7
GIT binary patch
literal 1143
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`z(E;1l8sRB-?PeFljY
z45F+3!%BYLVg7fY0fPSCVZ0Zhah})uf`ApWI9wL2p6UMshCg?if8AySl0f!9ur9D^
z#oumlK0c;RG$!$$0_ScUavIfGP+GFMfPn>C{~R2d(;d
z=NmknC4Xjx_p@UPa1#Q;i|!uOIX*k!af{T$<*JY7$sAuA@Zf;P{XjLK6+qd?$JGxm
zNjNY&ZvUdR1B+q~EQx=1Oa&+l^xDtcEMKqjJ~*O%Y<2j9Lt0<1^8UHS3=9ysum9d-
z_<4&JNCJHg2`hNeK^VZWEx55v3P>@Q1o;IsI6S+N2I3@nySp%Su*!M>Ih+L^k;Ond
z0gOLnJDmqI*h@TpUD+S93JNd@mTKDY0)02vXIQJR}%W#y8eT$-DjS7K!q0Mt~>
zV7UDMZhbU0VDqf3JW?~$GfEiD4GgMft~X&<6P}q;lEGkTU|?|EWRX2kjUKB)#?|)z52UH}EtSAJiiowvt($v5h2+W(OoXZ0$5kgWDoLQC1U~X=1
zWa1Q*dgM7!Ruf4!G{}=7Ei)(8N?*SyH9a#wPd6cV~y
zyDIvTQg2L#V@}v-k;}rpYOKAUYDP@
zKMw%%X{*_Zu~^A%+4!B#Q*#*9oY7_k7{9aQ2cyCLL66mG1Bf06=(+{)9gn&`0>}v9
zvm1bV1W*_rm~N=Wi>r?FE(^wFGMNV0%vRCP!wOR*w(3K_>w0BQsw9-ssAuk7A6lA>
z%}roQIwvPRIhn?Ri+Eglr>0VB^^7bJ4G+g+u}y$_l?qf!C>8)T_WMr0HS*$fuldvB$mZ?!}gcU5ICP
zmnN2*`&JJm_Qb}#)Qo+1q=5J@4lyu!c#Ll6jg1z+d?1y8ycTd=^OIEW#i
zbcKnqK*(Z*@P|B%pAdOGAiND9XwT94|pNLeY0GCjQN761)-*q#mJ{W9ETq`CvYXDcTH5qY!1GQcs!&
yM=RdoU3tdtqLT)n;AbgNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`z(E;1l8sRB-?PeIV(=
zz_5>jVLuq{V`OkiW?-1Zz%Uab2$2GkAX%8=1I)|^SXuWoF+s(Fx?n~f=Hol9r+3!E
z;#zTknMCH$Y3w=^mS!_$SNqn
zBv`6x!wVEz?djqeqH#VsLBgj&P@LhUp(BGax3;vjw6-<7y10aZ?(wsSPaoG;=l$5}a9IM}$D+gsbmGFv*@
zx|-cxJzd<#GTgkJ-(NppKHi?k@_)mD1rH`%*zlplgJK#|-m>5{ddGcYWFQ5M(UO5H^*+2yWxAanww^U19BT7;dOH!?pi&B9U
zgOP!uxvqh!uAzB|p_!F|k(Hsjwt=CQfx+e584pl2Z(@38a<;CyzJ6w2N@|5(MoDf?
zP1&qGC}UsFD^^p|GvNv
z%^cqlpehDK6H8MAV<0eZo^mb^s6+_KoZ!r=R0b1s19MBKU(QBhKv_*B+0Y+
literal 0
HcmV?d00001
diff --git a/res/flags/AG.png b/res/flags/AG.png
new file mode 100644
index 0000000000000000000000000000000000000000..78c03626bae174c6201b23be4bf25b07960bfebb
GIT binary patch
literal 1394
zcmZ`#drXs86u&L)z(Q&3ke8VugBFb7*Oo`&8zF!#&`1#qDn!{RDPjY8X^>i
zxS32Qgb)|m91AX{!m=2^;ha2Wg@I-U|3HEu4-u!#Ww?!<3R%!(C+D7X?(h75=iJ=7
z%#2hfBand*VoKA*a>zSf$HNU`7lWpTL{lfpk`TIf&hsw?9qvKOG`S3+<2-~as}WiQ
zsB#`58y}&?0)+4;g#64cU0Lx6Q3f;9b0k2RnwmP`&VpjAQ7D@?XnoImKZ@ph2AB_<
z>cyahhtMEG4Xs}|p8Ho>F+_I
zQYi?ANaNpWJjuN0cz3492O`vf01jOsgWuusKJwTO&xr}A)|D{kZfsw_>$5)L0}<*v
zGXrqwZjeVgyqm1xc<(^u7e?P1#*N-naZ)(Y6F2pg7lm0ceM9leB%
zJc6m4J*c%QA;Lrum#uku#!q4;4-$0fDRMNlcmH|LE2tRW|bxBrs`5>!em{l1
zTm&|EEFj`ZYx{=wo?zedH;(8XeW&1mDOPz#HcFhkuX0@q_os@{$MpBo;Ihq}mPbM^
zczvGfl1HI%w@PIa_h~wZP372j$1_2bAQdO&gpDc-{L?ErerQM_=yY^A9M>G34zt5y
zrsgFk_=$2qt!=cQ`-1L4quHw^iC(7?d_T-`v@~6()qmwv|J~VdTY65nekQCx6H;G&
z-9IaC&nX%
zogJiwB*~5!&m+et-7e|lUM6N|XNk+)K8c;~^oV0C+U&O2;5*ZGy+67ktfDa8ckS;o_*|}4l4~teSP5KdAs`_kUm%L$
zM@I-mIf59RFT@3+J$wPq=TAJ)JbXi7FcoQ4<^L~etr
z4202&y^uz_Xkri{sU$;uHM!vQzgr3F
A5C8xG
literal 0
HcmV?d00001
diff --git a/res/flags/AI.png b/res/flags/AI.png
new file mode 100644
index 0000000000000000000000000000000000000000..8a707823107c6539e77e852aeb80f08445cb55ee
GIT binary patch
literal 1515
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`#@x;1l8sRB-?P{o@t=
zch~G{=-eh_*UP5cyegyPrc;Pd)Jz7odIzVrb@_b{=B!N2Uc{hO!=O@YwQr_kD(RXwTwH)pNdyZUfc@ftzX4hH2~pkiETeP+kToURKM-Op<~
zU(8&5JE`c3zVm~+9w7JWlm+|BCv3=Qk8p277y`6fp_)Otnn4kaR6s7dWgmFmHsG3V
z;0?#%TekjJbsaCt7~Qf9xM>$~-Nyf#UEm%2fLx<=29-LXVrI3Pu$1%1wF4L4uH3Z0Z`t|UiP!A{k8C;l@Zi}ObCxY^T9TBxK+~xg
z;u2=H>a{x#{r_<8|C#dtFZO-^_Qok@0)t{rbH|ob^EU6PnVRU=E@#udHmmcFQ%FeS
zT+^VLbEj;-JY(g;tX@5fMu;Jdsx^yNZTo+J`Tu)s{$FVSczc_9a39c+in#tbk0wdu
zW}t(aH5)_SnsbaZ)$O~19%t2Rbc~r-RkYC3q7E7+O4Xe+HvGRf;s5#8|JSBIJ~da_
zsTJrQpgAA~@W2N#U|N9D0SrC36qxImKJD4V^DiG?e*5yynw^I^b->zzQp&Yly0y8J
zwl2E#XWD`LCZS!B*atkI23ZZX0u(z~5CenCjMs6%G{;yH
z@At5CxEipCu`GY5qo;`f}SloeO!JGvXHgv3*v7=?llr24L
z=Im)&G-*@Us##VMe$K(((eB~?_YYh+apTC9Gj|SMI(6&VH9np6_YYn?dGqMivv&_)
zK7IT6^>cXv2@x3~u4&xd{T)4BeVx7C{vJMFexAPG=TDqDb&m1$(`Qe`MZ`p>Pnk9~
zJR~gi`ju-}%}vZqo1aES-M(dQwR=}})$d>GK66YePhH8poPK5w>$KUn>F@UZNR#q0YFW~42H}9@770C12)gf$|E&1J)?xd
z%)p@P-rlX))r4oJlw>d%8W|WI*-#b;R3nLGmv3fnYDr~5Dnlm7f%?T|>HFUo_yHA(
zBP$94s$wuSu{1R>1_JZuDd+NlN(7OV1ZP&IGME@xS~yMA`D6~1)I^dD4f142%gjl&
q($_CaP0!5F(@o1sOfLr6rtj#f2c(L-cBuk2F?hQAxvX7`|TP=G06yNAtPc&}aA(aBbp+GMiDu}LYT3w>99#}o0VnAbsSCg0J8)#fcB)EF|
z$iCZOhDwS5;C?H4u2yG9vLR(3%piL2zrPM!mO<7D4ySG1ceSbpu`1ivrG&KNu$tWu
zEeE`mJEz*4yK3;&Tupzn-lTb8y?`)@VAI1x#^KI?od{k!b>
z10O$Jh!#VI;YgIfQ(XH=OHEJl!I(c9O89s#9vGgSTfX_h%128}OJ9BXh4RS7#mSj7
z^QYgqcx<2dg}r%C${raQwFccncg)k3_gMU{^nvK(}Hux)?nJs7+8k+{OicK|7wUQgM4W0
z{~M-HT=$^CRN5hv3<*#B(j1|)nKT_s27EC(6M;YnlL6Wh_k}s9FU$vq+f6jhCxYB)
zM?{FnCPwme7(tarxFgxPpJlDdKsL@L1eWbZQ-&C3{#q>k&()s$^H|o-@!^O-j0`h+
zw&pH8nyNYfcpl?}LWGzYrug&ZDlD6;EKWYo31caa@TK$7nUV1OzodHpGso$Mix_t8
zF)};xn4Wp*S^^eT)to+loFlt;?KE0$%zrwCVp~_-!E*m|sU7Vq)D0rHBFG5`Po
literal 0
HcmV?d00001
diff --git a/res/flags/AM.png b/res/flags/AM.png
new file mode 100644
index 0000000000000000000000000000000000000000..b39695fd4985429e3e5be9d040bffec6661ce9f3
GIT binary patch
literal 744
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&j3?%D+y-WjAEa{HEjtmSN`?>!lvI6-E$sR$z
z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`YL6XFV_@87?FlR*fG
zZZHV@D&{emEMhQTz+kvIEH?e)a>h?97=Q=}CSLhd38WZHg8YIR9G=|(SvL>2?-1Tg-P?Q|Zj
z0%Sx;Mrm%6m6c0=a%paAUWt`e08mpggW>Z3yY#`u_I?en3Uy$cjRMsu&DS
zEKLoJfxx_Z%DFtC5&NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`!UQ;1l8sRB-?P{d0n9
zP{glxP5{OhR68%Odeunzg0$*6pg3HOpxRk}wJX{xFFItNH_2W#P)3%$YN-6ARPMT^
z@`F_Q=WVhV}XP?&)L9}lB}7E6FDyQVS=
zknL*C7VNXenDPQZef0Lj)I^bC!vzxyjk-@FByqJsm8;ffo%U-Y_>uDD)jxY-i|Ud6fTwf#KOK{o8r{
zZ<>MbRV{IiC`m~yNwrEYN(E93Mh1rFx(24YhUOuLW>yA9R)*%<28LD!2A6MVJV4Qq
zo1c=IR*74~qP7b$Kn>;~8;bMOO3D+9QW^A1i;MJg@{<#D^ouiq0{SWW$@-qTiRr1n
ziRqci*}CTX`k8qtsTFz|CAm2@WwX`+jgSBt5t31wn`C9>lAm0fo0?Z*WfcI_RLo$w
z{Qqu!G&NxJtgJjzGt)Cl7>o@JYDDYffNI2%%z>&2&rB)FU@$Q?n11K%VW1L8BqhF?
zxv3?U1*r^~AouAPm!3el4NL*Cqr6hPO6o@eo<mdK
II;Vst05+0I-~a#s
literal 0
HcmV?d00001
diff --git a/res/flags/AQ.png b/res/flags/AQ.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa76fbb278419bf8f476d23c7d50d79c6d720617
GIT binary patch
literal 1405
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`(>3;1l8sRB-?PeXH7Y
zKxA2S&b<085LwiKxNrm%cWJqhGw)W`+*_f2S1oJLS=5{bk_ZJbHc+K&%f(G+-hBV{
z_s6flkKg=Qed1NoqB}0l7l2Z5^)4+J?HkTRYynzVu<*{W-~ayq|NrURpGyzFG_HAI
z4K@&HOY)2xv-ds=?z;kH1Jy4&_yVX52rfSO>>HpI(2#(hD?q0L
zk!SlQpksi7K=AhS@0iKgAg0;Wohw^%7wA-o6p+0C>U#*tg&@0tPI73xu=~=xe;^Nm
zz`Xs>k^Sz~eyL&ggM|lQOxyKz)$vy+ZhZuX6;Rpj=ih*aAgctjL2&_&5g;RJ`i+m@
zet-G#r)I@HWMyz)03DD%`zFxp0LV{KSGq*)}IGD56A`@2oV7$fX3
zJs`zc666=m;PC858ivL>2?-1Tg-P?Q|ZEaloaXvXg!lyw{oZ+OQBcn05wzM_7y7-iCo#ST@pFXayprN9p)TN`Y
zrl)vPMO9Z>TYde46-(AE>QY(0Y~8|@OV=)5&Cc?RtEzietKx>;qpv(lsJCu^(g(S%slrBzj_Peo5W
z42lem4UP`Ke__S-CD-pP6h`YE`GJ;rE%K1S+?o#
z_Wa})ThwkUe0kAP?`e9``;wk&xkNnf+<%an!BpDi_{`@kjsk;9wZt`|BqgyV)hf9t
z6-Y4{85o-D8kp)Dnui#gSs55v8JcSw7+M(^T)v(007XM?eoAIqC2kFi+AhQZHJF2J
zD9%qSDNig)Wza7zF4E7*PfpCyFU|l8=%?f->wD%VrlzeE9XXd4(R_JAv
z$zRRB;^F@xdq|GV|k)PT*ivhqmHOwTA`
zFtIdq{9V2rs74&g9H^S`%#@N026GdW?l*0RfJ!8hl=x=mrj}F|q%vfJ+^1h$mcIXe
zfghSVz9B$W42C9_rUu49VBS3CTpmz~Ad)%3nN_I_W){XKPW@HRNkBR
literal 0
HcmV?d00001
diff --git a/res/flags/AR.png b/res/flags/AR.png
new file mode 100644
index 0000000000000000000000000000000000000000..28750f42a84aca02908a5c7af99f452d6a8357ef
GIT binary patch
literal 955
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lsFmS6XFV_@87>)vgUsA
zY6NQC_85V-KWPObn8>@YzrpCw>-V1?-njxqK*qbTe}IDjf#BcY*H?GlSQ-IDKn9Te
z=jZqPd;4$C5C@|Bd-{P~sG4OFHj3q&S!3+-1
zZlr-YN#5=*3>~bp9zYIffk$L9kWK*O57|!VfeiK%PhVH|hpd7EOoFAFHoQQgR!C~-bV#nA|-aOd2w|TK`ll$rqM}+H}IT#q0y_c4mYo$3G=pfY+*NBpo#FA92
z6zqGhWKPNvqF-N~R11O-MlAo;anVXoN>YJFJnVhX_uCJe&my%kc
zmr;_NQ&To;9nc5~kP#snrMXE~RxbI;rManjC014eKuyIAhRgr&)<;tVHqXk+BQ-NU
zqlCfKz@TCV^BbTVaU^q~YQi&9N-`KM3=AG`Jn#spL=s7fZ)R?4No7GQLng?5`o(4G
z``;J%p_$_w0#wCdXkuw8@mC9gZX=&o*F!9qyprj^}WN45l
vLt17|s+GQeQEGZ-ex7bxPGWj7$Toe)AUzn
literal 0
HcmV?d00001
diff --git a/res/flags/AS.png b/res/flags/AS.png
new file mode 100644
index 0000000000000000000000000000000000000000..36ba9b34df2ad79233575adbeb183e9b1e98b847
GIT binary patch
literal 1651
zcmZ{i2~<-@6ov-~qIdvNDO&NgrJ@nU_X4IV50HXTKz$e?9B|jH`t5D=-LC4ek0ELA`StP}%+AVvtL6HyyW`_9bVH#6UV@7$T2Ob-dP
zvi#T*0ALjyIj%^O-pK^jiaR9c?2O#k~07l?a
zVmAN^6o4KU09Xb9_EJ^xYA*mxE9om40T6ib-~j;q4;%Ci8_yCjodAPAdHL?oLyDF|
z2k)_QfIkVa9YCay`Kp-NtB(7ytK>;tr*brEwYI0n2!<-i^GP6j7FdIk=mI-DgSM_h
z_)X`DU!K?8{OeYALtf^Eqz##y7@E%Z2||Gx;LHT;+)Y=rZ1FToWGPG0e(=O#)y*-D
zMz7bu80alXWTkxVupKca$l$C}GNv1S=frSM6TqDY)-N^*jkLy-UBU|^WAFWVsK5M%
zuDe^W)4hKEy82{lDmG;|3gTTr%39CXrrSe9FGzql&4lGliU_r#?^wXNNZ;7FGrg~*
zY^1YGKQaR2!ta$<+frSTolNYZnx?pew3YLID=uhlYom}D#1zl7_LL^Rbg;BcKhXaM
zHw=&4YaVyCKka^UNh$gP1!v;c_Vx7*4-ZcWx1lj9y|?)4`*1IZo_4AeJL*;1p(pn%
zb5-k{8_SC(rs+DKrgL~<#M?AS$J5l0^>%YR(_g4o>j!_MttD9{SO-
zQ@!Pvdv5)z>1r_ICsq;t*wSdVRM~YZ`^DWRUH^a)JYGdm@=sara>R>*nXraecwY*H
z#)JqB2?JmK*#cQ$61^hOAM7@t8w4j)q(N)s(6Zk2{*8Y1@W+A(#se%KncGe?wN)(i
zvVt1#V1Hi*xt_zC<(OzoW3jk?lWs0LFV;Ay*0*|H*+!P>On3N|J7z|AOivHJ?RH7(
z;Sp~h;KZ{Frz)&)SIOKc?*y}ps-Mzwlg}I~N;^o~pDO+E0qdD@YBiy*uB)o8LCBlSC%7mry@~_XaSw;fj@xUwA{W91gd592
zf+cJL4`&NRoQd0Q3>35j^y=EFJA#VmshhEO4i#xVa_jzYqVAux;%MRGtn
ztuI0T#k}!{VL?2RKu7>8if+j;)BHCRA>tB3KtWNoa!IBSWM&)1!bK7u5ijKdk>P-d
ze6yhJnKT4K_QntcQh>6=gNnMtkEYyL7Xy*$Mo5@wD!lvI6-E$sR$z
z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBC?OHx6XFV_@87@wR@3sW
zy7_zOz`swQ|Ns9VC^*6X(IFtkSQ6wH%;50s2FNnTByV>Yh7ML)4r>`sfLsmfnCc#oo8(yH0rKgKyh{WaOgavX5A}&l0>x7szgq}z#Hz-bc
z-Nex6kf*`K!n8A!V}i$o?q%X2OC7#SFv>l&Eq8k&a~npqhbSs9vZ8yH#{7+k)c@c>0bZhlH;S|x4`i`p*405zC{
zY$(o8D=AMbN@dV5EiTf}$xlwq(J#&b3h1ZgC+mCWCZ?zQCZ=a5XX~2l>u2Vrq*mx<
zl;q~rl+9WPG(rMoL`X(yZjzOiOMY@`ZfahMl~n*xQ!#_#^8dT_(bRy=v$FC?%}mcI
zVK6f=sJgdzD^QI%k~vT{;h8BV84Q*N29JtYT?HzUL{j3LnVVWtS&+(*338u)aasEQ
z_XU1v=J~r>mdKI;Vst06FQ@)Bpeg
literal 0
HcmV?d00001
diff --git a/res/flags/AU.png b/res/flags/AU.png
new file mode 100644
index 0000000000000000000000000000000000000000..7004861f7fcf4afb3baa9e4991a2c827ebf51e42
GIT binary patch
literal 1719
zcmZ`(3sjR;9KVCj;eykUYA6rEN~Jx%4TR;68pF}HaD+IO1tNQIj6K{-5f#SF02u>8
zQo=AKA4oGFDWU=*Qwg5oTRW~i11Ay0H(gJ=wBy@LocV(`1zPp9SFQLS|9b)knc}3;oMfUiD9AZ+qLV^$lF1{)
zQ5+#z2x$Nmk45fE0fyn_7npRYV|cwpz~y2gCXneQIvJQog5CU7(8IFg3Wc
zRgmM1qAlgrMaR_DetP7lt@=Ppe$?awD8%D8*=*;D#G0{mihO-bc{~Ti;jWcaoJq+G
znp6TK_r})BsM&PtOe|koSL?jbR#kX(t_1@~~ze&L3-`CV_WJnjuHU0lWHS2>nT&rw_VcwB^A=p_AfwTwZyMBD5AKJ=>Pr$YQXHCx
zp)Eq3wad7XkT}Srie&5C|-?d;{%-S;@f`hj^w$XD@98FK{
z>4Zv3YO|=n{uk9{M{0}k=FSVLhc(xlz2BJ;_O0Q{!?`(w4?Y0KK_<#F|1*2=TytD;8!U1_cBViB^no)k3+HCzLD2Dl#2Glp2Y26-8lGXRR?;
zIiN+L%Yv^ksYMJ1ODi_1r5YoHkpx8sK-=X!hWv*!>c?Pkq)NHM2x4YYLl3Ol|7y-s
zrNpQJw8;0VzRF<%FjejoCUWP`Uy{3}$)D@47@tB6yPckOgS7W=B(_;E!&t
zxTt{?e-FwcG$pT%61WGG&&OfgpORT&dNNWm!VG!F3wKTugz(
S<*L@5Pz1Q~i7ZE4M*cr$n^WNc
literal 0
HcmV?d00001
diff --git a/res/flags/AW.png b/res/flags/AW.png
new file mode 100644
index 0000000000000000000000000000000000000000..238084e4a895810b51b34591ac6c92047110506e
GIT binary patch
literal 938
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5l-L{K6XFV_@87@g*m)O-
zoVxD1^+MS|u0!Wtub#WL(=R!7-2<}WYW#ZdR5kA38`Y5AaoW2VD(>2IzkK@D?MYpi
zG`-gr&dHu}8>kDS#i8?FeD~$m<%Xgust5-Ij%*@EjeEs58Vk!6JeT@qz
z8kUtC&73i7rg7r*%?J1n6ivIq7;%ovn&EV0GJArh^cx19^ln*)KMk@5LLK`LGBeB)
zR_Fg?a&i&SF{&l55hW>!C8<`)MX5lF!N|bST-U%<*U&t~(9Fuf$jZ=M+rZGuz~J)j
zj0Y$ha`RI%(<*UmSk!hQ2B^UtWJ7U&T1k0gQ7VIeX>pN$PJVJ?j(%|lP(VK=KUv>1
zH!(fcH!(dkIa}9UUq3T1CAC5?qa-({rfk+apb-)vBSJDtbCayBT=J7kb5rw5tgHfn
znu-|=m;c|bkERA}o|TnHYG!&y34@t|LDjvzTY+lCk<5Xr3C~O^$zZTFFnCnF>MBr)
zB$5)}%-qzH%7RpeOpyEZi_6mYzc27ZGsiassEWbR#M0Ej7zoUpr<}_JDiJ_3Cpfbz
zl>w;0Da6618z`rVBo`Xw$&i+rlWL`}UzD1jnV+YdmXnxX46;n$FNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5l$amj6XFV_@87@A5WJKj
zXqjm2^sBq2pC`y(7B&8{gsWk45JTW{G%2_^bI4+*kR=lF)2@NF0L7c81OgSWTV=9#
zrRkQn2A|GwJWG%R8ue`%*YyLEYgU?mY!&*{Dg-3owTRrcSHCQ5{5(VEL#r@Q@DjfX
z6bYDI0wORM=r-;=u>ToLg8YIR9G=}s1Bx*wdAqwXbg;^L06Clm9+AaBIsuG7WILS)
zGT2KzeO=ifvI+_?36^Tw@B)P@JY5_^G|nd{Ncc1eiZh%vY-BLz)|R$rR~HwS2~auC
z%Ve{s=Fc0ZCZ{_E4AX?!7zG0j3(Gh?H4`luPJ1>t^sJe)r)kloO(rr8PeU9WLVaVM
zgT15OS@{kW?Mhg%JU<~LWlc8&%h!jS`R7}I{Mj$|uv7gX8$Sa>(gyL*Q?^w(0NtQk
z;u=wsl30>zm0Xkxq!^4049#^7Omz*-Lk!KV42-M{&9w~-tqcq<-_Ce|q9HdwB{QuO
zw}wS+7h-@K%t1C3=ckpFCl;kL=$953>F4ApC+6rEX8;BCQ}UDbJ#!P&Q+*TDGn2D*
z&Gq#&^HNeP^fF3vb85$!EpKi-TG*1
zz~)(5d8B5hXOu8lm>Te!r+|_jvN=#S;h8BV84QNT1_noqWI!<~iDZ{=W^QUpWkD)K
zCdh&M#bxRH-xv4+6^SD&3IVEOFf_3=H82JO^X4h%@_xR;4nS8k;!%D0p89
zl+#3#3k~vQNXyJgwbIuwN=?tq&(lrINlY&WS*Gt8p$DY&xLCx2nixD?{an^LB{Ts5
DNmwD5
literal 0
HcmV?d00001
diff --git a/res/flags/AZ.png b/res/flags/AZ.png
new file mode 100644
index 0000000000000000000000000000000000000000..686dbed76c41ffd984d60360fa5ede5669d3eabb
GIT binary patch
literal 978
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5l(-$>6XFV_@87@AFyk-~
zF-|`OMN)-Rl%H+hm>-UQ>n@~KY^i-nVlcv
z8lLexy-*Bzr4#vt!4xPp(asf!CfK@8^75bARzJP0Xp)=H1Z!uAIOEz>5L%PMxGD)m
zt_32H2*WxsVqnnX+4BkLJ;stCzhDN3XE)M7oFs2|7lsa2Sq~tGv%n*=7)U38@rP`u
z^FRiBiKnkC`$JYi0VcsxO&eaIP?x8RV~EE2s~5L29SY!SeHh)fd$)7+ox5|t*DIf!
zP{KX;cdq4siKQ`4lQqvO7iR2YIeWV1pM!x&-wpGqDMuc4rfAJQ`K-d>^kk=vA?rf2
zzq0XX_+H8?-_@4+^_R^8-V+5T^L)}jADzU$MKm&h+wQ*)E37^@lqFuj{r6+d-nY_k
zl^uV3$=sT6zvBph+#j9$9Orr1fv!?5ag8WRNi0dVN-jzTQVd20hUU5krn-jaA%02vXIQJR}%
zW#y8eT$-DjS7K!q0Mt~>V7UDMZhbU0VDqf3JW?~$GfEiD3=FF7?cIu9O?YNXNd|+V
zk%7UH4P}8qHIhhn`DW&(mQ)s`GGu}rs9#)`zW;rJA5f7vvZ4^6Dh5LnOH%`5ATV#9
zaxM?3L;y)iaAs91gSnxJQ{dmvbAWQ1NOGY;o(yT3IjL6q`bDYfnfZCTX*r4M#URV{
Y9i#MsRLH6Da-b##Pgg&ebxsLQ055Y|0RR91
literal 0
HcmV?d00001
diff --git a/res/flags/BA.png b/res/flags/BA.png
new file mode 100644
index 0000000000000000000000000000000000000000..5cfbb6d657bd65bf241170b98e67c3acd13d3a73
GIT binary patch
literal 1271
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`(dCz$e5NsNnwn`wYrc
z85E}|*e{AH-fa`U!7gOR_BmSr&ocZw4MqRYFuXg!Y2;GDpg0|5lkVR9#pfDMzV8*g5M*eFZ1M4rWkw#O%
ztTv5XXI4e`@s_FQt-UKQuaiJiz@RkMI&5uF)^?AiZ6OJ@H#Ui)D^Q#wYqN0uu6vF#
zn_U76?`{=FSD-wVO=G&8?V`wnT|kcnMi)HTE&x#j^e@CCKzF()ZU#C-(|tuua{kj@
zd_V<|(17`LnwZ(V6kpOh3v1>UboFNK0wP(uPEoz=}CZTLkYFdnrLp4a2
zfkAWbYzH94SQ6wH%;50sMjD8d#zTknMCH$Y3w=^mS!_
z$SNqnBv`6x!wVET@9E+gqH#VsK|-lP&^#d_B`GN_F*W)5gC~!kF*3*5)iJ6mFr4P(
z;_U9|>h$*TN<8Ix`oyV|+8SD#t5+nQFkHDZJ0mOe^@~?8r4vpVN=ix2o-u1?bVO8S
z@(IJ6H*Vduwy?6?y<=D63B#S$6;+kLfBgE%&XRP3m9@R4t<~Md&Gq<^MW+o7j~-Q5
zQBz&MWZBYmpfRawsn4H0dnzs>CYpR=>Xd0y!$ZPCuV1+aG{x|$xrv$S_AT4CmM5Gl
zEi3*0<=a>P85W#c?do!E91IKFtRc<*ETS;GBCJ&JL3V0hTQy=%(P0}8Wy!(hyiLa2iZ`ZpH@!Yawn`dR^k(!yFQNmziU{D#Ac^jxk
z9LXH0n()k&k_-k51B1sK4?F@YkwjABo0*$hQdyA7kO^|1esNj){`UobXy*8a097#<
znpm0|7z2TM^OSRWKqUf5<^*R}r81Zr8ab_9H)kSHP7_HkG{}=7Ei)(8N?*SyH9a#w
iPd6w9*{bk*X#w<#Ng@b=d#Wzp$PyTJkf#x
literal 0
HcmV?d00001
diff --git a/res/flags/BB.png b/res/flags/BB.png
new file mode 100644
index 0000000000000000000000000000000000000000..dcdbae7a9a0b325778a71d503914bbbd36b0a7f4
GIT binary patch
literal 1065
zcmZ`$Ye*DP6h2nwrud4|HR)x!n~BbhwoQ)y$YpJJ%iV0-s8rltcV}m(_QmXMJ}9#-
zq@psSA0ZLd4}~C0dtyTNKv78TK}G%0Bt#_0ih?Y%Gg+}k4R^kC?svZLoO@>ul^C_L
z(F>vhAXcx_m@uYFuWTk_NAxTX!z`}QPzcc081vN@iTfpXoyh=Ds{p7!05FME{TM)y
z1Q@phFsA^L{ii!N6#zsmEGae@p>m85HUvv`QL)!OKA>c
z{L_{t73<>=F-K-vfM>($4g9>D$5Yvj@ralsgS=GgQ?`Us%CvE+l`=%kk(su63@)EkPTUPUG*%t#Do6vQHRMz1L}uNbgf<;C@h
z$bq&@D?8=F$lMdAM>*}n`{=`R
zVSV4q3p>UaG?l(!KZX>m0a>xx+;F7yKdtB
zr*|Je#CMI~?m9bseDJdWOF1j9#*XJv%pIyBm%p*+i(3w6eWjEGni2Y)T%rcnTrp-|75=x
zB?)1Y&3r8jd23Yama$_ttYw7NwwUzbNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`%Gez$e5NsNnwn`wUrr
z2$b!|07uB;U^aV(pJlXnwx36tw?|m8r%bXhLL*Q?wx3k8?{p`(=ekbcG#$TdI)2h}
zJZIi$-dK^-Ja<{JT%~82#+9SDF%j)
zUwKP`G0IpHw}^*I%{&?$jphkV%tr!JbU->WvkZnw~t>x=byBhi-U*DZ7Me>FLytK=TCPx*W(LL9X)nb
zT}6%Yt+$`2uebZu(-w&+(C!uBoA=zPYir&dI{FVv4=9qpRK1
z!^{2i<=ra2`OmP({4{0dz
zm0Xkxq!^4049#^7Omz*-Lk!KV42-M{&9w~-tqcq<-_Ce|q9HdwB{QuOw}wS+7h-@K
z%t1C3=ckpFCl;kL=$953>F4ApC+6rEX8;BCQ}UDbJ#!P&Q+*TDGn2D*&Gq#&^HNeP
z^fF3vb85$!EpKi-TG*1z~)(5d8B5h
zXOu7)8yM7x*2e+Wh$EQ;RTG|>Qj)=7YGCj>Gk7CVi6oK|-^|?9lFEWqhD?zA^oz^V
z_rEXjLo>%W1gMI^(8SWzz!(V3o2Q)111b?fGAB5*3K*`2mQI&@YaavUG?C;&gFG41
tGILU`^!1BU(=+q)bklMY(~Cit={vdT0V&=-9xI?G22WQ%mvv4FO#u3av6=t?
literal 0
HcmV?d00001
diff --git a/res/flags/BE.png b/res/flags/BE.png
new file mode 100644
index 0000000000000000000000000000000000000000..555ac8bb743cc4a22bb621e39e5dd882dc0d96a6
GIT binary patch
literal 689
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&j3?%D+y-WjAEa{HEjtmSN`?>!lvI6-E$sR$z
z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`PI6XFV_@87=2F8*gzhDN3XE#6=GbVYvyD)UH%6b4foCO|{
z#Xvd%j6Y;Mod+`5OFVsD*&nhB3NQ(lYTEDug%mwq977~7CnqdW6KG*%GzjDs%yho^Qwi_cj0%Sx;Mrm%6
zm6c0=a%paAUWt`e08mpggW>Z3yYjhR3eF_#5XfHwWP8jl_3-4KKbMinrO(eO{AWw$0%$!s!ef^@;^vwJ`-L#y<^kR@@
Z`cAHTK+52qDk!2DJYD@<);T3K0RXgX)${-W
literal 0
HcmV?d00001
diff --git a/res/flags/BF.png b/res/flags/BF.png
new file mode 100644
index 0000000000000000000000000000000000000000..5a80be2aaad75c37e946cda3af74a98f1b2e7f85
GIT binary patch
literal 954
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lsFmS6XFV_@87@wURxIn
z(m@r})P1k3`#D+-NWKTMwRJyff{~W)S2xXXSt>u*NCQbA`;!((ydu@QJOzX*>&=fI
zQ2Kva1V{qeKoN!oo)E-1-?MXBqw4a`cF*%F-pNDGO^h%#mR^p{=2%xq8K_lg>XAEK4~qT)1-S+QqAvuQz-;
zSi}~Pkdcy;l$FN!c+rW-h^WZhH*O_P-E3}9U|>*iM5~=mW71*a`et?p2JKZUKVp}3
zYy&z-wZt`|BqgyV)hf9t6-Y4{85o-D8kp)Dnui#gSs55v8JcSw7+M(^T)v(007XM?
zeoAIqC2kFi+AhQZHJF2JD9%qSDNig)Wza7zF4E7*PfpCyFU|l8=%?f->wD%VrlzeE9XXd4(R_JAv$zRRB;^F@xdq
z|GV|k)PT*ivhqmHOwTA`Ff%Zyy0>>LP>nc}IZ!p>nJFb143-84kBV1a1uBt5QsSGL
zn_5y?kjjt=a-V*2S^EC>1%7De_=W&gF&LUyni?1bfqC!lvI6-E$sR$z
z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`zU6XFV_@87@w|Ns97
zpWewYu4kB<%P=jEVS2t)NAeyM*&C{Y*VKf7YM6@FJ_1sVB|(0{3=Yq3fb3>W@^*J&
z=wOxg0CG4BJR*yMbOIQE$aXppWU!Zb`ns||WEB)(5-ioU;ROo$db&7zm0Xkxq!^4049#^7Omz*-Lk!KV
z42-M{&9w~-tqcq<-_Ce|q9HdwB{QuOw}wS+7h-@K%t1C3=ckpFCl;kL=$953>F4Ap
zC+6rEX8;BCQ}UDbJ#!P&Q+*TDGn2D*&Gq#&^HNeP^fF3vb85$!EpKi-TG*1z~)(5d8B5hXOu9Q85mUE+q)IJn()k&k_-kz
z0|SHOCX4KWY9x{D^3BXmEvYO>Wyl0MP`|h=egFFcKcFIUWJMuBRSbqEmZk>AKw#cH
zNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lxPX?32_C|_wV2T|NsB5
zr_WzbnR~+}CFGqGRtE}xzjg0vW6yPKp9_+@5H*-0P+eDV
zz;!`IE?)=PGI{O|XM`<42XJY=hyYTIB|(0{3=Yq3q=7g|-tI089jvk*Kn`btM`SUO
zP5|Q%*-qzy4E7RFUsv{rtbzhef~A@^yg;EyPZ!4!jq}L~5-tsb<_QTYOw4IwVP<7~
zeklx7A3sVj0%Sx;
zMrm%6m6c0=a%paAUWt`e08mpggW>Z3yYWyl0MP`|h=egFFcKcFIUWJMuBRSbqEmZk>A
zKw#cH+oPSicL25MsPboFyt=akR{0KO(#FIo
z7OhP(h~pAMhE*tPDumkT;+{*XQ~R@L|FE62?>X=HeBb*%&+~rgeCNyb@p4mB)>Q@o
zsF8>SKN$5ka;qY|W)Ck1z_5koLUsW_az^D7O#wa|(TRR!01_+!IFSaxI$S#O3V>(`
zfHxrk;PL^`5)?N1I>8OaP!Bf(jBtE7+?))9l7JW}gfZlwTnNVxz#F89M0Q0^Drl%9
zG@|!9sR1BgP9nHah|<}-ac_T?{;A7rg`pl+!*aZ`LDjzYEVb3t>@0E$zzM3&xxLzV
z^-5mgUq+=bAn#T;>!3%owEVR_9BMNBOH!1~=uHJFV$}VfGa=y|rU`+~8HkVdePt%p
z_N=!$IK5gpFYJ$Z9!EOVoV7RUmP%iKQLqCHCNm|i@w4$<(yD?A)y>7-CvU}jI9eSc
zob)JdsLu^*-Lb{f)3d9!a!*2LQ`V2Rng)cqQS-Q(^94iW8U@=-b}FRB*%I7KtIkhU
zpIu)>J{Ic|dpxDh`^gP!PB+tQv@5%Y4h8#d`#82T6L~b((qVByrh#ztUYO`GU%mt3
zeRG@AeFD;MpU66LR-EobDXsd=Ojk08>P%uA{wn(+%oi2eFOyQ~-^WeyG5Io`)C&o^
z_e*m~_I?pog+78i30NR29lFq*OY$8
zzkK%Kr<}3R;>(E6nOK>Bk#Ek!0HyZP$A+Foa|~g*%Deh$NvnVF$=y>~Yl)vON}Q%8
zyid}D)@=jXjhE_z`K;R89V0oKfE(DDKjJJsm#5j5Y#CSZ=P>R~
zGPD>M>m{#7Vk*-s>oC~~RGZ_qZ;05Z&v~K?w=zR9@*yNItvMvkV^SrPspV(aF`kjbD6ESi0C?*WR7Q$d{AbT4OmV$A>LAE#y)(XPlAZTcW
zJ@Fp_kI&$Q#s9ycBz-Ul7GO6f2>D^6SXvYlpreIRXfB^l1Yy<#$u9b
zEDk-~28%{>A{fj#6kEjOCdP=XU<>UH3ko}$7mC9X`1EKVGeU&J`M@F}z+C;(jQ)!A
zj~@<4WO7(+5wL@x#9hh3Fh^^X&%YchhaqAEdkA{V@t439olO)nhsPAf3z&ejaX+*$
zhSfGN@cPP!Oo3Sdv(M2UvV#Mgn%5rzQ`9&4_;V7Nz|jH156V$daBuIXUVtA7gmJh`
n92y|5
literal 0
HcmV?d00001
diff --git a/res/flags/BJ.png b/res/flags/BJ.png
new file mode 100644
index 0000000000000000000000000000000000000000..13fa3c91e76b9d58cac653e13c7098f7da88acd6
GIT binary patch
literal 777
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5ln4*-32_C|_wV0lXb%J;
z&MyDG`&Iv668&>g49Y#I^8c#npDSQ)oBy^l-EW18p9+vYUs^Xk6f(}i;N
z%wF^Byb#m{n)!mI2xK>7NswPKgTu2MX&_FLx4R2N2dk_Hki%Kv5m^kR6TtXGw$pha
zgT2Jl*OmPttDpdrV5z1JFHp$E)5S4F<9u?0ginK@IKxRpM+ReVZE0&Ei8Vzsb7Jn;
zcrZlvP4AC)5a3ie&B@u_(WS_kVp+)PshO!_@Z!mbBljOLGNkSksEypTu?c9NYKdz^
zNlIc#s#S7PDv)9@GB7mPH89mRG!HQ}vobKUGBnpVFtjo-xO_X~0g8s){FKbJO57S2
zwOxn-YA^@cP@JDuQl40p%Aj9bT%@0qpPZPZUz`CH&`-%v*7wX!Oi%SqOwUZt)-~7H
z&&*3nt9VJXkcJ)skRQ71W*iuDhkg`Dal|kG&L|d_&?zannAvqxv3?U1*r^~
zAQ$Qvm!>MXBkT`FXl&If?1TAj|Zfy!3$7rhS{DftnaRUHx3vIVCg!
E0B~dPPyhe`
literal 0
HcmV?d00001
diff --git a/res/flags/BL.png b/res/flags/BL.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e50a79605926e8662a0e344de52b925313125a1
GIT binary patch
literal 692
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&j3?%D+y-WjAEa{HEjtmSN`?>!lvI6-E$sR$z
z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`PI6XFV_@87@Apgfg9
zesWad?tlOOgTTLkpG)iCs+zskv;-=+$84Ynq!>$r{DK)Ap4|Xh%$Vfu?!wT)D(eB{
za29w(76a)7F#eG3bRNiHFY)wsWq-&jD8M9Gs%gUu6jJeYaSV~ToSd*gE1PyI-n5}
zAR|IDN^_H}tX%SwOLJ56O028`fSQUK4441kt&gS#Y@U^sM`~tzMhSzNfkD;1y<355
z#F5N_stM0bDal~4G%$Enyy_}Yi6oK|-^|?9lFEWqhD?zA^oz^V_rEXjLo>%W1gMI^
z(8SWzz!(V3o2Q)111b?fGAB5*3K*^?mQGjQ_HzK`G?C;&gFG41GILU`^!1BU(=+q)
ibklMY(~Cit={x!80V&&m?!SSW7(8A5T-G@yGywo^Qq=tb
literal 0
HcmV?d00001
diff --git a/res/flags/BM.png b/res/flags/BM.png
new file mode 100644
index 0000000000000000000000000000000000000000..53de7c39b26a36e8db2e7ae4d0202ba86a72fcd9
GIT binary patch
literal 1601
zcmZ`%2~bm46n$Fvjx$1#MJXz+VhG_U2&8@iLj)nR1_DU5n(b#10+fU$$dUrp1X@?&}o-^+w}a^&Y(I*DMo4wM^(4;0eI3g7<&pEQkJPo^MD104du5P-Fw}7KRiv
z03?tAc*O<)Ee60MPF>G%17PWmV1K4J1dNP~JV-8hcCB8as%{*
z9odbuhxjftLaQaQ)ylDT0|Mo)mE%2ghXtOY-Hd+s;68W8fM@8Cd(ac2XOFehkVo*K
zM{vJeP@e~5a5uwX?*V!AIQ!-;&JW5i4>UGw!Xj%vl?}GEHAs>=-|ZF7R;Om&>eK4y
zDsDIDU+GRe)$hS*tLhkQc{HQGav}55Vey4iC?DM{)-DgfTd!J3>oJ3hVU6SI
z7&{_2I8Yb%YQej8l$RG}gmR^<1DSb6$CYi0aQ(yjxv%R&f$5T}02494h@JwE8gi(98(v!4Yb0h|d0bjpT3=9HC;*wPIl*>Qxh0f|Y-$*Ic?04sf
zC|Wl(R?6rB-YdtJo2*-El7M$x3u`{4dwDXqck|emwh9vpo6YA6I2dnwbYgsJZ1RN#
z6_lyVPTo|O7uRK9Dy+)Arf$rD|YjL-+f1
z&zF2OJu~s$_^YYcV=pJ?Ud&E!T4!lyZMwnSX36OjxjFf&yc0pb{`&&y0e;=>U7fm)
zM-LIuvEF=rQQ_G$5zO$gena0AinFUrZBsvd2wX?j_Anp}*sa=lh
zp2~l+P)wLRvKsj>Z%-1!HLNDVT>Z}*U1NqCvDuorUDWuc+u75aXGh<>9?lpY-Qs_z
z)hFL(SNixwMX!)FsVm);F*bhrVT9&TYay;K{l(Pv;iT8kaavouxcQb=pMncxDm$BF
zs{qjIqRy87@?#c!!L2gy{W3mBhM~N83@YG6B2$PY7b2O$B)g&{CzMPfkjN;B)H^I1
z{ab+~mM<2_|G(hkG5tYUKrwcZ#tLLfoOlc%3DS5ZI+n+YMx-JbK=`pdgf8I-u>g)x
z%!?vY5JViq$C4dIGD&o5Vu=P)SQ;sqq67&SMZIEq2@)(uhN8i+ND9bb&o?0dz`Wx_
zQD00f6v==qiInoZsrtV$5n{ef1jtS#Qrpc$2EJ=cCU^00e2E@hz5ow~Z`TMv)
z2(nlVVnP%kJMVNM?SLO8t56pMA*PEUq2d$_xWGAFY5C=MSHmoRQ8p}u4g}(83`LN5
jOel_xAqt{7LaDJGLJM$&3Y5n9!6HES4)oH{*qMI-CohOk
literal 0
HcmV?d00001
diff --git a/res/flags/BN.png b/res/flags/BN.png
new file mode 100644
index 0000000000000000000000000000000000000000..3ed976ebff6e2d310f0401e72a80a0d9c88944e8
GIT binary patch
literal 1599
zcmZ{iX;4#F6vr=M1X;uY$s=rov^qqEBp67OVHbp0pbEhi8DjDhB7q=z!KG9Imyv#`
zIE4-(Ri{IzosMOQMOnnk2L?J;1nU;6NPs}Xjv2|zLPBqpaj>1fIrpA-@BN+sIrqF*
zwL2rl!`06f0N}w*P0EDc-#%QN;N0Q5Mhx8=aYA|m0Ln{lOMC)c2Mba&(*ZcO8G!P0
z0GQ!cxefpY9e}Ak06293AjJ(Gd!hkwyskD4ZujH6Us?e`9YFlhxIS>c!MkIiOXu$i7OEh;VZ=S`D`jN@#4
zBm@e+eT*1h!4POG{Pgs+#bQ~unQcp2oB4rx=IT^kvSBdAI6=op0_<7-Q&M<%cveM>p_t&k-`(8{fE*XEEeKNn8Le&`tFG)!YkT|9
z(9q)IqHzQ$fXEvKZ^c-rMp{52gYmk`^%9CBef2W2#PYCIY+1MEs
z6yvv!VE>oE`t|FnRBBpU+WSDmD@5NznQ!x(z3IPj*Y8aaMb$-Wy0)RR)SZ{+vMqEC
z(bLhv0jy*hMetF?IA))r*{=Z8jUjJeBbt6vZ;SW!YR_XL*QD6BpKf&esIW0)Nn_{d
zROG>KpJu$p@OwnQSK9AKX$ByU1V*^vs5^ssXccfMiz>ZT_Bef=m`>*}u@+JErC*>S0Kb|x?&
z;a0|@@TQ`gu|ot{!M!xcJAZ8%A
zmdWj+NA)q{xlWTCIsBk|&DcclEo@Lv+Pd%8+}}!v%pU%%ifyV+bULazz*jn~l)spZ
z`4XRvD_$5F`6Q)6@4}uF^nTG0tuQ|vlxt}@otWvtvx3wTda<>q?@;Uft9!?<6J^ov
zL;wc+3M%IOTV=4Fo3P~ln2?X596<>R9f+VaSYh*-Xxu`+7)|Gk
zC4z!57L6t;5~3%<^RYr{S!sO}l<>7n@bVRfM>w1$nLts97GWIDZWts7jGvb8(*DJ~
z)8lYbQHeMo1FQ%-cgt;ve5A9&?2`zwe86Bb>5Y5(wUD8#%9SoDM6r{_D3I6-q{&Og
z_vec`3}{_^{5_JSu{S*D54Satbz<8Np;F9xh$zg{Rb2r`efYAd*N?
n4vkiViY2n5Fp-ommfO?O5;MY~ONsTl3WESQIU}hlF|YC;o&>`f
literal 0
HcmV?d00001
diff --git a/res/flags/BO.png b/res/flags/BO.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e20ea8cee8a5447c0dbc999370aefd513dd26bb
GIT binary patch
literal 733
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&j3?%D+y-WjAEa{HEjtmSN`?>!lvI6-E$sR$z
z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`YL6XFV_@87?FRa@?=
zmfTH8sjp{Qem-IN`IzDN6NcN@*yP&u7%EH{DoudOR0>{n04c_jAirP+hi5lH)-xt~
zySp%Su*!M>Ih+L^k;Ond0gOLnJDmqI*h@TpUD+S93JNd@mTKDY0)^Z>T^vIsE+;1}
zkV_D8VPI4U=Vat4?iFM>QtHScU@pSwaL0s&q3|?N;H?9LK)D)I!;aMg3`g$vGAO*0
zWKlTd`c?lc1H+7^{@%U~$-jXns+PD$l%yncptHiBgQQL(Wpayf04aNCsCFO}lsSNt1#YOr#`N@en
z`o$SQ0sWNxWPQ)v#Pn3(#PrPMY+ZAG{mi_S)C#?flH8n{vRUhZMo55+2+1hTO|r6b
z$xklLP0cH@vI+odDrPWT{(rYVni{ZqR#qOVnduoN4CbZ=Y}v}kv8xHsOex7=Ff=qU
zIQH!X2T+Y9l3l);xv3?U1*r^~AP4Ffm!2R2nn-e?L7oh0nK`Le`uatw>6!U?x@kFy>BS(+^qu_m
VfK*kStu{~-gQu&X%Q~loCIGg7+WP!lvI6-E$sR$z
z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD4`PI6XFV_@87?_PDW#`
zl-dq+r>{?*{{R2~$;*#6F*D^|yA<8JfeIXMbjt!M#*!evUJxFbS4w+VBE}+&on4Uihdd1?7N(t<91}byME5bYI^?l4nK11%7EDl@u$zlfOz6p?
zU(>4?7(CB;ir<`bHxFo{YKdz^NlIc#s#S7PDv)9@GB7mPH89mRG!HQ}vobKUGBnpV
zFtjo-xO_X~0g8s){FKbJO57S2wOxn-YA^@cP@JDuQl40p%Aj9bT%@0qpPZPZUz`CH
z&`-%v*7wX!Oi%SqOwUZt)-~7H&&*3nt;3REJAq{KHfH?^d)AeA8#Wt@QPaQqwc@^K{d464Q%8mgzeM>H(>x
TeIh4-nixD?{an^LB{Ts5H&oqe
literal 0
HcmV?d00001
diff --git a/res/flags/BR.png b/res/flags/BR.png
new file mode 100644
index 0000000000000000000000000000000000000000..7a2bc17adcf2a83ad69262607751e202dfc1247f
GIT binary patch
literal 1612
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`(RAz$e5NsNnwn`wX+K
z5NH+>8!XN|$5M8&F_1*4fvcZoEwRX?^Ptqd8*D%l$Yz*jjiPLp71JC`?+qFU&+uQ|
zC%SvB!liwpKsHbWD9(Uk7f?IUuKq)kH&5|o6}kwULxyA9rT7dB8Pv*|G|D;ktCT(4{K{s9RZcp;Uk)e>Q3g~G)CD&IXxcQ8?aV+0
zw~q;`I_I(J)-Y>Ua2wPxsFyKoRR!iXy}c$0)C*JtREcam$dFkGzXSbPRO!s3UCpdj
z$*Nt+rd!QpSYJ`+_UA56ze7xrS!@CfSYYtxl(+zcnq8+@(kj2G(gPCUKv}d91I8LS
zPBjml;lH#W6sN$L1+u+2XyS@fV8ZACClVluC6N$LX0SBLz|gogX%{fnGL{7S1v5B2
zyO9RsBze2LFm$lWdH^|`1s;*bKso`8KV&JxFbS4w+VBGP=z6+1
zhG?8mPLK#`5VUSMVd%(U%&jeL&2BuUUFrDAqh}AFKCZ9Op{TB+qok##r>Lo_tE}Ck
zrLMky!HOko7Oh&gZsE$MYnxS;uU?*?kdcy;l$Dm3n3`s+t?n*vuE&oYJF2dtrn-E|vZd(`PmMNjDlYo`iJPmt%iHVp
zDQ&IQtFp5e7L|VG?e#sYyEgZ&?A+M9wtH*;3aj}wo${S$RC?=+q;dM$dB)}U{;+b3
z>&9&=xmh&BI($vc)~d6&N?)7j+}Toj`daSo@;5P!Pxi;|{{H6f_WuVCI=A=B*p~fa
z$=Wf;ru5gDo5j!dWA>E%JQdpWVNcoLV`rnczrVA$U3JaOclH%OUVNPVd&S2F^?z)@
z;IjUnu{B&=9$45gsFt`!l%yncptHiBgQQL(Wpayf04aNCsCFO}lsSNt1#YOr#`N@en`o$SQ0sWNx
zWPQ)v#Pn3(#PrPMY+ZAG{mi_S)C#?flH8n{vRUhZMo55+2+1hTO|r6b$xklLP0cH@
zvI+odDrPWT{(rYVni{ZqR#qOVnduoN45kJq^Hb>ldY_XXfYWrsX827lUlmcM8%2QjhfV
RB!HS2JYD@<);T3K0RY1BM6dt=
literal 0
HcmV?d00001
diff --git a/res/flags/BS.png b/res/flags/BS.png
new file mode 100644
index 0000000000000000000000000000000000000000..2a152575c6b51d25fd7b0ce0794bc46f87db31b5
GIT binary patch
literal 1110
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`$r4;1l8sRB-?PeFh^d
zhNhVeYfdq&InA*8BoqPVghUy_QW<7#WmtQLVf875xUwcgVGF~u!whRt)w8lOSi3TG
zEMQ)9f_d#p#?>bv2xt-r2#RRO`*m*5S$d&((Yd09XQ2op$-=;3q0hZ?ist9*w*MbG
z`~xG9CVrMh6SaRobo%uGgisVuMJR@dGYE=;tk{9D0wfM`Rp&xvSAoPqzGy}91<1c?
z470YO_}9pqp&2D`>is7*0kt!h1o;IsI6S+N2I3@nySp%Su*!M>Ih+L^k;Ond0gOLn
zJDmqI*h@TpUD+S93JNd@mTKDY0)@7Ex;TbtoKH@WP-+k~Pe@2fN=r;letv+(!O~AJ
zPcF``jxndGY0ey{LrRO19tmYIEb*T-IoK=8EzB>@QINIaiN(|@mX@I*SFf0wY~3=E
zA);?`u>162|N93noVdZl>G0IT($~`R>=|91wG$XZ&fRLeeC^!5gBLlS=Wpg#U%q9yxjdAN1p9p@nXh}9Y0ud9!{DuWzM8oZMHTa
zj~o_YWZ3sl^PSgstvf&usFt`!l%yncptHiBgQQL(Wpayf04aNCsCFO}lsSNt1#YOr#`N@en`o$SQ
z0sWNxWPQ)v#Pn3(#PrPMY+ZAG{mi_S)C#?flH8n{vRUhZMo55+2+1hTO|r6b$xklL
zP0cH@vI+odDrPWT{(rYVni{ZqR#qOVnduoN48{fqHKO%#KsDk>=0MeiXQq^7Fqjz_
zywraS%x4UeNJ@M&b5lzy3sM;}LGIHpE=%A4zQ7O79N!S2Dh5LnOH%`5ATV#9axM?3
zL;%U0;LIvuxSAO|>F74U0m^A2$%O`aGNfhZq+03g7p10W=I80Ag05vgqy85}Sb4q9e09=iDtpET3
literal 0
HcmV?d00001
diff --git a/res/flags/BT.png b/res/flags/BT.png
new file mode 100644
index 0000000000000000000000000000000000000000..4782cf34a635ceed016635320705acc2f61ca1f1
GIT binary patch
literal 1608
zcmZ{i3rtg27{?DPVQNrtAou{vd?G2gdx!m)AAEIu@|_>pKN0M}2>wX&Syn!t`tK>^si5`f}T04#8;
zSPMWt2>?A409qLUUb*KQlOq6_QJ)mgh=G7Yp}^#X|8Cs`tcQR#`Cvs0rvX1qKGl3D
zCj@)D`JTP>@H0D3v6+HNq`L1WT<@qL?JkZ*Wm|G+5`@FH_1vr*4Mf#1)
zsY89o^{Nh|;q9QlU-znhr2qU#dEP|YHyG-UW1mPoL$iFHQT0Hp)#y~+gNh#AojPNE
z#Ya(uJ$d2ha+&cYyJJd4GmX@yV^(3A8>^2a{u@JKWR0ub#Ih!Cy7C#?L^sq1kP0d$L1APlM;fhXXWS%;b2>(q5h(|DA809r@v8Y
zmTmf!JiK<)&AM~tgk*y~brHS^1Ht$3)NlM+u=zx~ZPyxGvKJON&r%roLGxzx2+KZI
ztf>(u218HHq3W(LR^n}Ec;L~e%8I(%cPzJ@6xq_J3w?DdCh)}Kr=N$TpXrwXpX-^b
zmN00XWGM-$;5+qm9=^zm+Z+v!I{U=J#q8YJbSbpV$v!NKdIBddGCCULGT`j)Hp4wX
zAi@=DR@0*+8LOYLncnfm?q1*#+24t`aO>KFc?m%|zPm!H>wk2L^k=yzlXuUi2Qa9@
zMd{Qc=a>~-&n;p3t_&(l6#MM_cK^(c%h+G1hImk=bK?R6SDl)>8=~56OXHn=Uz5j58kWHD$Sq^
z(~DxbTk=uy&ixzNsnWQ>sM?yAOMm{+RMl|pz`a)bsjB#}kdlAU^7U+Wb+1(2QGS~_
zQ28M4Owh)M#LVk?a($Snr$$k?`cbcNFvinq-T8s
z6KC%$I9m%{c;hY@f_!lnjTS9o=Zm>HG8!!jill&Cg*72xFq8ghv{_KudM&*whsYua1Qm+8vZ7or5aRhE(gObNcex2)_(2(v0_0F?
z7%2pPl#w#rHL{;Aw!v>6R2a;0d$2Gz7`x@`aKdA}^c8
bm*U}&C`J%8;+*oEPz2~P3DLDt%!B^|isSD?
literal 0
HcmV?d00001
diff --git a/res/flags/BV.png b/res/flags/BV.png
new file mode 100644
index 0000000000000000000000000000000000000000..991a6cd76c9dc9ca138a7bbed09cef9638f327b7
GIT binary patch
literal 866
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5l;{oc32_C|_wV0-udVxD
zUF%1F!HP{M7}V0UTUY;_KmWa^HdtKqor>Cz++3(s+v=Zl=e<`|f3L3jv$64Kef|G6
zt5wq?_{^{vz5
z5m?ASzxKx+&-Vt0h3lKy7#IrM1iFg-yDk9jR4s9hC`m~yNwrEYN(E93Mh1rFx(24Y
zhUOuLW>yA9R)*%<28LD!2A6MVJV4Qqo1c=IR*74~qP7b$Kn>;~8;bMOO3D+9QW^A1
zi;MJg@{<#D^ouiq0{SWW$@-qTiRr1niRqci*}CTX`k8qtsTFz|CAm2@WwX`+jgSBt
z5t31wn`C9>lAm0fo0?Z*WfcI_RLo$w{Qqu!G&NxJtgJjzGt)Cl7%U773LGZv$F3$k
zGo>Vh!O+ma;Mlhl96&XaNOt*V=BAcZ7Njy{f*hz{T$aB7eSsfPkvOuV5TGgsLla9=
z17jdCZ=P~452!={Nl9>KRVst2p}EtAn;BPta+*kTp+TMuX_+~xR{Huysp*;ddAeyi
fiRr~4%k-VX^njH3x)V2mnixD?{an^LB{Ts5n6?!lvI6-E$sR$z
z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBC?Oi)6XFV_@87>)y6SfE
z%G*niKKAtV1d7DjdHVq=#*!evUJxFbS4w+VBE}%spKkLnJOICoGUl5OHC0SSQ4!G3k`48-ugLbyh~1
z#ybHl94tkb1r!8>#eDT=ot$DJbanp~W(KRjYQ~GX%t2PEmbgZgq$HN4S|t~y0x1R~
z14DCN15;f?^AJNbD+41dLvw8dLn{M=%eONgplHa=PsvQH#I0db+l3gABSAJ4=ckpF
zCl;kL=$953>F4ApC+6rEX8;BCQ}UDbJ#!P&Q+*TDGn2D*&Gq#&^HNeP^fF3vb85$!EpKi-TG*1z~)(5d8B5hXOu8l7#I{d
zOxTZIO?YNXNd|+Vk%7UH4P}8qHIhhn`DW&(mQ)s`GGu}rs9#)`zW;pzDC)$K6@>s*
zF&LUyni?1bfqCbP0l+XkKPQ1;x
literal 0
HcmV?d00001
diff --git a/res/flags/BY.png b/res/flags/BY.png
new file mode 100644
index 0000000000000000000000000000000000000000..40cdd8a7dd363d1210f8e72c2fcb8e0b87abcc7d
GIT binary patch
literal 950
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lsFUM6XFV_@87@wuy5+K
z1 xBM31J-e!g_|?aHQ;W+0KL^On3=wf=5H2SmZGlG+E|ldmS_KxFTC
zOt_I(0n%>b2vq!d>YOJt7u>0CfpVwMeX(-=otlYh7ML)4r>`sfLsmfnCc#oo8(yGLt*47)h{pNk1PP@ELGy%!l%%x8)a2t#4Mj3@V(!>j
zJgNBkgO#Q51Se;AN7us%!qX>AnRHB1U0GXweS@=Kpl773=yW^NQeIzO9fp+o+xphc
zvlC+|THd&D;zmv}hEMZX&fM9mD#pMiuAMC%ZLPx~GVdE-pP$8(4@V9QFf!ChsX92T
zdEEs%M76{2OC7#SFv>l&Eq8k&a~npqhbSs9vZ8yH#{7+k)c@c>0b
zZhlH;S|x4`i`p*405zC{Y$(o8D=AMbN@dV5EiTf}$xlwq(J#&b3h1ZgC+mCWCZ?zQ
zCZ=a5XX~2l>u2Vrq*mx|lMPg(!~
literal 0
HcmV?d00001
diff --git a/res/flags/BZ.png b/res/flags/BZ.png
new file mode 100644
index 0000000000000000000000000000000000000000..5de79b76302015933fdc454f9673127d60afd83b
GIT binary patch
literal 1592
zcmZ`(2~bm46n&x;m2oPx7F#P*L0n29iHI>@+-Oojg|UbtYHdPx$bux%1UE#Ms54>}
z17a*7ARr_P@(Eca$eIuc7(qdlAXQOh#I}mK%(O2;Q|e6r-1qK#=bd}*{r}zh$2Nxr
z&6@euOaQ>FkYHjs^z&?E`cyb;W=>;5H;uVIbUgs&>CW#dj&T1CH8?yJfP_T=Bqjs!
z7D9$!
zxGh+*cM&4lu=SWwBu_k?BNAPJYluL6oB-BJZMIGd)}+mk%-o-+x@x>$W6@Tb%bU9D
zD_ZnPh1cC9v*4+Xvo_6Ut5ZFqGB2pLN@HP3OK!%El;p}ir*wxaZBRBN8q}=lyla#fh~sm&AC&E+9&%4PzO$+G25K%#SLh+fu8e2rR+!Mb21Qqa
z_*U_*Ggm~Sqnq}e-Eiaw-*V}p>c*04vz8EZ(XI~yQkf^Op>2x3d+iS@k9QU_jGA1N
z`j;9dPeu=~NSEHe*ILm9X7Y(7{$QIZq!#F;A%swCPw*Rd$Z5KzFlJZC1+4n<2+uzh_j|C4Hm*W|gWH)ftQ>oDpp8l6Q|+gVfH-Y6|@fcW^e+FQkoAl|s`gg_)u
zK9VmGori0P*jr`1wf^Zh*mD2&8*ED#>*CqaO%aBNZ2{{ZcQb68=#4={Aa$G{3^z04
zf};e`lRu0Xv4QPy;Uo+RB{@BCbeZkoB3c?S3&vnWi0dPkv{T7*Hzm5b0VD3n6hCM0
zd8?cjyWv0eBZBXmogEImcSs7X^SBs2;Ceco>~dAUe73>RV)S0}?b6cX%O$a_mc-=R
z_#NwV75Sw_d@_s1iH>3LC^KA>Oi@w2-FJIdtwadgYK?mTHzrAfHr(b>&scZIO$k2&6vd1I7U
z+32&|{O)S@pE5;n)kyb@%&BQ6<^BDm&wCH|_vh6Iopk>`*?Hy5lQ}CTLod%=8#Mo1
zEq=PpBOvehxJN_iGd!7t$y~Izo-7LkE^&
zad;oBzYh){fm?xKmmxU3Hx`FrvA23z{r?Hz@@Z^_nl$dLih+v7h
z(Fj81Q$<`lPlzC!VUPgeivH4KKH_}PLy%xPo5>Oae=JsAq(LB
zv1hXd*^u((BuXfoOBYJw=zwjj47>)G;UR#*=FkxgCZ5h@^LaiD4uvVOrNad7@P*E@+p7l#
Nfe=y{Q5i^1`Ws=2pcw!F
literal 0
HcmV?d00001
diff --git a/res/flags/CA.png b/res/flags/CA.png
new file mode 100644
index 0000000000000000000000000000000000000000..68bcac99970681322594d1181388e5a3bb1bdf13
GIT binary patch
literal 1085
zcmZ`%S!fec6un(y+O$!FOA{B|s8(v7nc5f}+)@*pshu&VG47gek_=6n&`hco(OTDj
zDMUm<{i%u+7i_PN`0>
zo23H)z2LC9FwUmCr~v(dt}u+DFl-gA0KI2Qe)=?+&ks0UBEZ4L0PV*C#*k_s1xT>~
zSuX&80iZ0=HLzthK;B$ugWHaR;o)HdKqgHhckYnf_2UP*dzYZc_2C2Q=^^Fi)FVda
zzyO&xjT!<>QTgo~dGdr@xE{r%+K
zJ5o_WuY?{kGRS}bPC7bBX({E=5MYWVmhkjnzepxSii@csz!XUwm`ISeHWG_bj~JQp
zacU?S9Gt+I;=;$oma#Ef8XZNCZ)T)$@DqkS)g?8;`uDFxH1Th$v%zW2Tn8q_3CE5k
zM(>~fwW;<60<9{DcI}A9Fg4$hTDn?~RG(n8x+`7;yvBv?28-7l%+CwW^msfg=ZCcZ
znW0<8zB$^;C1sY%DV|lHy=xEWS(l9+Z}&f5*wF1?zjKZ#)w=3;ZagnYd#zgplPKA@
zihDMsg-yHawr!p#4n2BVGdFRBk&bXjQZYZz+v0Om0?r-ib{~;I5MU%s-kx^LXANE8&O=W|lp0p@4qu
z+&L4PZAws$0LQZIvzqR8s4?Z7B`PslZA-|Y&?^{
z96LAEj1ohRq)|CY71cGhtx`Sx`IhDsx4HxfDN&hcm=-y##G9)^QC~PoPh&P%mt&Y*
Q?fimGAlN0_&025AZy~S3X#fBK
literal 0
HcmV?d00001
diff --git a/res/flags/CC.png b/res/flags/CC.png
new file mode 100644
index 0000000000000000000000000000000000000000..13fe2b7f4d49db51cc475e1cdee7f1c4c53ab3c0
GIT binary patch
literal 1637
zcmZ`(YfMvT7=E~kq9pRe0E!OGhE{=dibAs!-2@@DaRmenBV0x)hqlsEY!3>8w4fsb
z3V1;ffecNi$Yo)RY%p=b#o-0U#(Ko<6$UZfgrzSFngbDrmYpYMH7
zPib^ygsaPP7XYpjaaatAEBI@n1NrWDaa54ts0fjU03DT!XJt-g?=2U{NP)e+fbjq@
zLm=ZMkV6C0sQ^<8xM$aQZ{Gyi_eFme7fuKxBO@>p9$-LL@Zd
z)d(Km#JRH=_=P{kvV#^6(T(W623-pRj$lDCT)%{aN&dP&`#bm&X2Yai#KYWO+-t_a
zx3H_lRM)^~BRO;1EVQL1ID7%?tE^THSaJZ;1`yoh(|`{SA+Hq`?bz`Z$nnkPh-BB(!AM=3uq+o70M7UcB=t$y;Xek?TWSiQF9r|R+K
z^wbKE<({W%>rN&bANaMkYSd4ktn_NAPfogfXY;0>i~9=xn|0WtD+=lLX_DP{JF@+E
zVaKk&7nMq`37S;2t
z-xH<%V(vicG2f_@jAmv@)t&x??iM26nW;pH`c$(;pPuJ35M*_!-)p@X<0fBfr#
z#Lleodza)B?RWEEJ{vZSjyC-q;azClTmEXYV|-0yBeU<(ldgZ<15!e($1fE;oWAf_
zly$Fr-^8=uriW3GibRZ)Xt*32vUGiHJ5s3H-
zdTj=`N2X&z<>+;kS}T{SDZP>aRJvA9Ni;GAE0rl!@=SjbMX9pV+1vmnr%@N|u4^YL
zJoprG${bA^!-Q$&IT|*LW0+_n(nEN5?nmk^jwv6*h*_0F$zcOc7c4WR5RSV|9t$U4
zmCh*hfuM1~akSL|p{)af`&PDsQfjqIr`mQ@Dxi1+6)@rez_x@MG
zj*T!g-D`>vGGj$D;$hyWeRmnaS7T}@gvn4C8WW08Yt@UZJR?}|=SRlJAXMOnkh}z;
zW!RGch)^z$&|)e=WF11bl6N$5!3gPBvZFan0L;(NqoTEqVJKhKEBb45i3-)xP|JSLM{T&$-d6
zc87}ZcPW;(DC>eY<&Pwdwf*JvnLvkO%l(79oknbEK;*vL($^FA>%`t~2Jxa#%FRoj
zZV?ODj1NsTP1OtL8u{+o%YQ}(TqF8#fS;=o|s%p)5yD+Qe7Ow3y2}x%;v}^V3C{+iT
z*+^lmc($i(5n^x)!%(sEA0`7GpjapwG&fjVb^X&}Xk%@oWT#1R4o6!2dM%s8o%VE$
zZBW4HX2-Pc3Utu%K-7#vA9OkcNr679B%r;}XPv^~XTc^&=@bQjAMU`U*b@YGJi}dr
z8^u+(!0p;91R+Yo(_VKyS$u2)I`qSIx^{6YDuRK^jT|FkVIql4mcpF6{yxqO8-~DG
z#)@GYFBn-_>RaV{2AcuLm&FL>cntGX?KpBPFL@t9T>Z4I)i)FwyW7$&Fj{nF${}`S
z5`(kb!^OwR)79I>%iW?Tfz65M#vM%%j*Z+Nn;e}Or{jK#Ui*eRRsHd#W687AcV>bP
zl7XG=nw$6MLV~+)ym9u=RRevcB0TJ?ZWrhGQ*%a%*3(Z+Dpyu{!JM!_4
zRYiBxy^CXQPtWyTSybK8ESL7U)t!(=WgdS$LYSC$M4Yl#Qc>e}q`uFvrXe7N>KRDB
z`e0yiKt(UQ+08s(tS;{LPCoWo)*t7t)PDTxLvBlQXLgA7#ktbAPBsLHXEdUqTkVc-
z-!1NaH0Li|Qg^NVPLtb}Ip;lQ|F+-~QRVou9%0V>`Tpf`;gCA0Xu;Xqx^(V?{>0{2
zIt!H*Cg&a0&-VEt)Sr_6(buM-anMm$88bdN}TPTp2ZVNwaKt>h7U|VWApC;39*>5jOMUZ#ot{Rfwuqv
literal 0
HcmV?d00001
diff --git a/res/flags/CF.png b/res/flags/CF.png
new file mode 100644
index 0000000000000000000000000000000000000000..6df7750774eaef306712db2f5cb3363b4ed269ac
GIT binary patch
literal 1124
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`&>(;1l8sRB-?PeFlRj
z5Ylf}a4F)qtO7EiB8JUTN{N>Rj4uh8Kt%L?vsTa2Zf>*}v8@0p(`{hTX_Rxy-?l)p
zv&DkRpq4?W0VJr~7_N|T1+39Cdl?Xg6fI1yo(V)gxl17;?zt;kTuLwVgAD)q>kk%Qmcmv}CL+NLt)FvRsSQ6wH%;50sMjD8d#zTknMCH
z$Y3w=^mS!_$SNqnBv`6x!wVET@9E+gqH+H0MOQwjKmnJ)J9qEO+PwpUP5*rbtp0j<
zOwddZ+j)4=#ebZCC%Y#bMCR~KKQ7MUnlv%sfcpiNpqViXL-yuo^@c4sm+(#NzM8gm
zhA+pgyAMlt+Q!Yd7vN!Ku9I(aYgN7&VdJP8{L;s2>Jou1IulQef77wuTJvG
zh~9ErzOVgnpHGH*$-bEU>!)X)ng8~5{r|^&!S4bV8_#sm0(wog#5JNMC9x#cD!C{X
zNHG{07@F%EnCcpuhZve!85mg^nrj;vS{WEzzMb&^MMG|WN@iLmZVijtF2n#en1gI6
z&QB{TPb^Ah&@U}6($C3HPR!9S&HxJNr{pK=d*&vlr}`$QXC`Osn(OOl=B1=o=w+1T
z=G2tUS_d>j0%Sx;Mrm%6m6c0=a%paAUWt`e08mpggW>Z3yYr(ax_zW;rJ
zADTJ7AwX3Oh9;J#2F5^O-aO@89#Dw@k~zVdRjCYS7M4!Ib{DOIa+*kTp+TMuX_+~x
qR{Huysp*;ddAeyiiRr~4%k-Vy^nlbJp`QOhO$?r{elF{r5}E)w)R)Zw
literal 0
HcmV?d00001
diff --git a/res/flags/CG.png b/res/flags/CG.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d37cd50a89eebdd39f6373333c4196c1793ad9c
GIT binary patch
literal 1539
zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ejmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`#@);1l8sRB-?PeTJ#d
zP&CCkWUcF~n_hqJdHsf<`(D4Ud%UhUfh+J??RxK;=imEC3T}A5t~I%z@DMYJf(8&3RR2d`Dg3jIr#dHX
zbbF1g_<`5YOYSdn41l&n5X4xZ%G6D6Z*L(P3sia0{Y92Ono6c=&Y4@>-XW_5IsmBn
zg8TDyEQ)ity1l=RWGq$NxI02S*AIc
zY