1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-04 03:48:07 +02:00

migrate push tests

This commit is contained in:
Jesse Duffield 2023-02-21 21:49:48 +11:00
parent 6b8abb7887
commit bfde06d049
339 changed files with 381 additions and 752 deletions

View File

@ -140,6 +140,10 @@ func (self *Shell) CreateLightweightTag(name string, ref string) *Shell {
return self.RunCommand(fmt.Sprintf("git tag %s %s", name, ref))
}
func (self *Shell) CreateAnnotatedTag(name string, message string, ref string) *Shell {
return self.RunCommand(fmt.Sprintf("git tag -a %s -m \"%s\" %s", name, message, ref))
}
// convenience method for creating a file and adding it
func (self *Shell) CreateFileAndAdd(fileName string, fileContents string) *Shell {
return self.

View File

@ -0,0 +1,57 @@
package sync
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var Push = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Push a commit to a pre-configured upstream",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {
},
SetupRepo: func(shell *Shell) {
shell.EmptyCommit("one")
shell.CloneIntoRemote("origin")
shell.SetBranchUpstream("master", "origin/master")
shell.EmptyCommit("two")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Status().Content(Contains("↑1 repo → master"))
t.Views().Files().
IsFocused().
Press(keys.Universal.Push)
assertSuccessfullyPushed(t)
},
})
func assertSuccessfullyPushed(t *TestDriver) {
t.Views().Status().Content(Contains("✓ repo → master"))
t.Views().Remotes().
Focus().
Lines(
Contains("origin"),
).
PressEnter()
t.Views().RemoteBranches().
IsFocused().
Lines(
Contains("master"),
).
PressEnter()
t.Views().SubCommits().
IsFocused().
Lines(
Contains("two"),
Contains("one"),
)
}

View File

@ -0,0 +1,33 @@
package sync
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var PushAndAutoSetUpstream = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Push a commit and set the upstream automatically as configured by git",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {
},
SetupRepo: func(shell *Shell) {
shell.EmptyCommit("one")
shell.CloneIntoRemote("origin")
shell.EmptyCommit("two")
shell.SetConfig("push.default", "current")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
// assert no mention of upstream/downstream changes
t.Views().Status().Content(MatchesRegexp(`^\s+repo → master`))
t.Views().Files().
IsFocused().
Press(keys.Universal.Push)
assertSuccessfullyPushed(t)
},
})

View File

@ -0,0 +1,35 @@
package sync
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var PushAndSetUpstream = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Push a commit and set the upstream via a prompt",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.EmptyCommit("one")
shell.CloneIntoRemote("origin")
shell.EmptyCommit("two")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
// assert no mention of upstream/downstream changes
t.Views().Status().Content(MatchesRegexp(`^\s+repo → master`))
t.Views().Files().
IsFocused().
Press(keys.Universal.Push)
t.ExpectPopup().Prompt().
Title(Equals("Enter upstream as '<remote> <branchname>'")).
SuggestionLines(Equals("origin master")).
ConfirmFirstSuggestion()
assertSuccessfullyPushed(t)
},
})

View File

@ -0,0 +1,56 @@
package sync
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var PushFollowTags = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Push with --follow-tags configured in git config",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {
},
SetupRepo: func(shell *Shell) {
shell.EmptyCommit("one")
shell.CloneIntoRemote("origin")
shell.SetBranchUpstream("master", "origin/master")
shell.EmptyCommit("two")
shell.CreateAnnotatedTag("mytag", "message", "HEAD")
shell.SetConfig("push.followTags", "true")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Status().Content(Contains("↑1 repo → master"))
t.Views().Files().
IsFocused().
Press(keys.Universal.Push)
t.Views().Status().Content(Contains("✓ repo → master"))
t.Views().Remotes().
Focus().
Lines(
Contains("origin"),
).
PressEnter()
t.Views().RemoteBranches().
IsFocused().
Lines(
Contains("master"),
).
PressEnter()
t.Views().SubCommits().
IsFocused().
Lines(
Contains("two").Contains("mytag"),
Contains("one"),
)
},
})

View File

