Unverified Commit 9084712b by Edward Thomson Committed by GitHub

Merge pull request #4904 from libgit2/ethomson/crlf

Update CRLF filtering to match modern git
parents 77f1460f e385e647

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

......@@ -310,6 +310,7 @@ bool git_buf_text_gather_stats(
}
}
return (stats->nul > 0 ||
/* Treat files with a bare CR as binary */
return (stats->cr != stats->crlf || stats->nul > 0 ||
((stats->printable >> 7) < stats->nonprintable));
}
......@@ -18,68 +18,58 @@
#include "buf_text.h"
#include "repository.h"
typedef enum {
GIT_CRLF_UNDEFINED,
GIT_CRLF_BINARY,
GIT_CRLF_TEXT,
GIT_CRLF_TEXT_INPUT,
GIT_CRLF_TEXT_CRLF,
GIT_CRLF_AUTO,
GIT_CRLF_AUTO_INPUT,
GIT_CRLF_AUTO_CRLF,
} git_crlf_t;
struct crlf_attrs {
int crlf_action;
int eol;
int attr_action; /* the .gitattributes setting */
int crlf_action; /* the core.autocrlf setting */
int auto_crlf;
int safe_crlf;
git_cvar_value core_eol;
};
struct crlf_filter {
git_filter f;
};
static int check_crlf(const char *value)
static git_crlf_t check_crlf(const char *value)
{
if (GIT_ATTR_TRUE(value))
return GIT_CRLF_TEXT;
if (GIT_ATTR_FALSE(value))
else if (GIT_ATTR_FALSE(value))
return GIT_CRLF_BINARY;
if (GIT_ATTR_UNSPECIFIED(value))
return GIT_CRLF_GUESS;
if (strcmp(value, "input") == 0)
return GIT_CRLF_INPUT;
if (strcmp(value, "auto") == 0)
else if (GIT_ATTR_UNSPECIFIED(value))
;
else if (strcmp(value, "input") == 0)
return GIT_CRLF_TEXT_INPUT;
else if (strcmp(value, "auto") == 0)
return GIT_CRLF_AUTO;
return GIT_CRLF_GUESS;
return GIT_CRLF_UNDEFINED;
}
static int check_eol(const char *value)
static git_cvar_value check_eol(const char *value)
{
if (GIT_ATTR_UNSPECIFIED(value))
return GIT_EOL_UNSET;
if (strcmp(value, "lf") == 0)
;
else if (strcmp(value, "lf") == 0)
return GIT_EOL_LF;
if (strcmp(value, "crlf") == 0)
else if (strcmp(value, "crlf") == 0)
return GIT_EOL_CRLF;
return GIT_EOL_UNSET;
}
static int crlf_input_action(struct crlf_attrs *ca)
{
if (ca->crlf_action == GIT_CRLF_BINARY)
return GIT_CRLF_BINARY;
if (ca->eol == GIT_EOL_LF)
return GIT_CRLF_INPUT;
if (ca->crlf_action == GIT_CRLF_AUTO)
return GIT_CRLF_AUTO;
if (ca->eol == GIT_EOL_CRLF)
return GIT_CRLF_CRLF;
return ca->crlf_action;
}
static int has_cr_in_index(const git_filter_source *src)
{
git_repository *repo = git_filter_source_repo(src);
......@@ -122,55 +112,125 @@ static int has_cr_in_index(const git_filter_source *src)
return found_cr;
}
static int crlf_apply_to_odb(
struct crlf_attrs *ca,
git_buf *to,
const git_buf *from,
const git_filter_source *src)
static int text_eol_is_crlf(struct crlf_attrs *ca)
{
/* Empty file? Nothing to do */
if (!git_buf_len(from))
if (ca->auto_crlf == GIT_AUTO_CRLF_TRUE)
return 1;
else if (ca->auto_crlf == GIT_AUTO_CRLF_INPUT)
return 0;
/* Heuristics to see if we can skip the conversion.
* Straight from Core Git.
*/
if (ca->crlf_action == GIT_CRLF_AUTO || ca->crlf_action == GIT_CRLF_GUESS) {
git_buf_text_stats stats;
if (ca->core_eol == GIT_EOL_CRLF)
return 1;
if (ca->core_eol == GIT_EOL_UNSET && GIT_EOL_NATIVE == GIT_EOL_CRLF)
return 1;
/* Check heuristics for binary vs text - returns true if binary */
if (git_buf_text_gather_stats(&stats, from, false))
return GIT_PASSTHROUGH;
return 0;
}
/* If there are no CR characters to filter out, then just pass */
if (!stats.cr)
return GIT_PASSTHROUGH;
static git_cvar_value output_eol(struct crlf_attrs *ca)
{
switch (ca->crlf_action) {
case GIT_CRLF_BINARY:
return GIT_EOL_UNSET;
case GIT_CRLF_TEXT_CRLF:
return GIT_EOL_CRLF;
case GIT_CRLF_TEXT_INPUT:
return GIT_EOL_LF;
case GIT_CRLF_UNDEFINED:
case GIT_CRLF_AUTO_CRLF:
return GIT_EOL_CRLF;
case GIT_CRLF_AUTO_INPUT:
return GIT_EOL_LF;
case GIT_CRLF_TEXT:
case GIT_CRLF_AUTO:
return text_eol_is_crlf(ca) ? GIT_EOL_CRLF : GIT_EOL_LF;
}
/* TODO: warn when available */
return ca->core_eol;
}
/* If safecrlf is enabled, sanity-check the result. */
if (stats.cr != stats.crlf || stats.lf != stats.crlf) {
switch (ca->safe_crlf) {
case GIT_SAFE_CRLF_FAIL:
GIT_INLINE(int) check_safecrlf(
struct crlf_attrs *ca,
const git_filter_source *src,
git_buf_text_stats *stats)
{
const char *filename = git_filter_source_path(src);
if (!ca->safe_crlf)
return 0;
if (output_eol(ca) == GIT_EOL_LF) {
/*
* CRLFs would not be restored by checkout:
* check if we'd remove CRLFs
*/
if (stats->crlf) {
if (ca->safe_crlf == GIT_SAFE_CRLF_WARN) {
/* TODO: issue a warning when available */
} else {
if (filename && *filename)
giterr_set(
GITERR_FILTER, "CRLF would be replaced by LF in '%s'",
filename);
else
giterr_set(
GITERR_FILTER, "CRLF would be replaced by LF");
return -1;
}
}
} else if (output_eol(ca) == GIT_EOL_CRLF) {
/*
* CRLFs would be added by checkout:
* check if we have "naked" LFs
*/
if (stats->crlf != stats->lf) {
if (ca->safe_crlf == GIT_SAFE_CRLF_WARN) {
/* TODO: issue a warning when available */
} else {
if (filename && *filename)
giterr_set(
GITERR_FILTER, "LF would be replaced by CRLF in '%s'",
git_filter_source_path(src));
filename);
else
giterr_set(
GITERR_FILTER, "LF would be replaced by CRLF");
return -1;
case GIT_SAFE_CRLF_WARN:
/* TODO: issue warning when warning API is available */;
break;
default:
break;
}
}
}
/*
* We're currently not going to even try to convert stuff
* that has bare CR characters. Does anybody do that crazy
* stuff?
return 0;
}
static int crlf_apply_to_odb(
struct crlf_attrs *ca,
git_buf *to,
const git_buf *from,
const git_filter_source *src)
{
git_buf_text_stats stats;
bool is_binary;
int error;
/* Binary attribute? Empty file? Nothing to do */
if (ca->crlf_action == GIT_CRLF_BINARY || !git_buf_len(from))
return GIT_PASSTHROUGH;
is_binary = git_buf_text_gather_stats(&stats, from, false);
/* Heuristics to see if we can skip the conversion.
* Straight from Core Git.
*/
if (stats.cr != stats.crlf)
if (ca->crlf_action == GIT_CRLF_AUTO ||
ca->crlf_action == GIT_CRLF_AUTO_INPUT ||
ca->crlf_action == GIT_CRLF_AUTO_CRLF) {
if (is_binary)
return GIT_PASSTHROUGH;
if (ca->crlf_action == GIT_CRLF_GUESS) {
/*
* If the file in the index has any CR in it, do not convert.
* This is the new safer autocrlf handling.
......@@ -179,90 +239,41 @@ static int crlf_apply_to_odb(
return GIT_PASSTHROUGH;
}
if (!stats.cr)
if ((error = check_safecrlf(ca, src, &stats)) < 0)
return error;
/* If there are no CR characters to filter out, then just pass */
if (!stats.crlf)
return GIT_PASSTHROUGH;
}
/* Actually drop the carriage returns */
return git_buf_text_crlf_to_lf(to, from);
}
static const char *line_ending(struct crlf_attrs *ca)
{
switch (ca->crlf_action) {
case GIT_CRLF_BINARY:
case GIT_CRLF_INPUT:
return "\n";
case GIT_CRLF_CRLF:
return "\r\n";
case GIT_CRLF_GUESS:
if (ca->auto_crlf == GIT_AUTO_CRLF_FALSE)
return "\n";
break;
case GIT_CRLF_AUTO:
if (ca->eol == GIT_EOL_CRLF)
return "\r\n";
case GIT_CRLF_TEXT:
break;
default:
goto line_ending_error;
}
if (ca->auto_crlf == GIT_AUTO_CRLF_TRUE)
return "\r\n";
else if (ca->auto_crlf == GIT_AUTO_CRLF_INPUT)
return "\n";
else if (ca->eol == GIT_EOL_UNSET)
return GIT_EOL_NATIVE == GIT_EOL_CRLF ? "\r\n" : "\n";
else if (ca->eol == GIT_EOL_LF)
return "\n";
else if (ca->eol == GIT_EOL_CRLF)
return "\r\n";
line_ending_error:
giterr_set(GITERR_INVALID, "invalid input to line ending filter");
return NULL;
}
static int crlf_apply_to_workdir(
struct crlf_attrs *ca, git_buf *to, const git_buf *from)
struct crlf_attrs *ca,
git_buf *to,
const git_buf *from)
{
git_buf_text_stats stats;
const char *workdir_ending = NULL;
bool is_binary;
/* Empty file? Nothing to do. */
if (git_buf_len(from) == 0)
return 0;
/* Determine proper line ending */
workdir_ending = line_ending(ca);
if (!workdir_ending)
return -1;
/* only LF->CRLF conversion is supported, do nothing on LF platforms */
if (strcmp(workdir_ending, "\r\n") != 0)
if (git_buf_len(from) == 0 || output_eol(ca) != GIT_EOL_CRLF)
return GIT_PASSTHROUGH;
/* If there are no LFs, or all LFs are part of a CRLF, nothing to do */
is_binary = git_buf_text_gather_stats(&stats, from, false);
/* If there are no LFs, or all LFs are part of a CRLF, nothing to do */
if (stats.lf == 0 || stats.lf == stats.crlf)
return GIT_PASSTHROUGH;
if (ca->crlf_action == GIT_CRLF_AUTO ||
ca->crlf_action == GIT_CRLF_GUESS) {
ca->crlf_action == GIT_CRLF_AUTO_INPUT ||
ca->crlf_action == GIT_CRLF_AUTO_CRLF) {
/* If we have any existing CR or CRLF line endings, do nothing */
if (stats.cr > 0 && stats.crlf > 0)
return GIT_PASSTHROUGH;
/* If we have bare CR characters, do nothing */
if (stats.cr != stats.crlf)
if (stats.cr > 0)
return GIT_PASSTHROUGH;
/* Don't filter binary files */
......@@ -273,69 +284,80 @@ static int crlf_apply_to_workdir(
return git_buf_text_lf_to_crlf(to, from);
}
static int crlf_check(
git_filter *self,
void **payload, /* points to NULL ptr on entry, may be set */
const git_filter_source *src,
const char **attr_values)
static int convert_attrs(
struct crlf_attrs *ca,
const char **attr_values,
const git_filter_source *src)
{
int error;
struct crlf_attrs ca;
GIT_UNUSED(self);
memset(ca, 0, sizeof(struct crlf_attrs));
if (!attr_values) {
ca.crlf_action = GIT_CRLF_GUESS;
ca.eol = GIT_EOL_UNSET;
if ((error = git_repository__cvar(&ca->auto_crlf,
git_filter_source_repo(src), GIT_CVAR_AUTO_CRLF)) < 0 ||
(error = git_repository__cvar(&ca->safe_crlf,
git_filter_source_repo(src), GIT_CVAR_SAFE_CRLF)) < 0 ||
(error = git_repository__cvar(&ca->core_eol,
git_filter_source_repo(src), GIT_CVAR_EOL)) < 0)
return error;
/* downgrade FAIL to WARN if ALLOW_UNSAFE option is used */
if ((git_filter_source_flags(src) & GIT_FILTER_ALLOW_UNSAFE) &&
ca->safe_crlf == GIT_SAFE_CRLF_FAIL)
ca->safe_crlf = GIT_SAFE_CRLF_WARN;
if (attr_values) {
/* load the text attribute */
ca->crlf_action = check_crlf(attr_values[2]); /* text */
if (ca->crlf_action == GIT_CRLF_UNDEFINED)
ca->crlf_action = check_crlf(attr_values[0]); /* crlf */
if (ca->crlf_action != GIT_CRLF_BINARY) {
/* load the eol attribute */
int eol_attr = check_eol(attr_values[1]);
if (ca->crlf_action == GIT_CRLF_AUTO && eol_attr == GIT_EOL_LF)
ca->crlf_action = GIT_CRLF_AUTO_INPUT;
else if (ca->crlf_action == GIT_CRLF_AUTO && eol_attr == GIT_EOL_CRLF)
ca->crlf_action = GIT_CRLF_AUTO_CRLF;
else if (eol_attr == GIT_EOL_LF)
ca->crlf_action = GIT_CRLF_TEXT_INPUT;
else if (eol_attr == GIT_EOL_CRLF)
ca->crlf_action = GIT_CRLF_TEXT_CRLF;
}
ca->attr_action = ca->crlf_action;
} else {
ca.crlf_action = check_crlf(attr_values[2]); /* text */
if (ca.crlf_action == GIT_CRLF_GUESS)
ca.crlf_action = check_crlf(attr_values[0]); /* clrf */
ca.eol = check_eol(attr_values[1]); /* eol */
ca->crlf_action = GIT_CRLF_UNDEFINED;
}
ca.auto_crlf = GIT_AUTO_CRLF_DEFAULT;
ca.safe_crlf = GIT_SAFE_CRLF_DEFAULT;
/*
* Use the core Git logic to see if we should perform CRLF for this file
* based on its attributes & the value of `core.autocrlf`
*/
ca.crlf_action = crlf_input_action(&ca);
if (ca->crlf_action == GIT_CRLF_TEXT)
ca->crlf_action = text_eol_is_crlf(ca) ? GIT_CRLF_TEXT_CRLF : GIT_CRLF_TEXT_INPUT;
if (ca->crlf_action == GIT_CRLF_UNDEFINED && ca->auto_crlf == GIT_AUTO_CRLF_FALSE)
ca->crlf_action = GIT_CRLF_BINARY;
if (ca->crlf_action == GIT_CRLF_UNDEFINED && ca->auto_crlf == GIT_AUTO_CRLF_TRUE)
ca->crlf_action = GIT_CRLF_AUTO_CRLF;
if (ca->crlf_action == GIT_CRLF_UNDEFINED && ca->auto_crlf == GIT_AUTO_CRLF_INPUT)
ca->crlf_action = GIT_CRLF_AUTO_INPUT;
if (ca.crlf_action == GIT_CRLF_BINARY)
return GIT_PASSTHROUGH;
return 0;
}
if (ca.crlf_action == GIT_CRLF_GUESS ||
((ca.crlf_action == GIT_CRLF_AUTO ||
ca.crlf_action == GIT_CRLF_TEXT) &&
git_filter_source_mode(src) == GIT_FILTER_SMUDGE)) {
static int crlf_check(
git_filter *self,
void **payload, /* points to NULL ptr on entry, may be set */
const git_filter_source *src,
const char **attr_values)
{
struct crlf_attrs ca;
error = git_repository__cvar(
&ca.auto_crlf, git_filter_source_repo(src), GIT_CVAR_AUTO_CRLF);
if (error < 0)
return error;
GIT_UNUSED(self);
if (ca.crlf_action == GIT_CRLF_GUESS &&
ca.auto_crlf == GIT_AUTO_CRLF_FALSE)
return GIT_PASSTHROUGH;
convert_attrs(&ca, attr_values, src);
if (ca.auto_crlf == GIT_AUTO_CRLF_INPUT &&
ca.eol != GIT_EOL_CRLF &&
git_filter_source_mode(src) == GIT_FILTER_SMUDGE)
if (ca.crlf_action == GIT_CRLF_BINARY)
return GIT_PASSTHROUGH;
}
if (git_filter_source_mode(src) == GIT_FILTER_CLEAN) {
error = git_repository__cvar(
&ca.safe_crlf, git_filter_source_repo(src), GIT_CVAR_SAFE_CRLF);
if (error < 0)
return error;
/* downgrade FAIL to WARN if ALLOW_UNSAFE option is used */
if ((git_filter_source_flags(src) & GIT_FILTER_ALLOW_UNSAFE) &&
ca.safe_crlf == GIT_SAFE_CRLF_FAIL)
ca.safe_crlf = GIT_SAFE_CRLF_WARN;
}
*payload = git__malloc(sizeof(ca));
GITERR_CHECK_ALLOC(*payload);
......@@ -354,6 +376,7 @@ static int crlf_apply(
/* initialize payload in case `check` was bypassed */
if (!*payload) {
int error = crlf_check(self, payload, src, NULL);
if (error < 0)
return error;
}
......
......@@ -15,16 +15,6 @@
/* Amount of file to examine for NUL byte when checking binary-ness */
#define GIT_FILTER_BYTES_TO_CHECK_NUL 8000
/* Possible CRLF values */
typedef enum {
GIT_CRLF_GUESS = -1,
GIT_CRLF_BINARY = 0,
GIT_CRLF_TEXT,
GIT_CRLF_INPUT,
GIT_CRLF_CRLF,
GIT_CRLF_AUTO,
} git_crlf_t;
typedef struct {
git_attr_session *attr_session;
git_buf *temp_buf;
......
......@@ -13,14 +13,40 @@ static git_repository *g_repo;
static const char *systype;
static git_buf expected_fixture = GIT_BUF_INIT;
static int unlink_file(void *payload, git_buf *path)
{
char *fn;
cl_assert(fn = git_path_basename(path->ptr));
GIT_UNUSED(payload);
if (strcmp(fn, ".git"))
cl_must_pass(p_unlink(path->ptr));
git__free(fn);
return 0;
}
void test_checkout_crlf__initialize(void)
{
git_buf reponame = GIT_BUF_INIT;
g_repo = cl_git_sandbox_init("crlf");
/*
* remove the contents of the working directory so that we can
* check out over it.
*/
cl_git_pass(git_buf_puts(&reponame, "crlf"));
cl_git_pass(git_path_direach(&reponame, 0, unlink_file, NULL));
if (GIT_EOL_NATIVE == GIT_EOL_CRLF)
systype = "windows";
else
systype = "posix";
git_buf_dispose(&reponame);
}
void test_checkout_crlf__cleanup(void)
......@@ -99,41 +125,45 @@ static void test_checkout(const char *autocrlf, const char *attrs)
{
git_buf attrbuf = GIT_BUF_INIT;
git_buf expected_dirname = GIT_BUF_INIT;
git_buf systype_and_direction = GIT_BUF_INIT;
git_buf sandboxname = GIT_BUF_INIT;
git_buf reponame = GIT_BUF_INIT;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
struct compare_data compare_data = { NULL, autocrlf, attrs };
const char *c;
git_buf_puts(&reponame, "crlf");
cl_git_pass(git_buf_puts(&reponame, "crlf"));
cl_git_pass(git_buf_puts(&systype_and_direction, systype));
cl_git_pass(git_buf_puts(&systype_and_direction, "_to_workdir"));
git_buf_puts(&sandboxname, "autocrlf_");
git_buf_puts(&sandboxname, autocrlf);
cl_git_pass(git_buf_puts(&sandboxname, "autocrlf_"));
cl_git_pass(git_buf_puts(&sandboxname, autocrlf));
if (*attrs) {
git_buf_puts(&sandboxname, ",");
cl_git_pass(git_buf_puts(&sandboxname, ","));
for (c = attrs; *c; c++) {
if (*c == ' ')
git_buf_putc(&sandboxname, ',');
cl_git_pass(git_buf_putc(&sandboxname, ','));
else if (*c == '=')
git_buf_putc(&sandboxname, '_');
cl_git_pass(git_buf_putc(&sandboxname, '_'));
else
git_buf_putc(&sandboxname, *c);
cl_git_pass(git_buf_putc(&sandboxname, *c));
}
git_buf_printf(&attrbuf, "* %s\n", attrs);
cl_git_pass(git_buf_printf(&attrbuf, "* %s\n", attrs));
cl_git_mkfile("crlf/.gitattributes", attrbuf.ptr);
}
cl_repo_set_string(g_repo, "core.autocrlf", autocrlf);
git_buf_joinpath(&expected_dirname, systype, sandboxname.ptr);
git_buf_joinpath(&expected_fixture, "crlf_data", expected_dirname.ptr);
cl_git_pass(git_buf_joinpath(&expected_dirname, systype_and_direction.ptr, sandboxname.ptr));
cl_git_pass(git_buf_joinpath(&expected_fixture, "crlf_data", expected_dirname.ptr));
cl_fixture_sandbox(expected_fixture.ptr);
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
git_checkout_head(g_repo, &opts);
cl_git_pass(git_checkout_head(g_repo, &opts));
compare_data.dirname = sandboxname.ptr;
cl_git_pass(git_path_direach(&reponame, 0, compare_file, &compare_data));
......@@ -145,25 +175,27 @@ static void test_checkout(const char *autocrlf, const char *attrs)
git_buf_dispose(&expected_fixture);
git_buf_dispose(&expected_dirname);
git_buf_dispose(&sandboxname);
git_buf_dispose(&systype_and_direction);
git_buf_dispose(&reponame);
}
static void empty_workdir(const char *name)
{
git_vector contents = GIT_VECTOR_INIT;
char *basename;
int cmp;
size_t i;
const char *fn;
git_path_dirload(&contents, name, 0, 0);
cl_git_pass(git_path_dirload(&contents, name, 0, 0));
git_vector_foreach(&contents, i, fn) {
char *basename = git_path_basename(fn);
int cmp = strncasecmp(basename, ".git", 4);
cl_assert(basename = git_path_basename(fn));
cmp = strncasecmp(basename, ".git", 4);
git__free(basename);
if (cmp == 0)
continue;
p_unlink(fn);
if (cmp)
cl_git_pass(p_unlink(fn));
}
git_vector_free_deep(&contents);
}
......@@ -335,7 +367,7 @@ void test_checkout_crlf__with_ident(void)
p_unlink("crlf/more1.identlf");
p_unlink("crlf/more2.identcrlf");
git_checkout_head(g_repo, &opts);
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert_equal_file(
ALL_LF_TEXT_AS_CRLF
......@@ -364,7 +396,7 @@ void test_checkout_crlf__autocrlf_false_no_attrs(void)
cl_repo_set_bool(g_repo, "core.autocrlf", false);
git_checkout_head(g_repo, &opts);
cl_git_pass(git_checkout_head(g_repo, &opts));
check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
......@@ -377,7 +409,7 @@ void test_checkout_crlf__autocrlf_true_no_attrs(void)
cl_repo_set_bool(g_repo, "core.autocrlf", true);
git_checkout_head(g_repo, &opts);
cl_git_pass(git_checkout_head(g_repo, &opts));
check_file_contents("./crlf/all-lf", ALL_LF_TEXT_AS_CRLF);
check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_AS_CRLF);
......@@ -390,7 +422,7 @@ void test_checkout_crlf__autocrlf_input_no_attrs(void)
cl_repo_set_string(g_repo, "core.autocrlf", "input");
git_checkout_head(g_repo, &opts);
cl_git_pass(git_checkout_head(g_repo, &opts));
check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
......@@ -405,7 +437,7 @@ void test_checkout_crlf__autocrlf_false_text_auto_attr(void)
cl_repo_set_bool(g_repo, "core.autocrlf", false);
git_checkout_head(g_repo, &opts);
cl_git_pass(git_checkout_head(g_repo, &opts));
if (GIT_EOL_NATIVE == GIT_EOL_CRLF) {
check_file_contents("./crlf/all-lf", ALL_LF_TEXT_AS_CRLF);
......@@ -425,7 +457,7 @@ void test_checkout_crlf__autocrlf_true_text_auto_attr(void)
cl_repo_set_bool(g_repo, "core.autocrlf", true);
git_checkout_head(g_repo, &opts);
cl_git_pass(git_checkout_head(g_repo, &opts));
check_file_contents("./crlf/all-lf", ALL_LF_TEXT_AS_CRLF);
check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_AS_CRLF);
......@@ -440,7 +472,7 @@ void test_checkout_crlf__autocrlf_input_text_auto_attr(void)
cl_repo_set_string(g_repo, "core.autocrlf", "input");
git_checkout_head(g_repo, &opts);
cl_git_pass(git_checkout_head(g_repo, &opts));
check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
......@@ -453,8 +485,8 @@ void test_checkout_crlf__can_write_empty_file(void)
cl_repo_set_bool(g_repo, "core.autocrlf", true);
git_repository_set_head(g_repo, "refs/heads/empty-files");
git_checkout_head(g_repo, &opts);
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/empty-files"));
cl_git_pass(git_checkout_head(g_repo, &opts));
check_file_contents("./crlf/test1.txt", "");
......
......@@ -99,12 +99,19 @@ void test_filter_crlf__with_safecrlf(void)
cl_git_fail(git_filter_list_apply_to_data(&out, fl, &in));
cl_assert_equal_i(giterr_last()->klass, GITERR_FILTER);
/* Normalized \n is reversible, so does not fail with safecrlf */
/* Normalized \n fails for autocrlf=true when safecrlf=true */
in.ptr = "Normal\nLF\nonly\nline-endings.\n";
in.size = strlen(in.ptr);
cl_git_fail(git_filter_list_apply_to_data(&out, fl, &in));
cl_assert_equal_i(giterr_last()->klass, GITERR_FILTER);
/* String with \r but without \r\n does not fail with safecrlf */
in.ptr = "Normal\nCR only\rand some more\nline-endings.\n";
in.size = strlen(in.ptr);
cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
cl_assert_equal_s(in.ptr, out.ptr);
cl_assert_equal_s("Normal\nCR only\rand some more\nline-endings.\n", out.ptr);
git_filter_list_free(fl);
git_buf_dispose(&out);
......
......@@ -14,9 +14,11 @@
static git_repository *g_repo;
static git_index *g_index;
static git_buf expected_fixture = GIT_BUF_INIT;
void test_index_crlf__initialize(void)
{
g_repo = cl_git_sandbox_init("crlf");
g_repo = cl_git_sandbox_init_new("crlf");
cl_git_pass(git_repository_index(&g_index, g_repo));
}
......@@ -24,6 +26,208 @@ void test_index_crlf__cleanup(void)
{
git_index_free(g_index);
cl_git_sandbox_cleanup();
if (expected_fixture.size) {
cl_fixture_cleanup(expected_fixture.ptr);
git_buf_free(&expected_fixture);
}
}
struct compare_data
{
const char *systype;
const char *dirname;
const char *safecrlf;
const char *autocrlf;
const char *attrs;
};
static int add_and_check_file(void *payload, git_buf *actual_path)
{
git_buf expected_path = GIT_BUF_INIT;
git_buf expected_path_fail = GIT_BUF_INIT;
git_buf expected_contents = GIT_BUF_INIT;
struct compare_data *cd = payload;
char *basename;
const git_index_entry *entry;
git_blob *blob;
bool failed = true;
basename = git_path_basename(actual_path->ptr);
if (!strcmp(basename, ".git") || !strcmp(basename, ".gitattributes")) {
failed = false;
goto done;
}
cl_git_pass(git_buf_joinpath(&expected_path, cd->dirname, basename));
cl_git_pass(git_buf_puts(&expected_path_fail, expected_path.ptr));
cl_git_pass(git_buf_puts(&expected_path_fail, ".fail"));
if (git_path_isfile(expected_path.ptr)) {
cl_git_pass(git_index_add_bypath(g_index, basename));
cl_assert(entry = git_index_get_bypath(g_index, basename, 0));
cl_git_pass(git_blob_lookup(&blob, g_repo, &entry->id));
cl_git_pass(git_futils_readbuffer(&expected_contents, expected_path.ptr));
if (strcmp(expected_contents.ptr, git_blob_rawcontent(blob)) != 0)
goto done;
git_blob_free(blob);
} else if (git_path_isfile(expected_path_fail.ptr)) {
cl_git_pass(git_futils_readbuffer(&expected_contents, expected_path_fail.ptr));
git_buf_rtrim(&expected_contents);
if (git_index_add_bypath(g_index, basename) == 0 ||
giterr_last()->klass != GITERR_FILTER ||
strcmp(expected_contents.ptr, giterr_last()->message) != 0)
goto done;
} else {
cl_fail("unexpected index failure");
}
failed = false;
done:
if (failed) {
git_buf details = GIT_BUF_INIT;
git_buf_printf(&details, "filename=%s, system=%s, autocrlf=%s, safecrlf=%s, attrs={%s}",
basename, cd->systype, cd->autocrlf, cd->safecrlf, cd->attrs);
clar__fail(__FILE__, __LINE__,
"index contents did not match expected", details.ptr, 0);
git_buf_dispose(&details);
}
git__free(basename);
git_buf_dispose(&expected_contents);
git_buf_dispose(&expected_path);
git_buf_dispose(&expected_path_fail);
return 0;
}
static const char *system_type(void)
{
if (GIT_EOL_NATIVE == GIT_EOL_CRLF)
return "windows";
else
return "posix";
}
static void test_add_index(const char *safecrlf, const char *autocrlf, const char *attrs)
{
git_buf attrbuf = GIT_BUF_INIT;
git_buf expected_dirname = GIT_BUF_INIT;
git_buf sandboxname = GIT_BUF_INIT;
git_buf reponame = GIT_BUF_INIT;
struct compare_data compare_data = { system_type(), NULL, safecrlf, autocrlf, attrs };
const char *c;
git_buf_puts(&reponame, "crlf");
git_buf_puts(&sandboxname, "autocrlf_");
git_buf_puts(&sandboxname, autocrlf);
git_buf_puts(&sandboxname, ",safecrlf_");
git_buf_puts(&sandboxname, safecrlf);
if (*attrs) {
git_buf_puts(&sandboxname, ",");
for (c = attrs; *c; c++) {
if (*c == ' ')
git_buf_putc(&sandboxname, ',');
else if (*c == '=')
git_buf_putc(&sandboxname, '_');
else
git_buf_putc(&sandboxname, *c);
}
git_buf_printf(&attrbuf, "* %s\n", attrs);
cl_git_mkfile("crlf/.gitattributes", attrbuf.ptr);
}
cl_repo_set_string(g_repo, "core.safecrlf", safecrlf);
cl_repo_set_string(g_repo, "core.autocrlf", autocrlf);
cl_git_pass(git_index_clear(g_index));
git_buf_joinpath(&expected_dirname, "crlf_data", system_type());
git_buf_puts(&expected_dirname, "_to_odb");
git_buf_joinpath(&expected_fixture, expected_dirname.ptr, sandboxname.ptr);
cl_fixture_sandbox(expected_fixture.ptr);
compare_data.dirname = sandboxname.ptr;
cl_git_pass(git_path_direach(&reponame, 0, add_and_check_file, &compare_data));
cl_fixture_cleanup(expected_fixture.ptr);
git_buf_free(&expected_fixture);
git_buf_free(&attrbuf);
git_buf_free(&expected_fixture);
git_buf_free(&expected_dirname);
git_buf_free(&sandboxname);
git_buf_free(&reponame);
}
static void set_up_workingdir(const char *name)
{
git_vector contents = GIT_VECTOR_INIT;
size_t i;
const char *fn;
git_path_dirload(&contents, name, 0, 0);
git_vector_foreach(&contents, i, fn) {
char *basename = git_path_basename(fn);
bool skip = strncasecmp(basename, ".git", 4) == 0 && strlen(basename) == 4;
git__free(basename);
if (skip)
continue;
p_unlink(fn);
}
git_vector_free_deep(&contents);
/* copy input files */
git_path_dirload(&contents, cl_fixture("crlf"), 0, 0);
git_vector_foreach(&contents, i, fn) {
char *basename = git_path_basename(fn);
git_buf dest_filename = GIT_BUF_INIT;
if (strcmp(basename, ".gitted") &&
strcmp(basename, ".gitattributes")) {
git_buf_joinpath(&dest_filename, name, basename);
cl_git_pass(git_futils_cp(fn, dest_filename.ptr, 0644));
}
git__free(basename);
git_buf_free(&dest_filename);
}
git_vector_free_deep(&contents);
}
void test_index_crlf__matches_core_git(void)
{
const char *safecrlf[] = { "true", "false", "warn", NULL };
const char *autocrlf[] = { "true", "false", "input", NULL };
const char *attrs[] = { "", "-crlf", "-text", "eol=crlf", "eol=lf",
"text", "text eol=crlf", "text eol=lf",
"text=auto", "text=auto eol=crlf", "text=auto eol=lf",
NULL };
const char **a, **b, **c;
for (a = safecrlf; *a; a++) {
for (b = autocrlf; *b; b++) {
for (c = attrs; *c; c++) {
set_up_workingdir("crlf");
test_add_index(*a, *b, *c);
}
}
}
}
void test_index_crlf__autocrlf_false_no_attrs(void)
......@@ -135,13 +339,55 @@ void test_index_crlf__autocrlf_input_text_auto_attr(void)
cl_assert_equal_oid(&oid, &entry->id);
}
void test_index_crlf__safecrlf_true_autocrlf_input_text_auto_attr(void)
{
const git_index_entry *entry;
git_oid oid;
cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
cl_repo_set_string(g_repo, "core.autocrlf", "input");
cl_repo_set_bool(g_repo, "core.safecrlf", true);
cl_git_mkfile("./crlf/newfile.txt", FILE_CONTENTS_LF);
cl_git_pass(git_index_add_bypath(g_index, "newfile.txt"));
entry = git_index_get_bypath(g_index, "newfile.txt", 0);
cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF));
cl_assert_equal_oid(&oid, &entry->id);
cl_git_mkfile("./crlf/newfile2.txt", FILE_CONTENTS_CRLF);
cl_git_fail(git_index_add_bypath(g_index, "newfile2.txt"));
}
void test_index_crlf__safecrlf_true_autocrlf_input_text__no_attr(void)
{
const git_index_entry *entry;
git_oid oid;
cl_repo_set_string(g_repo, "core.autocrlf", "input");
cl_repo_set_bool(g_repo, "core.safecrlf", true);
cl_git_mkfile("./crlf/newfile.txt", FILE_CONTENTS_LF);
cl_git_pass(git_index_add_bypath(g_index, "newfile.txt"));
entry = git_index_get_bypath(g_index, "newfile.txt", 0);
cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF));
cl_assert_equal_oid(&oid, &entry->id);
cl_git_mkfile("./crlf/newfile2.txt", FILE_CONTENTS_CRLF);
cl_git_fail(git_index_add_bypath(g_index, "newfile2.txt"));
}
void test_index_crlf__safecrlf_true_no_attrs(void)
{
cl_repo_set_bool(g_repo, "core.autocrlf", true);
cl_repo_set_bool(g_repo, "core.safecrlf", true);
cl_git_mkfile("crlf/newfile.txt", ALL_LF_TEXT_RAW);
cl_git_pass(git_index_add_bypath(g_index, "newfile.txt"));
cl_git_fail(git_index_add_bypath(g_index, "newfile.txt"));
cl_git_mkfile("crlf/newfile.txt", ALL_CRLF_TEXT_RAW);
cl_git_pass(git_index_add_bypath(g_index, "newfile.txt"));
......
* binary
*.sh text diff merge eol=lf
This test data was generated using the `tests/resources/generate_crlf.sh`
script. Please see that script for usage information.
(posix and windows directories) and `tests/resources/generate_crlf_checkin.sh`
(checkin_results directory) scripts. Please see these scripts for usage information.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
one
two three
four
\ No newline at end of file
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
one
two three
four
\ No newline at end of file
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
one
two three
four
\ No newline at end of file
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
⚽The rest is ASCII01.
The rest is ASCII02.
The rest is ASCII03.
The rest is ASCII04.
The rest is ASCII05.
The rest is ASCII06.
The rest is ASCII07.
The rest is ASCII08.
The rest is ASCII09.
The rest is ASCII10.
The rest is ASCII11.
The rest is ASCII12.
The rest is ASCII13.
The rest is ASCII14.
The rest is ASCII15.
The rest is ASCII16.
The rest is ASCII17.
The rest is ASCII18.
The rest is ASCII19.
The rest is ASCII20.
The rest is ASCII21.
The rest is ASCII22.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment