renamed goals; added better merge-dirs
This commit is contained in:
parent
3788cdb4b6
commit
95c8e68d0d
0
src/it/append-dirs-nomerge/folder1/file11.txt → src/it/merge-dirs-complex/folder1/file11.txt
Normal file → Executable file
0
src/it/append-dirs-nomerge/folder1/file11.txt → src/it/merge-dirs-complex/folder1/file11.txt
Normal file → Executable file
0
src/it/append-dirs-nomerge/folder1/file12.txt → src/it/merge-dirs-complex/folder1/file12.txt
Normal file → Executable file
0
src/it/append-dirs-nomerge/folder1/file12.txt → src/it/merge-dirs-complex/folder1/file12.txt
Normal file → Executable file
0
src/it/append-dirs-nomerge/folder2/file11.txt → src/it/merge-dirs-complex/folder2/file11.txt
Normal file → Executable file
0
src/it/append-dirs-nomerge/folder2/file11.txt → src/it/merge-dirs-complex/folder2/file11.txt
Normal file → Executable file
0
src/it/append-dirs-nomerge/folder2/file21.txt → src/it/merge-dirs-complex/folder2/file21.txt
Normal file → Executable file
0
src/it/append-dirs-nomerge/folder2/file21.txt → src/it/merge-dirs-complex/folder2/file21.txt
Normal file → Executable file
79
src/it/merge-dirs-complex/pom.xml
Executable file
79
src/it/merge-dirs-complex/pom.xml
Executable file
@ -0,0 +1,79 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.inteligr8</groupId>
|
||||||
|
<artifactId>merge-maven-plugin-text-files</artifactId>
|
||||||
|
<version>@pom.version@</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<name>Text Files Plugin Tests</name>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>merge-maven-plugin</artifactId>
|
||||||
|
<version>@pom.version@</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>merge-simple</id>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>merge-dirs</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<filesets>
|
||||||
|
<fileset>
|
||||||
|
<directory>${basedir}</directory>
|
||||||
|
<includes>
|
||||||
|
<include>*</include>
|
||||||
|
</includes>
|
||||||
|
<excludes>
|
||||||
|
<exclude>*.log</exclude>
|
||||||
|
<exclude>pom.xml</exclude>
|
||||||
|
<exclude>target</exclude>
|
||||||
|
</excludes>
|
||||||
|
<outputDirectory>target</outputDirectory>
|
||||||
|
</fileset>
|
||||||
|
</filesets>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
|
<version>1.4.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>assert</id>
|
||||||
|
<goals><goal>enforce</goal></goals>
|
||||||
|
<configuration>
|
||||||
|
<rules>
|
||||||
|
<requireFilesSize>
|
||||||
|
<minsize>8</minsize>
|
||||||
|
<maxsize>15</maxsize>
|
||||||
|
<files>
|
||||||
|
<file>target/file11.txt</file>
|
||||||
|
</files>
|
||||||
|
</requireFilesSize>
|
||||||
|
<requireFilesSize>
|
||||||
|
<minsize>3</minsize>
|
||||||
|
<maxsize>8</maxsize>
|
||||||
|
<files>
|
||||||
|
<file>target/file12.txt</file>
|
||||||
|
<file>target/file21.txt</file>
|
||||||
|
</files>
|
||||||
|
</requireFilesSize>
|
||||||
|
</rules>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -20,10 +20,10 @@
|
|||||||
<version>@pom.version@</version>
|
<version>@pom.version@</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>append-simple</id>
|
<id>merge-simple</id>
|
||||||
<phase>validate</phase>
|
<phase>validate</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>append-dirs</goal>
|
<goal>merge-files</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<filesets>
|
<filesets>
|
@ -20,10 +20,10 @@
|
|||||||
<version>@pom.version@</version>
|
<version>@pom.version@</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>append-simple</id>
|
<id>merge-simple</id>
|
||||||
<phase>validate</phase>
|
<phase>validate</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>append-dirs</goal>
|
<goal>merge-files</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<filesets>
|
<filesets>
|
1
src/it/merge-files-simple/folder1/file11.txt
Normal file
1
src/it/merge-files-simple/folder1/file11.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
test1
|
1
src/it/merge-files-simple/folder1/file12.txt
Normal file
1
src/it/merge-files-simple/folder1/file12.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
test1
|
1
src/it/merge-files-simple/folder2/file11.txt
Normal file
1
src/it/merge-files-simple/folder2/file11.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
test2
|
1
src/it/merge-files-simple/folder2/file21.txt
Normal file
1
src/it/merge-files-simple/folder2/file21.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
test2
|
@ -20,10 +20,10 @@
|
|||||||
<version>@pom.version@</version>
|
<version>@pom.version@</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>append-simple</id>
|
<id>merge-simple</id>
|
||||||
<phase>validate</phase>
|
<phase>validate</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>append-dirs</goal>
|
<goal>merge-files</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<filesets>
|
<filesets>
|
@ -31,7 +31,7 @@ import org.apache.maven.plugin.MojoExecutionException;
|
|||||||
import org.apache.maven.plugins.annotations.Parameter;
|
import org.apache.maven.plugins.annotations.Parameter;
|
||||||
import org.apache.maven.project.MavenProject;
|
import org.apache.maven.project.MavenProject;
|
||||||
|
|
||||||
public abstract class AbstractAppendMojo extends AbstractMojo {
|
public abstract class AbstractFileContentMojo extends AbstractMojo {
|
||||||
|
|
||||||
@Parameter( defaultValue = "${project}", readonly = true )
|
@Parameter( defaultValue = "${project}", readonly = true )
|
||||||
protected MavenProject project;
|
protected MavenProject project;
|
116
src/main/java/com/inteligr8/maven/merge/AbstractMergeMojo.java
Executable file
116
src/main/java/com/inteligr8/maven/merge/AbstractMergeMojo.java
Executable file
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.inteligr8.maven.merge;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.FileVisitResult;
|
||||||
|
import java.nio.file.FileVisitor;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
|
import org.apache.maven.plugins.annotations.Parameter;
|
||||||
|
import org.apache.maven.shared.model.fileset.FileSet;
|
||||||
|
import org.apache.maven.shared.model.fileset.util.FileSetManager;
|
||||||
|
|
||||||
|
public abstract class AbstractMergeMojo extends AbstractFileContentMojo {
|
||||||
|
|
||||||
|
@Parameter( property = "filesets", required = true )
|
||||||
|
protected List<FileSet> filesets;
|
||||||
|
|
||||||
|
protected boolean mergeInFileSet(boolean directory) throws MojoExecutionException {
|
||||||
|
if (this.getLog().isDebugEnabled())
|
||||||
|
this.getLog().debug("merge " + (directory ? "directories" : "files"));
|
||||||
|
|
||||||
|
boolean didMerge = false;
|
||||||
|
FileSetManager fsman = new FileSetManager(this.getLog());
|
||||||
|
Path basepath = this.project.getBasedir().toPath();
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (FileSet fileSet : this.filesets) {
|
||||||
|
Path baseInputPath = this.resolveDirectory(basepath, fileSet.getDirectory(), false, "fileset input");
|
||||||
|
final Path baseOutputPath = this.resolveDirectory(basepath, fileSet.getOutputDirectory(), true, "fileset output");
|
||||||
|
|
||||||
|
String[] filePathsAndNames = directory ? fsman.getIncludedDirectories(fileSet) : fsman.getIncludedFiles(fileSet);
|
||||||
|
for (String filePathAndName : filePathsAndNames) {
|
||||||
|
Path file = baseInputPath.resolve(filePathAndName);
|
||||||
|
|
||||||
|
if (Files.isDirectory(file)) {
|
||||||
|
if (this.getLog().isDebugEnabled())
|
||||||
|
this.getLog().debug("merging directory: " + filePathAndName);
|
||||||
|
|
||||||
|
final Path baseDirInputPath = file;
|
||||||
|
|
||||||
|
Files.walkFileTree(file, new FileVisitor<Path>() {
|
||||||
|
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
|
||||||
|
return FileVisitResult.TERMINATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||||
|
Path filePathAndName = baseDirInputPath.relativize(file);
|
||||||
|
Path tofile = baseOutputPath.resolve(filePathAndName);
|
||||||
|
AbstractMergeMojo.this.mergeFile(file, tofile, Files.exists(tofile));
|
||||||
|
if (!Files.exists(tofile.getParent()))
|
||||||
|
Files.createDirectories(tofile.getParent());
|
||||||
|
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Path tofile = baseOutputPath.resolve(filePathAndName);
|
||||||
|
didMerge = this.mergeFile(file, tofile, didMerge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException ie) {
|
||||||
|
throw new MojoExecutionException("Execution failed due to an I/O related issue", ie);
|
||||||
|
}
|
||||||
|
|
||||||
|
return didMerge;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean mergeFile(Path file, Path tofile, boolean alreadyMergedOnce) throws IOException {
|
||||||
|
if (this.getLog().isDebugEnabled())
|
||||||
|
this.getLog().debug("merging file: '" + file + "' => '" + tofile + "'");
|
||||||
|
|
||||||
|
if (!Files.exists(tofile.getParent()))
|
||||||
|
Files.createDirectories(tofile.getParent());
|
||||||
|
|
||||||
|
if (alreadyMergedOnce && this.spacing > 0) {
|
||||||
|
StringBuilder strbuilder = new StringBuilder();
|
||||||
|
for (int s = 0; s < this.spacing; s++)
|
||||||
|
strbuilder.append(this.lineEnding);
|
||||||
|
if (strbuilder.length() > 0)
|
||||||
|
this.appendText(strbuilder.toString(), tofile);
|
||||||
|
}
|
||||||
|
|
||||||
|
alreadyMergedOnce = this.appendFileContent(file, tofile) || alreadyMergedOnce;
|
||||||
|
return alreadyMergedOnce;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.inteligr8.maven.merge;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.maven.plugin.MojoExecutionException;
|
|
||||||
import org.apache.maven.plugins.annotations.Mojo;
|
|
||||||
import org.apache.maven.plugins.annotations.Parameter;
|
|
||||||
import org.apache.maven.shared.model.fileset.FileSet;
|
|
||||||
import org.apache.maven.shared.model.fileset.util.FileSetManager;
|
|
||||||
import org.codehaus.plexus.component.annotations.Component;
|
|
||||||
|
|
||||||
@Mojo( name = "append-dirs", threadSafe = true )
|
|
||||||
@Component( role = org.apache.maven.plugin.Mojo.class )
|
|
||||||
public class AppendDirectoriesContentMojo extends AbstractAppendMojo {
|
|
||||||
|
|
||||||
@Parameter( property = "filesets", required = true )
|
|
||||||
protected List<FileSet> filesets;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute() throws MojoExecutionException {
|
|
||||||
this.getLog().debug("Executing file append");
|
|
||||||
|
|
||||||
this.appendContentInFileSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean appendContentInFileSet() throws MojoExecutionException {
|
|
||||||
boolean didMerge = false;
|
|
||||||
FileSetManager fsman = new FileSetManager(this.getLog());
|
|
||||||
Path basepath = this.project.getBasedir().toPath();
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (FileSet fileSet : this.filesets) {
|
|
||||||
Path baseInputPath = this.resolveDirectory(basepath, fileSet.getDirectory(), false, "fileset input");
|
|
||||||
Path baseOutputPath = this.resolveDirectory(basepath, fileSet.getOutputDirectory(), true, "fileset output");
|
|
||||||
|
|
||||||
String[] filePathsAndNames = fsman.getIncludedFiles(fileSet);
|
|
||||||
for (String filePathAndName : filePathsAndNames) {
|
|
||||||
Path file = baseInputPath.resolve(filePathAndName);
|
|
||||||
Path tofile = baseOutputPath.resolve(filePathAndName);
|
|
||||||
if (!Files.exists(tofile.getParent()))
|
|
||||||
Files.createDirectories(tofile.getParent());
|
|
||||||
|
|
||||||
if (!Files.isDirectory(file)) {
|
|
||||||
if (didMerge && this.spacing > 0) {
|
|
||||||
StringBuilder strbuilder = new StringBuilder();
|
|
||||||
for (int s = 0; s < this.spacing; s++)
|
|
||||||
strbuilder.append(this.lineEnding);
|
|
||||||
if (strbuilder.length() > 0)
|
|
||||||
this.appendText(strbuilder.toString(), tofile);
|
|
||||||
}
|
|
||||||
|
|
||||||
didMerge = this.appendFileContent(file, tofile) || didMerge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException ie) {
|
|
||||||
throw new MojoExecutionException("Execution failed due to an I/O related issue", ie);
|
|
||||||
}
|
|
||||||
|
|
||||||
return didMerge;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -28,7 +28,7 @@ import org.codehaus.plexus.component.annotations.Component;
|
|||||||
|
|
||||||
@Mojo( name = "append-files", threadSafe = true )
|
@Mojo( name = "append-files", threadSafe = true )
|
||||||
@Component( role = org.apache.maven.plugin.Mojo.class )
|
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||||
public class AppendFilesContentMojo extends AbstractAppendMojo {
|
public class AppendFilesContentMojo extends AbstractFileContentMojo {
|
||||||
|
|
||||||
@Parameter( property = "filesets", required = true )
|
@Parameter( property = "filesets", required = true )
|
||||||
protected List<FileSet> filesets;
|
protected List<FileSet> filesets;
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.inteligr8.maven.merge;
|
||||||
|
|
||||||
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
|
import org.apache.maven.plugins.annotations.Mojo;
|
||||||
|
import org.codehaus.plexus.component.annotations.Component;
|
||||||
|
|
||||||
|
@Mojo( name = "merge-dirs", threadSafe = true )
|
||||||
|
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||||
|
public class MergeDirectoriesMojo extends AbstractMergeMojo {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws MojoExecutionException {
|
||||||
|
this.getLog().debug("Executing directory merge");
|
||||||
|
|
||||||
|
this.mergeInFileSet(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
32
src/main/java/com/inteligr8/maven/merge/MergeFilesMojo.java
Executable file
32
src/main/java/com/inteligr8/maven/merge/MergeFilesMojo.java
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.inteligr8.maven.merge;
|
||||||
|
|
||||||
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
|
import org.apache.maven.plugins.annotations.Mojo;
|
||||||
|
import org.codehaus.plexus.component.annotations.Component;
|
||||||
|
|
||||||
|
@Mojo( name = "merge-files", threadSafe = true )
|
||||||
|
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||||
|
public class MergeFilesMojo extends AbstractMergeMojo {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws MojoExecutionException {
|
||||||
|
this.getLog().debug("Executing file merge");
|
||||||
|
|
||||||
|
this.mergeInFileSet(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -20,9 +20,9 @@ public class FileSetUnitTest {
|
|||||||
|
|
||||||
FileSetManager fsman = new FileSetManager();
|
FileSetManager fsman = new FileSetManager();
|
||||||
Set<String> files = new HashSet<>(Arrays.asList(fsman.getIncludedFiles(fileset)));
|
Set<String> files = new HashSet<>(Arrays.asList(fsman.getIncludedFiles(fileset)));
|
||||||
Assert.assertTrue(files.size() > 2);
|
Assert.assertTrue(files.size() > 4);
|
||||||
System.err.println(files);
|
System.err.println(files);
|
||||||
Assert.assertTrue(files.contains("com/inteligr8/maven/merge/AbstractAppendMojo.java".replace("/", File.separator)));
|
Assert.assertTrue(files.contains("com/inteligr8/maven/merge/AbstractMergeMojo.java".replace("/", File.separator)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user