@ -0,0 +1,55 @@
package sync
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var PushNoFollowTags = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Push with --follow-tags NOT configured in git config",
ExtraCmdArgs: "",
Skip: true, // turns out this actually DOES push the tag. I have no idea why
SetupConfig: func(config *config.AppConfig) {
},
SetupRepo: func(shell *Shell) {
shell.EmptyCommit("one")
shell.EmptyCommit("two")
shell.CloneIntoRemote("origin")
shell.SetBranchUpstream("master", "origin/master")
shell.CreateAnnotatedTag("mytag", "message", "HEAD")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Status().Content(Contains("✓ repo → master"))
t.Views().Files().
IsFocused().
Press(keys.Universal.Push)
t.Views().Status().Content(Contains("✓ repo → master"))
t.Views().Remotes().
Focus().
Lines(
Contains("origin"),
).
PressEnter()
t.Views().RemoteBranches().
IsFocused().
Lines(
Contains("master"),
).
PressEnter()
t.Views().SubCommits().
IsFocused().
Lines(
// tag was not pushed to upstream
Contains("two").DoesNotContain("mytag"),
Contains("one"),
)
},
})

View File

@ -0,0 +1,59 @@
package sync
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var PushTag = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Push a specific tag",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {
},
SetupRepo: func(shell *Shell) {
shell.EmptyCommit("one")
shell.EmptyCommit("two")
shell.CloneIntoRemote("origin")
shell.CreateAnnotatedTag("mytag", "message", "HEAD")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Tags().
Focus().
Lines(
Contains("mytag"),
).
Press(keys.Branches.PushTag)
t.ExpectPopup().Prompt().
Title(Equals("remote to push tag 'mytag' to:")).
InitialText(Equals("origin")).
SuggestionLines(
Contains("origin"),
).
Confirm()
t.Views().Remotes().
Focus().
Lines(
Contains("origin"),
).
PressEnter()
t.Views().RemoteBranches().
IsFocused().
Lines(
Contains("master"),
).
PressEnter()
t.Views().SubCommits().
IsFocused().
Lines(
Contains("two").Contains("mytag"),
Contains("one"),
)
},
})

View File

@ -0,0 +1,75 @@
package sync
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var PushWithCredentialPrompt = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Push a commit to a pre-configured upstream, where credentials are required",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {
},
SetupRepo: func(shell *Shell) {
shell.EmptyCommit("one")
shell.CloneIntoRemote("origin")
shell.SetBranchUpstream("master", "origin/master")
shell.EmptyCommit("two")
// actually getting a password prompt is tricky: it requires SSH'ing into localhost under a newly created, restricted, user.
// This is not easy to do in a cross-platform way, nor is it easy to do in a docker container.
// If you can think of a way to do it, please let me know!
shell.RunCommand("cp ../../../../../hooks/pre-push .git/hooks/pre-push")
shell.RunCommand("chmod +x .git/hooks/pre-push")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Status().Content(Contains("↑1 repo → master"))
t.Views().Files().
IsFocused().
Press(keys.Universal.Push)
// correct credentials are: username=username, password=password
t.ExpectPopup().Prompt().
Title(Equals("Username")).
Type("username").
Confirm()
// enter incorrect password
t.ExpectPopup().Prompt().
Title(Equals("Password")).
Type("incorrect password").
Confirm()
t.ExpectPopup().Alert().
Title(Equals("Error")).
Content(Contains("incorrect username/password")).
Confirm()
t.Views().Status().Content(Contains("↑1 repo → master"))
// try again with correct password
t.Views().Files().
IsFocused().
Press(keys.Universal.Push)
t.ExpectPopup().Prompt().
Title(Equals("Username")).
Type("username").
Confirm()
t.ExpectPopup().Prompt().
Title(Equals("Password")).
Type("password").
Confirm()
t.Views().Status().Content(Contains("✓ repo → master"))
assertSuccessfullyPushed(t)
},
})

View File

