handle failing pathop tests
Some tests isolated from GrShapes_arcs do not fail gracefully, so make sure errors are properly handled. TBR=reed@google.com Bug: skia: Change-Id: Ia8c9903e64ef755ec11c398df3e5d258ca1f5f8b Reviewed-on: https://skia-review.googlesource.com/143112 Reviewed-by: Cary Clark <caryclark@skia.org> Commit-Queue: Cary Clark <caryclark@skia.org> Auto-Submit: Cary Clark <caryclark@skia.org>
This commit is contained in:
parent
6a4e60bb8f
commit
2587f41f26
@ -338,7 +338,7 @@ SkOpSpanBase::Collapsed SkOpSegment::collapsed(double s, double e) const {
|
|||||||
return SkOpSpanBase::Collapsed::kNo;
|
return SkOpSpanBase::Collapsed::kNo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkOpSegment::ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
|
bool SkOpSegment::ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
|
||||||
SkOpAngle::IncludeType includeType) {
|
SkOpAngle::IncludeType includeType) {
|
||||||
SkOpSegment* baseSegment = baseAngle->segment();
|
SkOpSegment* baseSegment = baseAngle->segment();
|
||||||
int sumMiWinding = baseSegment->updateWindingReverse(baseAngle);
|
int sumMiWinding = baseSegment->updateWindingReverse(baseAngle);
|
||||||
@ -358,17 +358,22 @@ void SkOpSegment::ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle
|
|||||||
int oppMaxWinding, oppSumWinding;
|
int oppMaxWinding, oppSumWinding;
|
||||||
nextSegment->setUpWindings(nextAngle->start(), nextAngle->end(), &sumMiWinding,
|
nextSegment->setUpWindings(nextAngle->start(), nextAngle->end(), &sumMiWinding,
|
||||||
&sumSuWinding, &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding);
|
&sumSuWinding, &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding);
|
||||||
last = nextSegment->markAngle(maxWinding, sumWinding, oppMaxWinding, oppSumWinding,
|
if (!nextSegment->markAngle(maxWinding, sumWinding, oppMaxWinding, oppSumWinding,
|
||||||
nextAngle);
|
nextAngle, &last)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
nextSegment->setUpWindings(nextAngle->start(), nextAngle->end(), &sumMiWinding,
|
nextSegment->setUpWindings(nextAngle->start(), nextAngle->end(), &sumMiWinding,
|
||||||
&maxWinding, &sumWinding);
|
&maxWinding, &sumWinding);
|
||||||
last = nextSegment->markAngle(maxWinding, sumWinding, nextAngle);
|
if (!nextSegment->markAngle(maxWinding, sumWinding, nextAngle, &last)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nextAngle->setLastMarked(last);
|
nextAngle->setLastMarked(last);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkOpSegment::ComputeOneSumReverse(SkOpAngle* baseAngle, SkOpAngle* nextAngle,
|
bool SkOpSegment::ComputeOneSumReverse(SkOpAngle* baseAngle, SkOpAngle* nextAngle,
|
||||||
SkOpAngle::IncludeType includeType) {
|
SkOpAngle::IncludeType includeType) {
|
||||||
SkOpSegment* baseSegment = baseAngle->segment();
|
SkOpSegment* baseSegment = baseAngle->segment();
|
||||||
int sumMiWinding = baseSegment->updateWinding(baseAngle);
|
int sumMiWinding = baseSegment->updateWinding(baseAngle);
|
||||||
@ -388,14 +393,19 @@ void SkOpSegment::ComputeOneSumReverse(SkOpAngle* baseAngle, SkOpAngle* nextAngl
|
|||||||
int oppMaxWinding, oppSumWinding;
|
int oppMaxWinding, oppSumWinding;
|
||||||
nextSegment->setUpWindings(nextAngle->end(), nextAngle->start(), &sumMiWinding,
|
nextSegment->setUpWindings(nextAngle->end(), nextAngle->start(), &sumMiWinding,
|
||||||
&sumSuWinding, &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding);
|
&sumSuWinding, &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding);
|
||||||
last = nextSegment->markAngle(maxWinding, sumWinding, oppMaxWinding, oppSumWinding,
|
if (!nextSegment->markAngle(maxWinding, sumWinding, oppMaxWinding, oppSumWinding,
|
||||||
nextAngle);
|
nextAngle, &last)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
nextSegment->setUpWindings(nextAngle->end(), nextAngle->start(), &sumMiWinding,
|
nextSegment->setUpWindings(nextAngle->end(), nextAngle->start(), &sumMiWinding,
|
||||||
&maxWinding, &sumWinding);
|
&maxWinding, &sumWinding);
|
||||||
last = nextSegment->markAngle(maxWinding, sumWinding, nextAngle);
|
if (!nextSegment->markAngle(maxWinding, sumWinding, nextAngle, &last)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nextAngle->setLastMarked(last);
|
nextAngle->setLastMarked(last);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// at this point, the span is already ordered, or unorderable
|
// at this point, the span is already ordered, or unorderable
|
||||||
@ -910,10 +920,10 @@ bool SkOpSegment::markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end,
|
|||||||
if (this->operand() == other->operand()) {
|
if (this->operand() == other->operand()) {
|
||||||
if (spanStart->windSum() != winding || spanStart->oppSum() != oppWinding) {
|
if (spanStart->windSum() != winding || spanStart->oppSum() != oppWinding) {
|
||||||
this->globalState()->setWindingFailed();
|
this->globalState()->setWindingFailed();
|
||||||
return false;
|
return true; // ... but let it succeed anyway
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SkASSERT(spanStart->windSum() == oppWinding);
|
FAIL_IF(spanStart->windSum() != oppWinding);
|
||||||
SkASSERT(spanStart->oppSum() == winding);
|
SkASSERT(spanStart->oppSum() == winding);
|
||||||
}
|
}
|
||||||
SkASSERT(!last);
|
SkASSERT(!last);
|
||||||
@ -931,13 +941,15 @@ bool SkOpSegment::markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end,
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkOpSpanBase* SkOpSegment::markAngle(int maxWinding, int sumWinding, const SkOpAngle* angle) {
|
bool SkOpSegment::markAngle(int maxWinding, int sumWinding, const SkOpAngle* angle,
|
||||||
|
SkOpSpanBase** result) {
|
||||||
SkASSERT(angle->segment() == this);
|
SkASSERT(angle->segment() == this);
|
||||||
if (UseInnerWinding(maxWinding, sumWinding)) {
|
if (UseInnerWinding(maxWinding, sumWinding)) {
|
||||||
maxWinding = sumWinding;
|
maxWinding = sumWinding;
|
||||||
}
|
}
|
||||||
SkOpSpanBase* last;
|
if (!markAndChaseWinding(angle->start(), angle->end(), maxWinding, result)) {
|
||||||
(void) markAndChaseWinding(angle->start(), angle->end(), maxWinding, &last);
|
return false;
|
||||||
|
}
|
||||||
#if DEBUG_WINDING
|
#if DEBUG_WINDING
|
||||||
if (last) {
|
if (last) {
|
||||||
SkDebugf("%s last seg=%d span=%d", __FUNCTION__,
|
SkDebugf("%s last seg=%d span=%d", __FUNCTION__,
|
||||||
@ -949,11 +961,11 @@ SkOpSpanBase* SkOpSegment::markAngle(int maxWinding, int sumWinding, const SkOpA
|
|||||||
SkDebugf("\n");
|
SkDebugf("\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return last;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkOpSpanBase* SkOpSegment::markAngle(int maxWinding, int sumWinding, int oppMaxWinding,
|
bool SkOpSegment::markAngle(int maxWinding, int sumWinding, int oppMaxWinding,
|
||||||
int oppSumWinding, const SkOpAngle* angle) {
|
int oppSumWinding, const SkOpAngle* angle, SkOpSpanBase** result) {
|
||||||
SkASSERT(angle->segment() == this);
|
SkASSERT(angle->segment() == this);
|
||||||
if (UseInnerWinding(maxWinding, sumWinding)) {
|
if (UseInnerWinding(maxWinding, sumWinding)) {
|
||||||
maxWinding = sumWinding;
|
maxWinding = sumWinding;
|
||||||
@ -961,9 +973,10 @@ SkOpSpanBase* SkOpSegment::markAngle(int maxWinding, int sumWinding, int oppMaxW
|
|||||||
if (oppMaxWinding != oppSumWinding && UseInnerWinding(oppMaxWinding, oppSumWinding)) {
|
if (oppMaxWinding != oppSumWinding && UseInnerWinding(oppMaxWinding, oppSumWinding)) {
|
||||||
oppMaxWinding = oppSumWinding;
|
oppMaxWinding = oppSumWinding;
|
||||||
}
|
}
|
||||||
SkOpSpanBase* last = nullptr;
|
|
||||||
// caller doesn't require that this marks anything
|
// caller doesn't require that this marks anything
|
||||||
(void) markAndChaseWinding(angle->start(), angle->end(), maxWinding, oppMaxWinding, &last);
|
if (!markAndChaseWinding(angle->start(), angle->end(), maxWinding, oppMaxWinding, result)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#if DEBUG_WINDING
|
#if DEBUG_WINDING
|
||||||
if (last) {
|
if (last) {
|
||||||
SkDebugf("%s last segment=%d span=%d", __FUNCTION__,
|
SkDebugf("%s last segment=%d span=%d", __FUNCTION__,
|
||||||
@ -975,7 +988,7 @@ SkOpSpanBase* SkOpSegment::markAngle(int maxWinding, int sumWinding, int oppMaxW
|
|||||||
SkDebugf(" \n");
|
SkDebugf(" \n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return last;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkOpSegment::markDone(SkOpSpan* span) {
|
void SkOpSegment::markDone(SkOpSpan* span) {
|
||||||
|
@ -105,9 +105,9 @@ public:
|
|||||||
|
|
||||||
void calcAngles();
|
void calcAngles();
|
||||||
SkOpSpanBase::Collapsed collapsed(double startT, double endT) const;
|
SkOpSpanBase::Collapsed collapsed(double startT, double endT) const;
|
||||||
static void ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
|
static bool ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
|
||||||
SkOpAngle::IncludeType );
|
SkOpAngle::IncludeType );
|
||||||
static void ComputeOneSumReverse(SkOpAngle* baseAngle, SkOpAngle* nextAngle,
|
static bool ComputeOneSumReverse(SkOpAngle* baseAngle, SkOpAngle* nextAngle,
|
||||||
SkOpAngle::IncludeType );
|
SkOpAngle::IncludeType );
|
||||||
int computeSum(SkOpSpanBase* start, SkOpSpanBase* end, SkOpAngle::IncludeType includeType);
|
int computeSum(SkOpSpanBase* start, SkOpSpanBase* end, SkOpAngle::IncludeType includeType);
|
||||||
|
|
||||||
@ -279,9 +279,9 @@ public:
|
|||||||
SkOpSpanBase** lastPtr);
|
SkOpSpanBase** lastPtr);
|
||||||
bool markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding,
|
bool markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding,
|
||||||
int oppWinding, SkOpSpanBase** lastPtr);
|
int oppWinding, SkOpSpanBase** lastPtr);
|
||||||
SkOpSpanBase* markAngle(int maxWinding, int sumWinding, const SkOpAngle* angle);
|
bool markAngle(int maxWinding, int sumWinding, const SkOpAngle* angle, SkOpSpanBase** result);
|
||||||
SkOpSpanBase* markAngle(int maxWinding, int sumWinding, int oppMaxWinding, int oppSumWinding,
|
bool markAngle(int maxWinding, int sumWinding, int oppMaxWinding, int oppSumWinding,
|
||||||
const SkOpAngle* angle);
|
const SkOpAngle* angle, SkOpSpanBase** result);
|
||||||
void markDone(SkOpSpan* );
|
void markDone(SkOpSpan* );
|
||||||
bool markWinding(SkOpSpan* , int winding);
|
bool markWinding(SkOpSpan* , int winding);
|
||||||
bool markWinding(SkOpSpan* , int winding, int oppWinding);
|
bool markWinding(SkOpSpan* , int winding, int oppWinding);
|
||||||
|
@ -156,7 +156,8 @@ SkOpSegment* FindChase(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** startPtr,
|
|||||||
}
|
}
|
||||||
// OPTIMIZATION: should this also add to the chase?
|
// OPTIMIZATION: should this also add to the chase?
|
||||||
if (sortable) {
|
if (sortable) {
|
||||||
(void) segment->markAngle(maxWinding, sumWinding, angle);
|
// TODO: add error handling
|
||||||
|
SkAssertResult(segment->markAngle(maxWinding, sumWinding, angle, nullptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
static SkOpSegment* findChaseOp(SkTDArray<SkOpSpanBase*>& chase, SkOpSpanBase** startPtr,
|
static bool findChaseOp(SkTDArray<SkOpSpanBase*>& chase, SkOpSpanBase** startPtr,
|
||||||
SkOpSpanBase** endPtr) {
|
SkOpSpanBase** endPtr, SkOpSegment** result) {
|
||||||
while (chase.count()) {
|
while (chase.count()) {
|
||||||
SkOpSpanBase* span;
|
SkOpSpanBase* span;
|
||||||
chase.pop(&span);
|
chase.pop(&span);
|
||||||
@ -30,7 +30,8 @@ static SkOpSegment* findChaseOp(SkTDArray<SkOpSpanBase*>& chase, SkOpSpanBase**
|
|||||||
#else
|
#else
|
||||||
*chase.append() = span;
|
*chase.append() = span;
|
||||||
#endif
|
#endif
|
||||||
return last->segment();
|
*result = last->segment();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (done) {
|
if (done) {
|
||||||
continue;
|
continue;
|
||||||
@ -39,7 +40,8 @@ static SkOpSegment* findChaseOp(SkTDArray<SkOpSpanBase*>& chase, SkOpSpanBase**
|
|||||||
bool sortable;
|
bool sortable;
|
||||||
const SkOpAngle* angle = AngleWinding(*startPtr, *endPtr, &winding, &sortable);
|
const SkOpAngle* angle = AngleWinding(*startPtr, *endPtr, &winding, &sortable);
|
||||||
if (!angle) {
|
if (!angle) {
|
||||||
return nullptr;
|
*result = nullptr;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (winding == SK_MinS32) {
|
if (winding == SK_MinS32) {
|
||||||
continue;
|
continue;
|
||||||
@ -50,12 +52,14 @@ static SkOpSegment* findChaseOp(SkTDArray<SkOpSpanBase*>& chase, SkOpSpanBase**
|
|||||||
sumMiWinding = segment->updateWindingReverse(angle);
|
sumMiWinding = segment->updateWindingReverse(angle);
|
||||||
if (sumMiWinding == SK_MinS32) {
|
if (sumMiWinding == SK_MinS32) {
|
||||||
SkASSERT(segment->globalState()->debugSkipAssert());
|
SkASSERT(segment->globalState()->debugSkipAssert());
|
||||||
return nullptr;
|
*result = nullptr;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
sumSuWinding = segment->updateOppWindingReverse(angle);
|
sumSuWinding = segment->updateOppWindingReverse(angle);
|
||||||
if (sumSuWinding == SK_MinS32) {
|
if (sumSuWinding == SK_MinS32) {
|
||||||
SkASSERT(segment->globalState()->debugSkipAssert());
|
SkASSERT(segment->globalState()->debugSkipAssert());
|
||||||
return nullptr;
|
*result = nullptr;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (segment->operand()) {
|
if (segment->operand()) {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
@ -81,8 +85,10 @@ static SkOpSegment* findChaseOp(SkTDArray<SkOpSpanBase*>& chase, SkOpSpanBase**
|
|||||||
}
|
}
|
||||||
// OPTIMIZATION: should this also add to the chase?
|
// OPTIMIZATION: should this also add to the chase?
|
||||||
if (sortable) {
|
if (sortable) {
|
||||||
(void) segment->markAngle(maxWinding, sumWinding, oppMaxWinding,
|
if (!segment->markAngle(maxWinding, sumWinding, oppMaxWinding,
|
||||||
oppSumWinding, angle);
|
oppSumWinding, angle, nullptr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,10 +98,12 @@ static SkOpSegment* findChaseOp(SkTDArray<SkOpSpanBase*>& chase, SkOpSpanBase**
|
|||||||
#else
|
#else
|
||||||
*chase.append() = span;
|
*chase.append() = span;
|
||||||
#endif
|
#endif
|
||||||
return first;
|
*result = first;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
*result = nullptr;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool bridgeOp(SkOpContourHead* contourList, const SkPathOp op,
|
static bool bridgeOp(SkOpContourHead* contourList, const SkPathOp op,
|
||||||
@ -181,7 +189,9 @@ static bool bridgeOp(SkOpContourHead* contourList, const SkPathOp op,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current = findChaseOp(chase, &start, &end);
|
if (!findChaseOp(chase, &start, &end, ¤t)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
SkPathOpsDebug::ShowActiveSpans(contourList);
|
SkPathOpsDebug::ShowActiveSpans(contourList);
|
||||||
if (!current) {
|
if (!current) {
|
||||||
break;
|
break;
|
||||||
@ -347,10 +357,12 @@ bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result
|
|||||||
contourList->dumpSegments("aligned");
|
contourList->dumpSegments("aligned");
|
||||||
#endif
|
#endif
|
||||||
// construct closed contours
|
// construct closed contours
|
||||||
|
SkPath original = *result;
|
||||||
result->reset();
|
result->reset();
|
||||||
result->setFillType(fillType);
|
result->setFillType(fillType);
|
||||||
SkPathWriter wrapper(*result);
|
SkPathWriter wrapper(*result);
|
||||||
if (!bridgeOp(contourList, op, xorMask, xorOpMask, &wrapper)) {
|
if (!bridgeOp(contourList, op, xorMask, xorOpMask, &wrapper)) {
|
||||||
|
*result = original;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
wrapper.assemble(); // if some edges could not be resolved, assemble remaining
|
wrapper.assemble(); // if some edges could not be resolved, assemble remaining
|
||||||
|
@ -520,6 +520,11 @@ bool testSimplifyCheck(skiatest::Reporter* reporter, const SkPath& path, const c
|
|||||||
ExpectSuccess::kYes : ExpectSuccess::kNo, SkipAssert::kNo, ExpectMatch::kNo);
|
ExpectSuccess::kYes : ExpectSuccess::kNo, SkipAssert::kNo, ExpectMatch::kNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool testSimplifyFail(skiatest::Reporter* reporter, const SkPath& path, const char* filename) {
|
||||||
|
return inner_simplify(reporter, path, filename,
|
||||||
|
ExpectSuccess::kNo, SkipAssert::kYes, ExpectMatch::kNo);
|
||||||
|
}
|
||||||
|
|
||||||
#if DEBUG_SHOW_TEST_NAME
|
#if DEBUG_SHOW_TEST_NAME
|
||||||
static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) {
|
static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) {
|
||||||
SkDebugf("\n");
|
SkDebugf("\n");
|
||||||
|
@ -38,13 +38,15 @@ extern bool testPathOpCheck(skiatest::Reporter* reporter, const SkPath& a, const
|
|||||||
const SkPathOp , const char* testName, bool checkFail);
|
const SkPathOp , const char* testName, bool checkFail);
|
||||||
extern bool testPathOpFail(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
|
extern bool testPathOpFail(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
|
||||||
const SkPathOp, const char* testName);
|
const SkPathOp, const char* testName);
|
||||||
extern bool testPathOpFuzz(skiatest::Reporter* reporter, const SkPath& a,
|
extern bool testPathOpFuzz(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
|
||||||
const SkPath& b, const SkPathOp , const char* testName);
|
const SkPathOp , const char* testName);
|
||||||
extern bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state,
|
extern bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state,
|
||||||
const char* pathStr);
|
const char* pathStr);
|
||||||
extern bool testSimplify(skiatest::Reporter* reporter, const SkPath& path, const char* filename);
|
extern bool testSimplify(skiatest::Reporter* reporter, const SkPath& path, const char* filename);
|
||||||
extern bool testSimplifyCheck(skiatest::Reporter* reporter, const SkPath& path,
|
extern bool testSimplifyCheck(skiatest::Reporter* reporter, const SkPath& path,
|
||||||
const char* filename, bool checkFail);
|
const char* filename, bool checkFail);
|
||||||
|
extern bool testSimplifyFail(skiatest::Reporter* reporter, const SkPath& path,
|
||||||
|
const char* filename);
|
||||||
extern bool testSimplifyFuzz(skiatest::Reporter* reporter, const SkPath& path,
|
extern bool testSimplifyFuzz(skiatest::Reporter* reporter, const SkPath& path,
|
||||||
const char* filename);
|
const char* filename);
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user