mirror of
https://github.com/hexedtech/codemp-intellij.git
synced 2024-11-21 22:54:48 +01:00
fix: various fixes on vfs
This commit is contained in:
parent
c7b9594c11
commit
44d5c77383
8 changed files with 136 additions and 43 deletions
|
@ -45,7 +45,7 @@ public class FileUtil {
|
||||||
return CodeMP.getClient("buffer access")
|
return CodeMP.getClient("buffer access")
|
||||||
.getWorkspace(path.getWorkspaceName())
|
.getWorkspace(path.getWorkspaceName())
|
||||||
.flatMap(ws -> {
|
.flatMap(ws -> {
|
||||||
String[] matches = ws.getFileTree(Optional.of(path.getRealPath()));
|
String[] matches = ws.getFileTree(Optional.of(path.getRealPath()), true);
|
||||||
if(matches.length == 0) return Optional.empty();
|
if(matches.length == 0) return Optional.empty();
|
||||||
Optional<BufferController> controller = ws.getBuffer(path.getRealPath());
|
Optional<BufferController> controller = ws.getBuffer(path.getRealPath());
|
||||||
if(controller.isPresent()) return controller;
|
if(controller.isPresent()) return controller;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package mp.code.intellij.vfs;
|
package mp.code.intellij.vfs;
|
||||||
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import mp.code.intellij.CodeMP;
|
import mp.code.intellij.CodeMP;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -13,10 +12,10 @@ import java.util.Arrays;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class CodeMPFolder extends CodeMPFile {
|
public class CodeMPDirectory extends CodeMPFile {
|
||||||
|
|
||||||
public CodeMPFolder(CodeMPFileSystem fileSystem, CodeMPPath path) {
|
public CodeMPDirectory(CodeMPFileSystem fileSystem, CodeMPPath path) {
|
||||||
super(fileSystem, path);
|
super(fileSystem, path, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,7 +38,7 @@ public class CodeMPFolder extends CodeMPFile {
|
||||||
return CodeMP.getClient("get folder children")
|
return CodeMP.getClient("get folder children")
|
||||||
.getWorkspace(this.path.getWorkspaceName())
|
.getWorkspace(this.path.getWorkspaceName())
|
||||||
.map(ws ->
|
.map(ws ->
|
||||||
Arrays.stream(ws.getFileTree(Optional.of(this.path.getRealPath())))
|
Arrays.stream(ws.getFileTree(Optional.of(this.path.getRealPath()), false))
|
||||||
.map(p -> new CodeMPPath(this.path.getWorkspaceName(), p))
|
.map(p -> new CodeMPPath(this.path.getWorkspaceName(), p))
|
||||||
.map(CodeMPPath::join)
|
.map(CodeMPPath::join)
|
||||||
.map(this.fileSystem::findFileByPath)
|
.map(this.fileSystem::findFileByPath)
|
||||||
|
@ -80,4 +79,5 @@ public class CodeMPFolder extends CodeMPFile {
|
||||||
public @NotNull InputStream getInputStream() throws IOException {
|
public @NotNull InputStream getInputStream() throws IOException {
|
||||||
throw new RuntimeException("WHAT FOLDER INPUT");
|
throw new RuntimeException("WHAT FOLDER INPUT");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
package mp.code.intellij.vfs;
|
package mp.code.intellij.vfs;
|
||||||
|
|
||||||
import com.intellij.openapi.util.NlsSafe;
|
import com.intellij.ide.projectView.impl.ProjectTreeStructure;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
import com.intellij.openapi.vfs.VirtualFileWithId;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import mp.code.exceptions.ControllerException;
|
import mp.code.exceptions.ControllerException;
|
||||||
|
@ -22,9 +23,14 @@ import java.util.Optional;
|
||||||
public class CodeMPFile extends VirtualFile {
|
public class CodeMPFile extends VirtualFile {
|
||||||
protected final CodeMPFileSystem fileSystem;
|
protected final CodeMPFileSystem fileSystem;
|
||||||
protected final CodeMPPath path;
|
protected final CodeMPPath path;
|
||||||
|
protected final boolean isDirectory; // TODO exists ONLY for ez debugging, remove afterwards
|
||||||
|
|
||||||
|
public CodeMPFile(CodeMPFileSystem fs, CodeMPPath p) {
|
||||||
|
this(fs, p, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull @NlsSafe String getName() {
|
public @NotNull String getName() {
|
||||||
return this.path.getFileName();
|
return this.path.getFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,15 +53,15 @@ public class CodeMPFile extends VirtualFile {
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return CodeMP.getClient("validity check")
|
return CodeMP.getClient("validity check")
|
||||||
.getWorkspace(this.path.getWorkspaceName())
|
.getWorkspace(this.path.getWorkspaceName())
|
||||||
.map(ws -> ws.getFileTree(Optional.of(this.path.getRealPath())))
|
.map(ws -> ws.getFileTree(Optional.of(this.path.getRealPath()), true))
|
||||||
.map(buf -> buf.length != 0)
|
.map(buf -> buf.length != 0)
|
||||||
.orElse(false);
|
.orElse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable CodeMPFolder getParent() {
|
public @Nullable CodeMPDirectory getParent() {
|
||||||
return this.path.getParent()
|
return this.path.getParent()
|
||||||
.map(parent -> new CodeMPFolder(this.fileSystem, parent))
|
.map(parent -> new CodeMPDirectory(this.fileSystem, parent))
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package mp.code.intellij.vfs;
|
||||||
|
|
||||||
|
import com.intellij.platform.workspace.jps.entities.ModuleEntity;
|
||||||
|
import com.intellij.platform.workspace.storage.EntityStorage;
|
||||||
|
import com.intellij.workspaceModel.core.fileIndex.WorkspaceFileIndexContributor;
|
||||||
|
import com.intellij.workspaceModel.core.fileIndex.WorkspaceFileKind;
|
||||||
|
import com.intellij.workspaceModel.core.fileIndex.WorkspaceFileSetRegistrar;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@SuppressWarnings("UnstableApiUsage")
|
||||||
|
public class CodeMPFileIndexContributor implements WorkspaceFileIndexContributor<ModuleEntity> {
|
||||||
|
@Override
|
||||||
|
public @NotNull Class<ModuleEntity> getEntityClass() {
|
||||||
|
return ModuleEntity.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerFileSets(
|
||||||
|
@NotNull ModuleEntity moduleEntity,
|
||||||
|
@NotNull WorkspaceFileSetRegistrar workspaceFileSetRegistrar,
|
||||||
|
@NotNull EntityStorage entityStorage
|
||||||
|
) {
|
||||||
|
moduleEntity.getContentRoots().forEach(contentRootEntity -> {
|
||||||
|
workspaceFileSetRegistrar.registerFileSet(
|
||||||
|
contentRootEntity.getUrl(),
|
||||||
|
WorkspaceFileKind.CONTENT,
|
||||||
|
moduleEntity,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,8 +33,8 @@ import java.util.function.BiConsumer;
|
||||||
* - Already open remote module will crash if not for that janky try-catch in {@link #findFileByPath(String)}, maybe
|
* - Already open remote module will crash if not for that janky try-catch in {@link #findFileByPath(String)}, maybe
|
||||||
* try to connect quietly?
|
* try to connect quietly?
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter // implements NonPhysicalFileSystem?
|
||||||
public class CodeMPFileSystem extends VirtualFileSystem {
|
public class CodeMPFileSystem extends VirtualFileSystem { // implements NonPhysicalFileSystem {
|
||||||
public static String PROTOCOL = "codemp";
|
public static String PROTOCOL = "codemp";
|
||||||
private final Set<VirtualFileListener> listeners;
|
private final Set<VirtualFileListener> listeners;
|
||||||
|
|
||||||
|
@ -51,31 +51,30 @@ public class CodeMPFileSystem extends VirtualFileSystem {
|
||||||
public @Nullable CodeMPFile findFileByPath(@NotNull @NonNls String path) {
|
public @Nullable CodeMPFile findFileByPath(@NotNull @NonNls String path) {
|
||||||
CodeMPPath cmpPath = new CodeMPPath(path);
|
CodeMPPath cmpPath = new CodeMPPath(path);
|
||||||
try {
|
try {
|
||||||
return CodeMP.getClient("file seek")
|
return this.fileOrFolderByPath(cmpPath);
|
||||||
.getWorkspace(cmpPath.getWorkspaceName())
|
|
||||||
.filter(ws -> ws.getFileTree(Optional.of(cmpPath.getRealPath())).length != 0)
|
|
||||||
.map(ws -> new CodeMPFile(this, cmpPath))
|
|
||||||
.orElseGet(() -> new CodeMPFolder(this, cmpPath));
|
|
||||||
} catch(NotConnectedException ex) {
|
} catch(NotConnectedException ex) {
|
||||||
CodeMPSettings.State state = Objects.requireNonNull(CodeMPSettings.getInstance().getState());
|
|
||||||
Credentials credentials = Objects.requireNonNull(state.getCredentials());
|
|
||||||
try {
|
try {
|
||||||
|
CodeMPSettings.State state = Objects.requireNonNull(CodeMPSettings.getInstance().getState());
|
||||||
|
Credentials credentials = Objects.requireNonNull(state.getCredentials());
|
||||||
CodeMP.connect(
|
CodeMP.connect(
|
||||||
Objects.requireNonNull(state.getServerUrl()),
|
|
||||||
Objects.requireNonNull(credentials.getUserName()),
|
Objects.requireNonNull(credentials.getUserName()),
|
||||||
Objects.requireNonNull(credentials.getPasswordAsString())
|
Objects.requireNonNull(credentials.getPasswordAsString())
|
||||||
);
|
);
|
||||||
return CodeMP.getClient("file seek")
|
return this.fileOrFolderByPath(cmpPath);
|
||||||
.getWorkspace(cmpPath.getWorkspaceName())
|
} catch(ConnectionException | NullPointerException e) {
|
||||||
.filter(ws -> ws.getFileTree(Optional.of(cmpPath.getRealPath())).length != 0)
|
|
||||||
.map(ws -> new CodeMPFile(this, cmpPath))
|
|
||||||
.orElseGet(() -> new CodeMPFolder(this, cmpPath));
|
|
||||||
} catch(ConnectionException e) {
|
|
||||||
return null;
|
return null;
|
||||||
} // TODO this sucks
|
} // TODO this sucks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CodeMPFile fileOrFolderByPath(CodeMPPath cmpPath) {
|
||||||
|
return CodeMP.getClient("file seek")
|
||||||
|
.getWorkspace(cmpPath.getWorkspaceName())
|
||||||
|
.filter(ws -> ws.getFileTree(Optional.ofNullable(cmpPath.getRealPath()), true).length != 0).map(ws -> new CodeMPFile(this, cmpPath))
|
||||||
|
.orElseGet(() -> new CodeMPDirectory(this, cmpPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refresh(boolean asynchronous) {
|
public void refresh(boolean asynchronous) {
|
||||||
// TODO find out if and where ij stores filetree
|
// TODO find out if and where ij stores filetree
|
||||||
|
@ -127,7 +126,7 @@ public class CodeMPFileSystem extends VirtualFileSystem {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected @NotNull CodeMPFile createChildFile(Object requester, @NotNull VirtualFile vDir, @NotNull String fileName) throws IOException {
|
protected @NotNull CodeMPFile createChildFile(Object requester, @NotNull VirtualFile vDir, @NotNull String fileName) throws IOException {
|
||||||
if(vDir instanceof CodeMPFolder parent) {
|
if(vDir instanceof CodeMPDirectory parent) {
|
||||||
try {
|
try {
|
||||||
Optional<Workspace> ws = CodeMP.getClient("delete file").getWorkspace(parent.path.getWorkspaceName());
|
Optional<Workspace> ws = CodeMP.getClient("delete file").getWorkspace(parent.path.getWorkspaceName());
|
||||||
if(ws.isPresent()) {
|
if(ws.isPresent()) {
|
||||||
|
@ -147,13 +146,13 @@ public class CodeMPFileSystem extends VirtualFileSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected @NotNull CodeMPFolder createChildDirectory(
|
protected @NotNull CodeMPDirectory createChildDirectory(
|
||||||
Object requester,
|
Object requester,
|
||||||
@NotNull VirtualFile vDir,
|
@NotNull VirtualFile vDir,
|
||||||
@NotNull String dirName
|
@NotNull String dirName
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
if(vDir instanceof CodeMPFolder parent) {
|
if(vDir instanceof CodeMPDirectory parent) {
|
||||||
return new CodeMPFolder(
|
return new CodeMPDirectory(
|
||||||
this,
|
this,
|
||||||
parent.path.resolve(dirName)
|
parent.path.resolve(dirName)
|
||||||
);
|
);
|
||||||
|
@ -207,4 +206,6 @@ public class CodeMPFileSystem extends VirtualFileSystem {
|
||||||
public @Nullable Path getNioPath(@NotNull VirtualFile file) {
|
public @Nullable Path getNioPath(@NotNull VirtualFile file) {
|
||||||
return file.toNioPath();
|
return file.toNioPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package mp.code.intellij.vfs;
|
package mp.code.intellij.vfs;
|
||||||
|
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -16,6 +17,7 @@ import java.util.Optional;
|
||||||
* This helper class manages just that.
|
* This helper class manages just that.
|
||||||
*/
|
*/
|
||||||
@Getter @Setter
|
@Getter @Setter
|
||||||
|
@EqualsAndHashCode
|
||||||
public class CodeMPPath {
|
public class CodeMPPath {
|
||||||
/**
|
/**
|
||||||
* The name of the workspace that contains this path.
|
* The name of the workspace that contains this path.
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
<virtualFileSystem
|
<virtualFileSystem
|
||||||
id="codemp_vfs"
|
id="codemp_vfs"
|
||||||
key="codemp"
|
key="codemp"
|
||||||
|
physical="false"
|
||||||
implementationClass="mp.code.intellij.vfs.CodeMPFileSystem"/>
|
implementationClass="mp.code.intellij.vfs.CodeMPFileSystem"/>
|
||||||
<notificationGroup id="CodeMP" displayType="BALLOON"/>
|
<notificationGroup id="CodeMP" displayType="BALLOON"/>
|
||||||
<applicationService serviceImplementation="mp.code.intellij.settings.CodeMPSettings"/>
|
<applicationService serviceImplementation="mp.code.intellij.settings.CodeMPSettings"/>
|
||||||
|
@ -31,5 +32,6 @@
|
||||||
instance="mp.code.intellij.settings.CodeMPSettingsConfigurable"
|
instance="mp.code.intellij.settings.CodeMPSettingsConfigurable"
|
||||||
id="mp.code.intellij.settings.CodeMPSettingsConfigurable"
|
id="mp.code.intellij.settings.CodeMPSettingsConfigurable"
|
||||||
displayName="CodeMP"/>
|
displayName="CodeMP"/>
|
||||||
|
<workspaceModel.fileIndexContributor implementation="mp.code.intellij.vfs.CodeMPFileIndexContributor" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
||||||
|
|
|
@ -1,12 +1,62 @@
|
||||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<path d="M32.0845 7.94025V4H24.0203V7.9896H16.029V4H7.91553V7.94025H4V36H16.0044V32.0045C16.0058 30.9457 16.4274 29.9308 17.1766 29.1826C17.9258 28.4345 18.9412 28.0143 20 28.0143C21.0588 28.0143 22.0743 28.4345 22.8234 29.1826C23.5726 29.9308 23.9942 30.9457 23.9956 32.0045V36H36V7.94025H32.0845Z"
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
fill="url(#paint0_linear)"/>
|
|
||||||
<defs>
|
<svg
|
||||||
<linearGradient id="paint0_linear" x1="2.94192" y1="4.89955" x2="37.7772" y2="39.7345"
|
width="100mm"
|
||||||
gradientUnits="userSpaceOnUse">
|
height="100mm"
|
||||||
<stop offset="0.15937" stop-color="#3BEA62"/>
|
viewBox="0 0 100 100"
|
||||||
<stop offset="0.5404" stop-color="#3C99CC"/>
|
version="1.1"
|
||||||
<stop offset="0.93739" stop-color="#6B57FF"/>
|
id="svg1"
|
||||||
</linearGradient>
|
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
||||||
</defs>
|
sodipodi:docname="logo.svg"
|
||||||
</svg>
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#505050"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:zoom="1.3166807"
|
||||||
|
inkscape:cx="94.935697"
|
||||||
|
inkscape:cy="141.64406"
|
||||||
|
inkscape:window-width="1870"
|
||||||
|
inkscape:window-height="1006"
|
||||||
|
inkscape:window-x="25"
|
||||||
|
inkscape:window-y="45"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs1" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="matrix(0.98311673,0,0,0.98311673,-37.145524,-20.419013)"
|
||||||
|
style="stroke-width:0.50858661;stroke-dasharray:none;stroke:#000000;stroke-opacity:1;fill:#010101;fill-opacity:1">
|
||||||
|
<path
|
||||||
|
style="font-weight:bold;font-size:90.3111px;line-height:1.25;font-family:'Monoid HalfTight';-inkscape-font-specification:'Monoid HalfTight';fill:#010101;stroke:#000000;stroke-width:0.50858661;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
|
||||||
|
d="m 80.686333,71.922312 q 5.115277,1.940277 7.231943,5.409258 2.116667,3.468981 2.116667,9.995369 V 102.2024 q 0,2.82222 1.881481,3.99815 1.881481,1.11713 5.644443,1.11713 v 14.11111 q -10.524535,0 -16.580553,-4.70371 -5.997221,-4.7037 -5.997221,-14.52268 V 87.326939 q 0,-4.762499 -3.821758,-6.702777 -3.762963,-1.940277 -11.230091,-1.940277 V 64.572776 q 7.467128,0 11.230091,-1.940277 3.821758,-1.940278 3.821758,-6.702777 v -14.87546 q 0,-9.81898 5.997221,-14.522683 6.056018,-4.703703 16.580553,-4.703703 v 14.111109 q -3.762962,0 -5.644443,1.175925 -1.881481,1.11713 -1.881481,3.939352 v 14.87546 q 0,6.526388 -2.116667,9.995369 -2.116666,3.468981 -7.231943,5.409258 z"
|
||||||
|
id="text6"
|
||||||
|
inkscape:label="{"
|
||||||
|
aria-label="{" />
|
||||||
|
<path
|
||||||
|
style="font-weight:bold;font-size:33.8667px;line-height:1.25;font-family:'Monoid HalfTight';-inkscape-font-specification:'Monoid HalfTight';fill:#010101;stroke:#000000;stroke-width:0.50858661;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
|
||||||
|
d="m 103.39005,77.574239 v 8.995842 h 1.36701 q 1.89618,0 2.75608,-0.176389 1.49931,-0.308681 2.38125,-1.477258 0.904,-1.168578 0.904,-2.844274 0,-1.675696 -0.904,-2.844273 -0.88194,-1.168578 -2.38125,-1.477259 -0.8599,-0.176389 -2.75608,-0.176389 z m -5.644455,-5.291672 h 6.967365 q 3.2632,0 4.65226,0.33073 3.13091,0.749653 5.09324,3.285246 1.98438,2.513544 1.98438,6.173617 0,3.660073 -1.98438,6.195666 -1.96233,2.513544 -5.09324,3.263197 -1.38906,0.33073 -4.65226,0.33073 h -1.32291 v 11.465287 h -5.644455 z"
|
||||||
|
id="text4"
|
||||||
|
inkscape:label="P"
|
||||||
|
aria-label="P" />
|
||||||
|
<path
|
||||||
|
style="font-weight:bold;font-size:33.8667px;line-height:1.25;font-family:'Monoid HalfTight';-inkscape-font-specification:'Monoid HalfTight';fill:#010101;stroke:#000000;stroke-width:0.50858661;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
|
||||||
|
d="M 103.24182,69.128189 H 97.597369 V 38.083715 h 5.644451 l 4.12309,9.657301 h 0.24254 l 4.10104,-9.657301 h 5.64445 v 31.044474 h -5.64445 V 49.372615 h -0.22048 l -2.80018,5.644449 h -2.42535 l -2.80017,-5.732644 h -0.22049 z"
|
||||||
|
id="text5"
|
||||||
|
inkscape:label="M"
|
||||||
|
aria-label="M" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 818 B After Width: | Height: | Size: 3.8 KiB |
Loading…
Reference in a new issue