@ -103,6 +103,13 @@ var tests = []*components.IntegrationTest{
sync.ForcePushMultipleUpstream,
sync.Pull,
sync.PullAndSetUpstream,
sync.Push,
sync.PushAndAutoSetUpstream,
sync.PushAndSetUpstream,
sync.PushFollowTags,
sync.PushNoFollowTags,
sync.PushTag,
sync.PushWithCredentialPrompt,
sync.RenameBranchAndPull,
tag.Checkout,
tag.CrudAnnotated,

View File

@ -1 +0,0 @@
ref: refs/heads/master

View File

@ -1,8 +0,0 @@
[core]
repositoryformatversion = 0
filemode = true
bare = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = /Users/jesseduffieldduffield/go/src/github.com/jesseduffield/lazygit/test/integration/push/actual/./repo

View File

@ -1 +0,0 @@
Unnamed repository; edit this file 'description' to name the repository.

View File

@ -1,7 +0,0 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store

View File

@ -1,2 +0,0 @@
x�ÎA
Â0@Q×9Eö‚d&ÓIDW=F:�`ÁX)ôöön?oñummé„}3ó%E‚2H ólV…ÅXêÄ‘32ψS¨HÀîU6{vŸ€†”$F£¬*‰RÈ(UBŚ͕w¿¯›¿�þ|¯ö)íõ°“®íâ�)GʈÙBp{ݧºýÉ]ûÖåaè~;Œ9

View File

@ -1,2 +0,0 @@
x�ΝA
ƒ0@Ρ®s�ΩJ&NΗ))Ές1™PΑ!")ΨΫΧ#tϋyπS5[ ρ¥ν�ΰ•Sρ‘ηώ΅’‰…³`�Xz�©ΛL%¦{pρΣήu‡q‚η8½τ�¶­zKΥ@&ιHBΈ"zοΞzN�ώΙ�}Λ²*Ί3�,Υ

View File

@ -1,2 +0,0 @@
# pack-refs with: peeled fully-peeled sorted
146ca480a776a466024a08d273987c4b2e71f23b refs/heads/master

View File

@ -1 +0,0 @@
69fef9300b95338821093ec2dfb6e2974d303510

View File

@ -1 +0,0 @@
146ca480a776a466024a08d273987c4b2e71f23b branch 'master' of ../origin

View File

@ -1 +0,0 @@
ref: refs/heads/master

View File

@ -1,16 +0,0 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[user]
email = CI@example.com
name = CI
[remote "origin"]
url = ../origin
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master

View File

@ -1 +0,0 @@
Unnamed repository; edit this file 'description' to name the repository.

View File

@ -1,7 +0,0 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store

View File

@ -1,4 +0,0 @@
0000000000000000000000000000000000000000 714500c4933e4316cc9747711829560cc42c2f8e CI <CI@example.com> 1648348228 +1100 commit (initial): myfile1
714500c4933e4316cc9747711829560cc42c2f8e 146ca480a776a466024a08d273987c4b2e71f23b CI <CI@example.com> 1648348228 +1100 commit: myfile2
146ca480a776a466024a08d273987c4b2e71f23b ee53190e06796d55bf236a35d45249c90eff8594 CI <CI@example.com> 1648348228 +1100 commit: myfile3
ee53190e06796d55bf236a35d45249c90eff8594 69fef9300b95338821093ec2dfb6e2974d303510 CI <CI@example.com> 1648348228 +1100 commit: myfile4

View File

@ -1,4 +0,0 @@
0000000000000000000000000000000000000000 714500c4933e4316cc9747711829560cc42c2f8e CI <CI@example.com> 1648348228 +1100 commit (initial): myfile1
714500c4933e4316cc9747711829560cc42c2f8e 146ca480a776a466024a08d273987c4b2e71f23b CI <CI@example.com> 1648348228 +1100 commit: myfile2
146ca480a776a466024a08d273987c4b2e71f23b ee53190e06796d55bf236a35d45249c90eff8594 CI <CI@example.com> 1648348228 +1100 commit: myfile3
ee53190e06796d55bf236a35d45249c90eff8594 69fef9300b95338821093ec2dfb6e2974d303510 CI <CI@example.com> 1648348228 +1100 commit: myfile4

View File

@ -1,2 +0,0 @@
0000000000000000000000000000000000000000 146ca480a776a466024a08d273987c4b2e71f23b CI <CI@example.com> 1648348228 +1100 fetch origin: storing head
146ca480a776a466024a08d273987c4b2e71f23b 69fef9300b95338821093ec2dfb6e2974d303510 CI <CI@example.com> 1648348229 +1100 update by push

View File

@ -1,2 +0,0 @@
x�ÎA
Â0@Q×9Eö‚d&ÓIDW=F:�`ÁX)ôöön?oñummé„}3ó%E‚2H ólV…ÅXêÄ‘32ψS¨HÀîU6{vŸ€†”$F£¬*‰RÈ(UBŚ͕w¿¯›¿�þ|¯ö)íõ°“®íâ�)GʈÙBp{ݧºýÉ]ûÖåaè~;Œ9

View File

@ -1,2 +0,0 @@
x�ΝA
ƒ0@Ρ®s�ΩJ&NΗ))Ές1™PΑ!")ΨΫΧ#tϋyπS5[ ρ¥ν�ΰ•Sρ‘ηώ΅’‰…³`�Xz�©ΛL%¦{pρΣήu‡q‚η8½τ�¶­zKΥ@&ιHBΈ"zοΞzN�ώΙ�}Λ²*Ί3�,Υ

View File

@ -1 +0,0 @@
69fef9300b95338821093ec2dfb6e2974d303510

View File

@ -1 +0,0 @@
69fef9300b95338821093ec2dfb6e2974d303510

View File

@ -1 +0,0 @@
test1

View File

@ -1 +0,0 @@
test2

View File

@ -1 +0,0 @@
test3

View File

@ -1 +0,0 @@
test4

View File

@ -1 +0,0 @@
{"KeyEvents":[{"Timestamp":916,"Mod":0,"Key":256,"Ch":80},{"Timestamp":2131,"Mod":0,"Key":256,"Ch":113}],"ResizeEvents":[{"Timestamp":0,"Width":272,"Height":74}]}

View File

@ -1,35 +0,0 @@
#!/bin/sh
set -e
set -e
cd $1
git init
git config user.email "CI@example.com"
git config user.name "CI"
echo test1 > myfile1
git add .
git commit -am "myfile1"
echo test2 > myfile2
git add .
git commit -am "myfile2"
cd ..
git clone --bare ./repo origin
cd repo
echo test3 > myfile3
git add .
git commit -am "myfile3"
echo test4 > myfile4
git add .
git commit -am "myfile4"
git remote add origin ../origin
git fetch origin
git branch --set-upstream-to=origin/master master

View File

@ -1 +0,0 @@
{ "description": "push changes to the remote", "speed": 10 }

View File

@ -1 +0,0 @@
ref: refs/heads/master

View File

@ -1,8 +0,0 @@
[core]
repositoryformatversion = 0
filemode = true
bare = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = /Users/jesseduffieldduffield/go/src/github.com/jesseduffield/lazygit/test/integration/pushAndSetUpstream/actual/./repo

View File

@ -1 +0,0 @@
Unnamed repository; edit this file 'description' to name the repository.

View File

@ -1,7 +0,0 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store

View File

@ -1,2 +0,0 @@
x�ÎM
Â0@a×9Eö‚d2?MADèªÇHÚ,[J½½=‚ÛÇ·xÓZëÒ<ôtj»ª�&ÐQà€)&* Â)#‹v yÊ܃Ûò®¯æÕ Éz•ˆ¨ŒÄ€¥P‰À4gÒyF�˜Ð\~·Çºûaô×a¼ë'×í©—i­7B )Åý wÔcªéŸÜÕ¯-O%÷×r8Ê

View File

@ -1,3 +0,0 @@
x�ÍA
à @Ñ®=Åì ÅÑé8…
YåFGˆ‚…ôöͺı<ø©Õºt@âKßUÁ*§b#Ïá¡’‰…³ ‹XÍä3S‰éîLüôwÛaœà9N/=bİV½¥V@&ñ$.x¸"ZkÎzNºşÉMı–eU4?3‹,Õ

View File

@ -1,2 +0,0 @@
x�ŽA
à E»öî ÅqÔ(„RÈ*ÇÐÉ Ä& ííëºzðx>íµ®MCr—v2k[`@Šqˆ’ŠäP¢¡X,ùNbuä“_M§!b0Ô­É ÀÁ¥x)Pßy†Â)X•ßí¹Ÿzšõ8Íþäzl|£½Þ5ÑE; ¾£ºí§ÿ™«ú•ucT? *:›

View File

@ -1,2 +0,0 @@
# pack-refs with: peeled fully-peeled sorted
978360cc5c0a9115bf3db5f10196cd135e1be962 refs/heads/master

View File

@ -1 +0,0 @@
d77ec09ecf2391f9b76e54de98187095cd2edf9d

View File

@ -1 +0,0 @@
978360cc5c0a9115bf3db5f10196cd135e1be962 not-for-merge branch 'master' of ../origin

View File

@ -1 +0,0 @@
ref: refs/heads/test

View File

@ -1,18 +0,0 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[user]
email = CI@example.com
name = CI
[remote "origin"]
url = ../origin
fetch = +refs/heads/*:refs/remotes/origin/*
[push]
default = nothing
[branch "test"]
remote = origin
merge = refs/heads/test

View File

@ -1 +0,0 @@
Unnamed repository; edit this file 'description' to name the repository.

View File

@ -1,7 +0,0 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store

View File

@ -1,5 +0,0 @@
0000000000000000000000000000000000000000 e0c356303c1b9b8fbe6acddb3e58f28b52348c60 CI <CI@example.com> 1648348273 +1100 commit (initial): myfile1
e0c356303c1b9b8fbe6acddb3e58f28b52348c60 978360cc5c0a9115bf3db5f10196cd135e1be962 CI <CI@example.com> 1648348273 +1100 commit: myfile2
978360cc5c0a9115bf3db5f10196cd135e1be962 eff34f9e6233e534513bb4b2154da4edd316283f CI <CI@example.com> 1648348273 +1100 commit: myfile3
eff34f9e6233e534513bb4b2154da4edd316283f d77ec09ecf2391f9b76e54de98187095cd2edf9d CI <CI@example.com> 1648348273 +1100 commit: myfile4
d77ec09ecf2391f9b76e54de98187095cd2edf9d d77ec09ecf2391f9b76e54de98187095cd2edf9d CI <CI@example.com> 1648348275 +1100 checkout: moving from master to test

View File

@ -1,4 +0,0 @@
0000000000000000000000000000000000000000 e0c356303c1b9b8fbe6acddb3e58f28b52348c60 CI <CI@example.com> 1648348273 +1100 commit (initial): myfile1
e0c356303c1b9b8fbe6acddb3e58f28b52348c60 978360cc5c0a9115bf3db5f10196cd135e1be962 CI <CI@example.com> 1648348273 +1100 commit: myfile2
978360cc5c0a9115bf3db5f10196cd135e1be962 eff34f9e6233e534513bb4b2154da4edd316283f CI <CI@example.com> 1648348273 +1100 commit: myfile3
eff34f9e6233e534513bb4b2154da4edd316283f d77ec09ecf2391f9b76e54de98187095cd2edf9d CI <CI@example.com> 1648348273 +1100 commit: myfile4

View File

@ -1 +0,0 @@
0000000000000000000000000000000000000000 d77ec09ecf2391f9b76e54de98187095cd2edf9d CI <CI@example.com> 1648348275 +1100 branch: Created from master

View File

@ -1 +0,0 @@
0000000000000000000000000000000000000000 978360cc5c0a9115bf3db5f10196cd135e1be962 CI <CI@example.com> 1648348273 +1100 fetch origin: storing head

View File

@ -1 +0,0 @@
0000000000000000000000000000000000000000 d77ec09ecf2391f9b76e54de98187095cd2edf9d CI <CI@example.com> 1648348276 +1100 update by push

View File

@ -1,2 +0,0 @@
x�ÎM
Â0@a×9Eö‚d2?MADèªÇHÚ,[J½½=‚ÛÇ·xÓZëÒ<ôtj»ª�&ÐQà€)&* Â)#‹v yÊ܃Ûò®¯æÕ Éz•ˆ¨ŒÄ€¥P‰À4gÒyF�˜Ð\~·Çºûaô×a¼ë'×í©—i­7B )Åý wÔcªéŸÜÕ¯-O%÷×r8Ê

View File

@ -1,3 +0,0 @@
x�ÍA
à @Ñ®=Åì ÅÑé8…
YåFGˆ‚…ôöͺı<ø©Õºt@âKßUÁ*§b#Ïá¡’‰…³ ‹XÍä3S‰éîLüôwÛaœà9N/=bİV½¥V@&ñ$.x¸"ZkÎzNºşÉMı–eU4?3‹,Õ

View File

@ -1,2 +0,0 @@
x�ŽA
à E»öî ÅqÔ(„RÈ*ÇÐÉ Ä& ííëºzðx>íµ®MCr—v2k[`@Šqˆ’ŠäP¢¡X,ùNbuä“_M§!b0Ô­É ÀÁ¥x)Pßy†Â)X•ßí¹Ÿzšõ8Íþäzl|£½Þ5ÑE; ¾£ºí§ÿ™«ú•ucT? *:›

Some files were not shown because too many files have changed in this diff Show More