analyze and format
This commit is contained in:
parent
086dcae907
commit
8358dec3a5
|
@ -437,7 +437,8 @@ class KeyManager {
|
||||||
.deviceKeys[event.content['requesting_device_id']]
|
.deviceKeys[event.content['requesting_device_id']]
|
||||||
.ed25519Key;
|
.ed25519Key;
|
||||||
}
|
}
|
||||||
setInboundGroupSession(roomId, sessionId, event.encryptedContent['sender_key'], event.content,
|
setInboundGroupSession(roomId, sessionId,
|
||||||
|
event.encryptedContent['sender_key'], event.content,
|
||||||
forwarded: false);
|
forwarded: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,11 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'package:olm/olm.dart' as olm;
|
import 'package:olm/olm.dart' as olm;
|
||||||
|
|
||||||
import '../fake_client.dart';
|
import '../fake_client.dart';
|
||||||
import '../fake_matrix_api.dart';
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('Key Manager', () {
|
group('Key Manager', () {
|
||||||
|
@ -47,22 +45,22 @@ void main() {
|
||||||
test('handle new m.room_key', () async {
|
test('handle new m.room_key', () async {
|
||||||
final validSessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
|
final validSessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
|
||||||
final validSenderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
|
final validSenderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
|
||||||
final sessionKey = 'AgAAAAAQcQ6XrFJk6Prm8FikZDqfry/NbDz8Xw7T6e+/9Yf/q3YHIPEQlzv7IZMNcYb51ifkRzFejVvtphS7wwG2FaXIp4XS2obla14iKISR0X74ugB2vyb1AydIHE/zbBQ1ic5s3kgjMFlWpu/S3FQCnCrv+DPFGEt3ERGWxIl3Bl5X53IjPyVkz65oljz2TZESwz0GH/QFvyOOm8ci0q/gceaF3S7Dmafg3dwTKYwcA5xkcc+BLyrLRzB6Hn+oMAqSNSscnm4mTeT5zYibIhrzqyUTMWr32spFtI9dNR/RFSzfCw';
|
final sessionKey =
|
||||||
|
'AgAAAAAQcQ6XrFJk6Prm8FikZDqfry/NbDz8Xw7T6e+/9Yf/q3YHIPEQlzv7IZMNcYb51ifkRzFejVvtphS7wwG2FaXIp4XS2obla14iKISR0X74ugB2vyb1AydIHE/zbBQ1ic5s3kgjMFlWpu/S3FQCnCrv+DPFGEt3ERGWxIl3Bl5X53IjPyVkz65oljz2TZESwz0GH/QFvyOOm8ci0q/gceaF3S7Dmafg3dwTKYwcA5xkcc+BLyrLRzB6Hn+oMAqSNSscnm4mTeT5zYibIhrzqyUTMWr32spFtI9dNR/RFSzfCw';
|
||||||
|
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption.keyManager.clearInboundGroupSessions();
|
||||||
var event = ToDeviceEvent(
|
var event = ToDeviceEvent(
|
||||||
sender: '@alice:example.com',
|
sender: '@alice:example.com',
|
||||||
type: 'm.room_key',
|
type: 'm.room_key',
|
||||||
content: {
|
content: {
|
||||||
'algorithm': 'm.megolm.v1.aes-sha2',
|
'algorithm': 'm.megolm.v1.aes-sha2',
|
||||||
'room_id': '!726s6s6q:example.com',
|
'room_id': '!726s6s6q:example.com',
|
||||||
'session_id': validSessionId,
|
'session_id': validSessionId,
|
||||||
'session_key': sessionKey,
|
'session_key': sessionKey,
|
||||||
},
|
},
|
||||||
encryptedContent: {
|
encryptedContent: {
|
||||||
'sender_key': validSessionId,
|
'sender_key': validSessionId,
|
||||||
});
|
});
|
||||||
await client.encryption.keyManager.handleToDeviceEvent(event);
|
await client.encryption.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getInboundGroupSession(
|
client.encryption.keyManager.getInboundGroupSession(
|
||||||
|
@ -75,14 +73,14 @@ void main() {
|
||||||
// not encrypted
|
// not encrypted
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption.keyManager.clearInboundGroupSessions();
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: '@alice:example.com',
|
sender: '@alice:example.com',
|
||||||
type: 'm.room_key',
|
type: 'm.room_key',
|
||||||
content: {
|
content: {
|
||||||
'algorithm': 'm.megolm.v1.aes-sha2',
|
'algorithm': 'm.megolm.v1.aes-sha2',
|
||||||
'room_id': '!726s6s6q:example.com',
|
'room_id': '!726s6s6q:example.com',
|
||||||
'session_id': validSessionId,
|
'session_id': validSessionId,
|
||||||
'session_key': sessionKey,
|
'session_key': sessionKey,
|
||||||
});
|
});
|
||||||
await client.encryption.keyManager.handleToDeviceEvent(event);
|
await client.encryption.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getInboundGroupSession(
|
client.encryption.keyManager.getInboundGroupSession(
|
||||||
|
@ -93,42 +91,72 @@ void main() {
|
||||||
|
|
||||||
test('outbound group session', () async {
|
test('outbound group session', () async {
|
||||||
final roomId = '!726s6s6q:example.com';
|
final roomId = '!726s6s6q:example.com';
|
||||||
expect(client.encryption.keyManager.getOutboundGroupSession(roomId) != null, false);
|
expect(
|
||||||
var sess = await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
expect(client.encryption.keyManager.getOutboundGroupSession(roomId) != null, true);
|
false);
|
||||||
|
var sess =
|
||||||
|
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
||||||
|
expect(
|
||||||
|
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
|
true);
|
||||||
await client.encryption.keyManager.clearOutboundGroupSession(roomId);
|
await client.encryption.keyManager.clearOutboundGroupSession(roomId);
|
||||||
expect(client.encryption.keyManager.getOutboundGroupSession(roomId) != null, true);
|
expect(
|
||||||
expect(client.encryption.keyManager.getInboundGroupSession(roomId, sess.outboundGroupSession.session_id(), client.identityKey) != null, true);
|
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
|
true);
|
||||||
|
expect(
|
||||||
|
client.encryption.keyManager.getInboundGroupSession(roomId,
|
||||||
|
sess.outboundGroupSession.session_id(), client.identityKey) !=
|
||||||
|
null,
|
||||||
|
true);
|
||||||
|
|
||||||
// rotate after too many messages
|
// rotate after too many messages
|
||||||
sess.sentMessages = 300;
|
sess.sentMessages = 300;
|
||||||
await client.encryption.keyManager.clearOutboundGroupSession(roomId);
|
await client.encryption.keyManager.clearOutboundGroupSession(roomId);
|
||||||
expect(client.encryption.keyManager.getOutboundGroupSession(roomId) != null, false);
|
expect(
|
||||||
|
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
|
false);
|
||||||
|
|
||||||
// rotate if devices in room change
|
// rotate if devices in room change
|
||||||
sess = await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
sess =
|
||||||
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS'].blocked = true;
|
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
||||||
|
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
||||||
|
.blocked = true;
|
||||||
await client.encryption.keyManager.clearOutboundGroupSession(roomId);
|
await client.encryption.keyManager.clearOutboundGroupSession(roomId);
|
||||||
expect(client.encryption.keyManager.getOutboundGroupSession(roomId) != null, false);
|
expect(
|
||||||
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS'].blocked = false;
|
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
|
false);
|
||||||
|
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
||||||
|
.blocked = false;
|
||||||
|
|
||||||
// rotate if too far in the past
|
// rotate if too far in the past
|
||||||
sess = await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
sess =
|
||||||
|
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
||||||
sess.creationTime = DateTime.now().subtract(Duration(days: 30));
|
sess.creationTime = DateTime.now().subtract(Duration(days: 30));
|
||||||
await client.encryption.keyManager.clearOutboundGroupSession(roomId);
|
await client.encryption.keyManager.clearOutboundGroupSession(roomId);
|
||||||
expect(client.encryption.keyManager.getOutboundGroupSession(roomId) != null, false);
|
expect(
|
||||||
|
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
|
false);
|
||||||
|
|
||||||
// force wipe
|
// force wipe
|
||||||
sess = await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
sess =
|
||||||
await client.encryption.keyManager.clearOutboundGroupSession(roomId, wipe: true);
|
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
||||||
expect(client.encryption.keyManager.getOutboundGroupSession(roomId) != null, false);
|
await client.encryption.keyManager
|
||||||
|
.clearOutboundGroupSession(roomId, wipe: true);
|
||||||
|
expect(
|
||||||
|
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
|
false);
|
||||||
|
|
||||||
// load from database
|
// load from database
|
||||||
sess = await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
sess =
|
||||||
|
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
||||||
client.encryption.keyManager.clearOutboundGroupSessions();
|
client.encryption.keyManager.clearOutboundGroupSessions();
|
||||||
expect(client.encryption.keyManager.getOutboundGroupSession(roomId) != null, false);
|
expect(
|
||||||
|
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
|
false);
|
||||||
await client.encryption.keyManager.loadOutboundGroupSession(roomId);
|
await client.encryption.keyManager.loadOutboundGroupSession(roomId);
|
||||||
expect(client.encryption.keyManager.getOutboundGroupSession(roomId) != null, true);
|
expect(
|
||||||
|
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
|
true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('inbound group session', () async {
|
test('inbound group session', () async {
|
||||||
|
@ -143,20 +171,49 @@ void main() {
|
||||||
'AgAAAAAQcQ6XrFJk6Prm8FikZDqfry/NbDz8Xw7T6e+/9Yf/q3YHIPEQlzv7IZMNcYb51ifkRzFejVvtphS7wwG2FaXIp4XS2obla14iKISR0X74ugB2vyb1AydIHE/zbBQ1ic5s3kgjMFlWpu/S3FQCnCrv+DPFGEt3ERGWxIl3Bl5X53IjPyVkz65oljz2TZESwz0GH/QFvyOOm8ci0q/gceaF3S7Dmafg3dwTKYwcA5xkcc+BLyrLRzB6Hn+oMAqSNSscnm4mTeT5zYibIhrzqyUTMWr32spFtI9dNR/RFSzfCw'
|
'AgAAAAAQcQ6XrFJk6Prm8FikZDqfry/NbDz8Xw7T6e+/9Yf/q3YHIPEQlzv7IZMNcYb51ifkRzFejVvtphS7wwG2FaXIp4XS2obla14iKISR0X74ugB2vyb1AydIHE/zbBQ1ic5s3kgjMFlWpu/S3FQCnCrv+DPFGEt3ERGWxIl3Bl5X53IjPyVkz65oljz2TZESwz0GH/QFvyOOm8ci0q/gceaF3S7Dmafg3dwTKYwcA5xkcc+BLyrLRzB6Hn+oMAqSNSscnm4mTeT5zYibIhrzqyUTMWr32spFtI9dNR/RFSzfCw'
|
||||||
};
|
};
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption.keyManager.clearInboundGroupSessions();
|
||||||
expect(client.encryption.keyManager.getInboundGroupSession(roomId, sessionId, senderKey) != null, false);
|
expect(
|
||||||
client.encryption.keyManager.setInboundGroupSession(roomId, sessionId, senderKey, sessionContent);
|
client.encryption.keyManager
|
||||||
|
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||||
|
null,
|
||||||
|
false);
|
||||||
|
client.encryption.keyManager
|
||||||
|
.setInboundGroupSession(roomId, sessionId, senderKey, sessionContent);
|
||||||
await Future.delayed(Duration(milliseconds: 10));
|
await Future.delayed(Duration(milliseconds: 10));
|
||||||
expect(client.encryption.keyManager.getInboundGroupSession(roomId, sessionId, senderKey) != null, true);
|
expect(
|
||||||
|
client.encryption.keyManager
|
||||||
|
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||||
|
null,
|
||||||
|
true);
|
||||||
|
|
||||||
expect(client.encryption.keyManager.getInboundGroupSession(roomId, sessionId, senderKey) != null, true);
|
expect(
|
||||||
expect(client.encryption.keyManager.getInboundGroupSession('otherroom', sessionId, senderKey) != null, true);
|
client.encryption.keyManager
|
||||||
expect(client.encryption.keyManager.getInboundGroupSession('otherroom', 'invalid', senderKey) != null, false);
|
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||||
|
null,
|
||||||
|
true);
|
||||||
|
expect(
|
||||||
|
client.encryption.keyManager
|
||||||
|
.getInboundGroupSession('otherroom', sessionId, senderKey) !=
|
||||||
|
null,
|
||||||
|
true);
|
||||||
|
expect(
|
||||||
|
client.encryption.keyManager
|
||||||
|
.getInboundGroupSession('otherroom', 'invalid', senderKey) !=
|
||||||
|
null,
|
||||||
|
false);
|
||||||
|
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption.keyManager.clearInboundGroupSessions();
|
||||||
expect(client.encryption.keyManager.getInboundGroupSession(roomId, sessionId, senderKey) != null, false);
|
expect(
|
||||||
await client.encryption.keyManager.loadInboundGroupSession(roomId, sessionId, senderKey);
|
client.encryption.keyManager
|
||||||
expect(client.encryption.keyManager.getInboundGroupSession(roomId, sessionId, senderKey) != null, true);
|
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||||
|
null,
|
||||||
|
false);
|
||||||
|
await client.encryption.keyManager
|
||||||
|
.loadInboundGroupSession(roomId, sessionId, senderKey);
|
||||||
|
expect(
|
||||||
|
client.encryption.keyManager
|
||||||
|
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||||
|
null,
|
||||||
|
true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@ void main() {
|
||||||
var updateCounter = 0;
|
var updateCounter = 0;
|
||||||
KeyVerification keyVerification;
|
KeyVerification keyVerification;
|
||||||
|
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
room = Room(id: '!localpart:server.abc', client: client);
|
room = Room(id: '!localpart:server.abc', client: client);
|
||||||
|
|
|
@ -101,8 +101,12 @@ void main() {
|
||||||
|
|
||||||
test('startOutgoingOlmSessions', () async {
|
test('startOutgoingOlmSessions', () async {
|
||||||
// start an olm session.....with ourself!
|
// start an olm session.....with ourself!
|
||||||
await client.encryption.olmManager.startOutgoingOlmSessions([client.userDeviceKeys[client.userID].deviceKeys[client.deviceID]]);
|
await client.encryption.olmManager.startOutgoingOlmSessions(
|
||||||
expect(client.encryption.olmManager.olmSessions.containsKey(client.identityKey), true);
|
[client.userDeviceKeys[client.userID].deviceKeys[client.deviceID]]);
|
||||||
|
expect(
|
||||||
|
client.encryption.olmManager.olmSessions
|
||||||
|
.containsKey(client.identityKey),
|
||||||
|
true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -539,7 +539,8 @@ class FakeMatrixApi extends MockClient {
|
||||||
// },
|
// },
|
||||||
// 'type': 'm.room_key'
|
// 'type': 'm.room_key'
|
||||||
// },
|
// },
|
||||||
{ // this is the commented out m.room_key event - only encrypted
|
{
|
||||||
|
// this is the commented out m.room_key event - only encrypted
|
||||||
'sender': '@othertest:fakeServer.notExisting',
|
'sender': '@othertest:fakeServer.notExisting',
|
||||||
'content': {
|
'content': {
|
||||||
'algorithm': 'm.olm.v1.curve25519-aes-sha2',
|
'algorithm': 'm.olm.v1.curve25519-aes-sha2',
|
||||||
|
@ -547,7 +548,8 @@ class FakeMatrixApi extends MockClient {
|
||||||
'ciphertext': {
|
'ciphertext': {
|
||||||
'7rvl3jORJkBiK4XX1e5TnGnqz068XfYJ0W++Ml63rgk': {
|
'7rvl3jORJkBiK4XX1e5TnGnqz068XfYJ0W++Ml63rgk': {
|
||||||
'type': 0,
|
'type': 0,
|
||||||
'body': 'Awogyh7K4iLUQjcOxIfi7q7LhBBqv9w0mQ6JI9+U9tv7iF4SIHC6xb5YFWf9voRnmDBbd+0vxD/xDlVNRDlPIKliLGkYGiAkEbtlo+fng4ELtO4gSLKVbcFn7tZwZCEUE8H2miBsCCKABgMKIFrKDJwB7gM3lXPt9yVoh6gQksafKt7VFCNRN5KLKqsDEAAi0AX5EfTV7jJ1ZWAbxftjoSN6kCVIxzGclbyg1HjchmNCX7nxNCHWl+q5ZgqHYZVu2n2mCVmIaKD0kvoEZeY3tV1Itb6zf67BLaU0qgW/QzHCHg5a44tNLjucvL2mumHjIG8k0BY2uh+52HeiMCvSOvtDwHg7nzCASGdqPVCj9Kzw6z7F6nL4e3mYim8zvJd7f+mD9z3ARrypUOLGkTGYbB2PQOovf0Do8WzcaRzfaUCnuu/YVZWKK7DPgG8uhw/TjR6XtraAKZysF+4DJYMG9SQWx558r6s7Z5EUOF5CU2M35w1t1Xxllb3vrS83dtf9LPCrBhLsEBeYEUBE2+bTBfl0BDKqLiB0Cc0N0ixOcHIt6e40wAvW622/gMgHlpNSx8xG12u0s6h6EMWdCXXLWd9fy2q6glFUHvA67A35q7O+M8DVml7Y9xG55Y3DHkMDc9cwgwFkBDCAYQe6pQF1nlKytcVCGREpBs/gq69gHAStMQ8WEg38Lf8u8eBr2DFexrN4U+QAk+S//P3fJgf0bQx/Eosx4fvWSz9En41iC+ADCsWQpMbwHn4JWvtAbn3oW0XmL/OgThTkJMLiCymduYAa1Hnt7a3tP0KTL2/x11F02ggQHL28cCjq5W4zUGjWjl5wo2PsKB6t8aAvMg2ujGD2rCjb4yrv5VIzAKMOZLyj7K0vSK9gwDLQ/4vq+QnKUBG5zrcOze0hX+kz2909/tmAdeCH61Ypw7gbPUJAKnmKYUiB/UgwkJvzMJSsk/SEs5SXosHDI+HsJHJp4Mp4iKD0xRMst+8f9aTjaWwh8ZvELE1ZOhhCbF3RXhxi3x2Nu8ORIz+vhEQ1NOlMc7UIo98Fk/96T36vL/fviowT4C/0AlaapZDJBmKwhmwqisMjY2n1vY29oM2p5BzY1iwP7q9BYdRFst6xwo57TNSuRwQw7IhFsf0k+ABuPEZy5xB5nPHyIRTf/pr3Hw',
|
'body':
|
||||||
|
'Awogyh7K4iLUQjcOxIfi7q7LhBBqv9w0mQ6JI9+U9tv7iF4SIHC6xb5YFWf9voRnmDBbd+0vxD/xDlVNRDlPIKliLGkYGiAkEbtlo+fng4ELtO4gSLKVbcFn7tZwZCEUE8H2miBsCCKABgMKIFrKDJwB7gM3lXPt9yVoh6gQksafKt7VFCNRN5KLKqsDEAAi0AX5EfTV7jJ1ZWAbxftjoSN6kCVIxzGclbyg1HjchmNCX7nxNCHWl+q5ZgqHYZVu2n2mCVmIaKD0kvoEZeY3tV1Itb6zf67BLaU0qgW/QzHCHg5a44tNLjucvL2mumHjIG8k0BY2uh+52HeiMCvSOvtDwHg7nzCASGdqPVCj9Kzw6z7F6nL4e3mYim8zvJd7f+mD9z3ARrypUOLGkTGYbB2PQOovf0Do8WzcaRzfaUCnuu/YVZWKK7DPgG8uhw/TjR6XtraAKZysF+4DJYMG9SQWx558r6s7Z5EUOF5CU2M35w1t1Xxllb3vrS83dtf9LPCrBhLsEBeYEUBE2+bTBfl0BDKqLiB0Cc0N0ixOcHIt6e40wAvW622/gMgHlpNSx8xG12u0s6h6EMWdCXXLWd9fy2q6glFUHvA67A35q7O+M8DVml7Y9xG55Y3DHkMDc9cwgwFkBDCAYQe6pQF1nlKytcVCGREpBs/gq69gHAStMQ8WEg38Lf8u8eBr2DFexrN4U+QAk+S//P3fJgf0bQx/Eosx4fvWSz9En41iC+ADCsWQpMbwHn4JWvtAbn3oW0XmL/OgThTkJMLiCymduYAa1Hnt7a3tP0KTL2/x11F02ggQHL28cCjq5W4zUGjWjl5wo2PsKB6t8aAvMg2ujGD2rCjb4yrv5VIzAKMOZLyj7K0vSK9gwDLQ/4vq+QnKUBG5zrcOze0hX+kz2909/tmAdeCH61Ypw7gbPUJAKnmKYUiB/UgwkJvzMJSsk/SEs5SXosHDI+HsJHJp4Mp4iKD0xRMst+8f9aTjaWwh8ZvELE1ZOhhCbF3RXhxi3x2Nu8ORIz+vhEQ1NOlMc7UIo98Fk/96T36vL/fviowT4C/0AlaapZDJBmKwhmwqisMjY2n1vY29oM2p5BzY1iwP7q9BYdRFst6xwo57TNSuRwQw7IhFsf0k+ABuPEZy5xB5nPHyIRTf/pr3Hw',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue