clean up some warnings
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
fb2c66e47e
commit
260e10ec9e
|
@ -8,6 +8,7 @@ public static class Extensions
|
|||
public static IEnumerable<T> Repeat<T>(this IEnumerable<T> sequence, int? count = null)
|
||||
{
|
||||
while (count == null || count-- > 0)
|
||||
// ReSharper disable once PossibleMultipleEnumeration
|
||||
foreach (var item in sequence)
|
||||
yield return item;
|
||||
}
|
||||
|
|
|
@ -41,17 +41,24 @@ public class Tree<T>(Tree<T>.Node root)
|
|||
set
|
||||
{
|
||||
if (value != null) value.Parent = this;
|
||||
if (Children.Count >= 2) Children[1] = value;
|
||||
else if (Children.Count == 0) Children.Add(null);
|
||||
switch (Children.Count)
|
||||
{
|
||||
case >= 2:
|
||||
Children[1] = value;
|
||||
break;
|
||||
case 0:
|
||||
Children.Add(null);
|
||||
break;
|
||||
}
|
||||
Children.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
public int DistanceToParent(Node parent)
|
||||
public int DistanceToParent(Node nodeParent)
|
||||
{
|
||||
var current = this;
|
||||
var dist = 0;
|
||||
while (current != parent)
|
||||
while (current != nodeParent)
|
||||
{
|
||||
dist++;
|
||||
current = current?.Parent;
|
||||
|
|
|
@ -35,5 +35,5 @@ public sealed partial class Day12() : Day(2015, 12, "JSAbacusFramework.io")
|
|||
|
||||
private long GetSum(JArray arr, string avoid) => arr.Sum((dynamic a) => (long)GetSum(a, avoid));
|
||||
|
||||
private long GetSum(JValue val, string avoid) => val.Type == JTokenType.Integer ? (long)(val.Value ?? 0L) : 0;
|
||||
private static long GetSum(JValue val, string avoid) => val.Type == JTokenType.Integer ? (long)(val.Value ?? 0L) : 0;
|
||||
}
|
|
@ -3,15 +3,18 @@ namespace AOC2015;
|
|||
/// <summary>
|
||||
/// Day 16: <a href="https://adventofcode.com/2015/day/16"/>
|
||||
/// </summary>
|
||||
public sealed class Day16() : Day(2015, 16, "Aunt Sue")
|
||||
public sealed partial class Day16() : Day(2015, 16, "Aunt Sue")
|
||||
{
|
||||
[GeneratedRegex(@": \d\d")]
|
||||
private static partial Regex TwoDigitsRegex();
|
||||
|
||||
public override void ProcessInput()
|
||||
{
|
||||
}
|
||||
|
||||
private IEnumerable<string> Common() =>
|
||||
Input
|
||||
.Select(i => Regex.Replace(i, @": \d\d", ": 9"))
|
||||
.Select(i => TwoDigitsRegex().Replace(i, ": 9"))
|
||||
.WhereMatch("children: 3")
|
||||
.WhereMatch("samoyeds: 2")
|
||||
.WhereMatch("akitas: 0")
|
||||
|
|
|
@ -18,7 +18,8 @@ public sealed class Day22() : Day(2015, 22, "Wizard Simulator 20XX")
|
|||
|
||||
private Dictionary<string, int> _boss;
|
||||
|
||||
public record Spell(
|
||||
private record Spell(
|
||||
// ReSharper disable once NotAccessedPositionalProperty.Local
|
||||
string Name,
|
||||
int Mana,
|
||||
int Duration = 0,
|
||||
|
@ -28,7 +29,7 @@ public sealed class Day22() : Day(2015, 22, "Wizard Simulator 20XX")
|
|||
int ManaCharge = 0
|
||||
);
|
||||
|
||||
public struct GameState(bool HardMode = false, int RoundNumber = 0, int TotalManaSpent = 0, int PlayerHealth = 50,
|
||||
private struct GameState(bool HardMode = false, int RoundNumber = 0, int TotalManaSpent = 0, int PlayerHealth = 50,
|
||||
int PlayerMana = 500, int BossHealth = 0, int BossDamage = 0, Dictionary<Spell, int>? ActiveSpells = null)
|
||||
{
|
||||
public GameResult DoTurn(Spell spell)
|
||||
|
@ -77,7 +78,7 @@ public sealed class Day22() : Day(2015, 22, "Wizard Simulator 20XX")
|
|||
}
|
||||
}
|
||||
|
||||
public enum GameResult
|
||||
private enum GameResult
|
||||
{
|
||||
Win,
|
||||
Loss,
|
||||
|
|
|
@ -15,15 +15,9 @@ public sealed partial class Day07() : Day(2016, 7, "Internet Protocol Version 7"
|
|||
{
|
||||
}
|
||||
|
||||
private static bool SupportsTls(string input)
|
||||
{
|
||||
foreach (var m in InsideBracketsRegex().Matches(input).Cast<Match>())
|
||||
{
|
||||
if (CheckAbba(m.ValueSpan)) return false;
|
||||
}
|
||||
|
||||
return BracketsRegex().Split(input).Any(v => CheckAbba(v));
|
||||
}
|
||||
private static bool SupportsTls(string input) =>
|
||||
!InsideBracketsRegex().Matches(input).Any(m => CheckAbba(m.ValueSpan)) &&
|
||||
BracketsRegex().Split(input).Any(v => CheckAbba(v));
|
||||
|
||||
private static bool CheckAbba(ReadOnlySpan<char> input)
|
||||
{
|
||||
|
@ -41,10 +35,10 @@ public sealed partial class Day07() : Day(2016, 7, "Internet Protocol Version 7"
|
|||
private static bool SupportsSsl(string input)
|
||||
{
|
||||
foreach (var ip in BracketsRegex().Split(input))
|
||||
foreach (var aba in CheckAba(ip))
|
||||
foreach (var m in InsideBracketsRegex().Matches(input).Cast<Match>())
|
||||
if (m.Value.Contains($"{aba[1]}{aba[0]}{aba[1]}"))
|
||||
return true;
|
||||
foreach (var aba in CheckAba(ip))
|
||||
foreach (var m in InsideBracketsRegex().Matches(input).Cast<Match>())
|
||||
if (m.Value.Contains($"{aba[1]}{aba[0]}{aba[1]}"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,6 @@ public sealed class Day05() : Day(2019, 5, "Sunny with a Chance of Asteroids")
|
|||
var i = 0;
|
||||
while (i < v.Count && v[i] != 99)
|
||||
{
|
||||
int Val(int mode, int val) => mode != 0 ? val : v[val];
|
||||
|
||||
var mode1 = v[i] / 100 % 10;
|
||||
var mode2 = v[i] / 1000;
|
||||
|
||||
|
@ -51,6 +49,10 @@ public sealed class Day05() : Day(2019, 5, "Sunny with a Chance of Asteroids")
|
|||
i += 4;
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
int Val(int mode, int val) => mode != 0 ? val : v[val];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,12 +36,6 @@ public sealed class Day10() : Day(2019, 10, "Monitoring Station")
|
|||
|
||||
public override object Part2()
|
||||
{
|
||||
static IEnumerable<(int x, int y, double angle, double dist)> GetValue(
|
||||
Queue<(int x, int y, double angle, double dist)> q)
|
||||
{
|
||||
if (q.Count > 0) yield return q.Dequeue();
|
||||
}
|
||||
|
||||
return _asteroids!
|
||||
.Where(a => a != _best)
|
||||
.Select(a =>
|
||||
|
@ -60,5 +54,11 @@ public sealed class Day10() : Day(2019, 10, "Monitoring Station")
|
|||
.Take(1)
|
||||
.Select(a => a.x * 100 + a.y)
|
||||
.Single();
|
||||
|
||||
static IEnumerable<(int x, int y, double angle, double dist)> GetValue(
|
||||
Queue<(int x, int y, double angle, double dist)> q)
|
||||
{
|
||||
if (q.Count > 0) yield return q.Dequeue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,7 @@ public sealed class Day14() : Day(2019, 14, "Space Stoichiometry")
|
|||
|
||||
private bool Consume(string chem, long quantity)
|
||||
{
|
||||
if (quantity <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(quantity));
|
||||
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(quantity);
|
||||
|
||||
_available.TryAdd(chem, 0);
|
||||
|
||||
|
@ -70,6 +69,7 @@ public sealed class Day14() : Day(2019, 14, "Space Stoichiometry")
|
|||
{
|
||||
public readonly Component Product;
|
||||
public readonly Component[] Reactants;
|
||||
private static readonly string[] Separators = [", ", " => "];
|
||||
|
||||
private Reaction(Component[] reactants, Component product)
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ public sealed class Day14() : Day(2019, 14, "Space Stoichiometry")
|
|||
|
||||
public static Reaction Parse(string s)
|
||||
{
|
||||
var ss = s.Split(new[] { ", ", " => " }, StringSplitOptions.None);
|
||||
var ss = s.Split(Separators, StringSplitOptions.None);
|
||||
|
||||
return new(
|
||||
ss.Take(ss.Length - 1).Select(ParseComponent).ToArray(),
|
||||
|
|
|
@ -34,7 +34,7 @@ public sealed class Day07() : Day(2020, 7, "Handy Haversacks")
|
|||
public override object Part1()
|
||||
{
|
||||
// breadth-first search with Queue
|
||||
var start = new Queue<string>(new[] { "shiny gold" });
|
||||
Queue<string> start = new(["shiny gold"]);
|
||||
var p = new HashSet<string>();
|
||||
string node;
|
||||
while (true)
|
||||
|
|
|
@ -9,6 +9,9 @@ public sealed class Day14() : Day(2020, 14, "Docking Data")
|
|||
{
|
||||
}
|
||||
|
||||
private static readonly char[] SquareBrackets = ['[', ']'];
|
||||
private static readonly char[] BracketsAndEquals = [..SquareBrackets, '='];
|
||||
|
||||
public override object Part1()
|
||||
{
|
||||
var writes = new Dictionary<ulong, ulong>();
|
||||
|
@ -32,7 +35,7 @@ public sealed class Day14() : Day(2020, 14, "Docking Data")
|
|||
}
|
||||
else
|
||||
{
|
||||
var spl = line.Split(new[] { '[', ']', '=' },
|
||||
var spl = line.Split(BracketsAndEquals,
|
||||
StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||
.Skip(1)
|
||||
.Select(ulong.Parse)
|
||||
|
@ -60,7 +63,7 @@ public sealed class Day14() : Day(2020, 14, "Docking Data")
|
|||
else
|
||||
{
|
||||
var value = ulong.Parse(spl[2]);
|
||||
var addr = ulong.Parse(spl[0].Split(new[] { '[', ']' },
|
||||
var addr = ulong.Parse(spl[0].Split(SquareBrackets,
|
||||
StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)[1]);
|
||||
|
||||
var floats = new List<int>();
|
||||
|
|
|
@ -58,7 +58,7 @@ public sealed class Day17() : Day(2020, 17, "Conway Cubes")
|
|||
{
|
||||
var active = Neighbors(prev, x, y, z);
|
||||
if (prev[(x, y, z)] == '#')
|
||||
next[(x, y, z)] = active == 2 || active == 3 ? '#' : '.';
|
||||
next[(x, y, z)] = active is 2 or 3 ? '#' : '.';
|
||||
else
|
||||
next[(x, y, z)] = active == 3 ? '#' : '.';
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ public sealed class Day17() : Day(2020, 17, "Conway Cubes")
|
|||
{
|
||||
var active = Neighbors4(prev, x, y, z, w);
|
||||
if (prev[(x, y, z, w)] == '#')
|
||||
next[(x, y, z, w)] = active == 2 || active == 3 ? '#' : '.';
|
||||
next[(x, y, z, w)] = active is 2 or 3 ? '#' : '.';
|
||||
else
|
||||
next[(x, y, z, w)] = active == 3 ? '#' : '.';
|
||||
}
|
||||
|
|
|
@ -20,23 +20,27 @@ public sealed class Day18() : Day(2020, 18, "Operation Order")
|
|||
{
|
||||
postfixNotation.Append(c);
|
||||
}
|
||||
else if (c == '(')
|
||||
else switch (c)
|
||||
{
|
||||
postfixStack.Push(c);
|
||||
}
|
||||
else if (c == ')')
|
||||
{
|
||||
while (postfixStack.Count > 0 && postfixStack.Peek() != '(')
|
||||
postfixNotation.Append(postfixStack.Pop());
|
||||
case '(':
|
||||
postfixStack.Push(c);
|
||||
break;
|
||||
case ')':
|
||||
{
|
||||
while (postfixStack.Count > 0 && postfixStack.Peek() != '(')
|
||||
postfixNotation.Append(postfixStack.Pop());
|
||||
|
||||
postfixStack.TryPop(out _);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (postfixStack.Count > 0 && precedence(c) <= precedence(postfixStack.Peek()))
|
||||
postfixNotation.Append(postfixStack.Pop());
|
||||
postfixStack.TryPop(out _);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
while (postfixStack.Count > 0 && precedence(c) <= precedence(postfixStack.Peek()))
|
||||
postfixNotation.Append(postfixStack.Pop());
|
||||
|
||||
postfixStack.Push(c);
|
||||
postfixStack.Push(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (postfixStack.Count > 0)
|
||||
|
@ -54,8 +58,15 @@ public sealed class Day18() : Day(2020, 18, "Operation Order")
|
|||
var a = expressionStack.Pop();
|
||||
var b = expressionStack.Pop();
|
||||
|
||||
if (c == '+') expressionStack.Push(a + b);
|
||||
if (c == '*') expressionStack.Push(a * b);
|
||||
switch (c)
|
||||
{
|
||||
case '+':
|
||||
expressionStack.Push(a + b);
|
||||
break;
|
||||
case '*':
|
||||
expressionStack.Push(a * b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return expressionStack.Pop();
|
||||
|
|
|
@ -3,8 +3,11 @@ namespace AOC2020;
|
|||
/// <summary>
|
||||
/// Day 20: <a href="https://adventofcode.com/2020/day/20" />
|
||||
/// </summary>
|
||||
public sealed class Day20() : Day(2020, 20, "Jurassic Jigsaw")
|
||||
public sealed partial class Day20() : Day(2020, 20, "Jurassic Jigsaw")
|
||||
{
|
||||
[GeneratedRegex("(?<=#.{77})#.{4}#{2}.{4}#{2}.{4}#{3}(?=.{77}#.{2}#.{2}#.{2}#.{2}#.{2}#)")]
|
||||
private static partial Regex MonsterRegex();
|
||||
|
||||
public override void ProcessInput()
|
||||
{
|
||||
}
|
||||
|
@ -51,14 +54,6 @@ public sealed class Day20() : Day(2020, 20, "Jurassic Jigsaw")
|
|||
var sides = new Dictionary<string, PuzzlePiece>();
|
||||
var connections = new Dictionary<PuzzlePiece, List<PuzzlePiece>>();
|
||||
|
||||
void AddConnection(PuzzlePiece p1, PuzzlePiece p2)
|
||||
{
|
||||
if (!connections.ContainsKey(p1)) connections.Add(p1, []);
|
||||
if (!connections.ContainsKey(p2)) connections.Add(p2, []);
|
||||
connections[p1].Add(p2);
|
||||
connections[p2].Add(p1);
|
||||
}
|
||||
|
||||
foreach (var piece in puzzlePieces)
|
||||
foreach (var (original, flipped) in piece.SidesWithFlippedPaired.Value)
|
||||
{
|
||||
|
@ -78,6 +73,14 @@ public sealed class Day20() : Day(2020, 20, "Jurassic Jigsaw")
|
|||
}
|
||||
|
||||
return connections;
|
||||
|
||||
void AddConnection(PuzzlePiece p1, PuzzlePiece p2)
|
||||
{
|
||||
if (!connections.ContainsKey(p1)) connections.Add(p1, []);
|
||||
if (!connections.ContainsKey(p2)) connections.Add(p2, []);
|
||||
connections[p1].Add(p2);
|
||||
connections[p2].Add(p1);
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<PuzzlePiece[]> ComposePuzzle(Dictionary<PuzzlePiece, List<PuzzlePiece>> connections)
|
||||
|
@ -171,10 +174,8 @@ public sealed class Day20() : Day(2020, 20, "Jurassic Jigsaw")
|
|||
|
||||
private static int CountSeaMonstersInImage(char[][] lines)
|
||||
{
|
||||
const string pattern = @"(?<=#.{77})#.{4}#{2}.{4}#{2}.{4}#{3}(?=.{77}#.{2}#.{2}#.{2}#.{2}#.{2}#)";
|
||||
var singleLine = lines.Aggregate("", (curr, next) => curr + new string(next));
|
||||
var matches = Regex.Matches(singleLine, pattern);
|
||||
return matches.Count;
|
||||
return MonsterRegex().Matches(singleLine).Count;
|
||||
}
|
||||
|
||||
private class PuzzlePiece
|
||||
|
@ -253,4 +254,6 @@ public sealed class Day20() : Day(2020, 20, "Jurassic Jigsaw")
|
|||
private static HashSet<string> CalculateAllSidesWithFlipped(PuzzlePiece piece) =>
|
||||
piece.Sides.Value.Concat(piece.Sides.Value.Select(s => new string(s.Reverse().ToArray()))).ToHashSet();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -34,9 +34,6 @@ public sealed class Day03() : Day(2021, 3, "Binary Diagnostic")
|
|||
var o = _report!;
|
||||
var c = _report!;
|
||||
|
||||
char MostCommon(int i, IReadOnlyCollection<string> report) =>
|
||||
report.Count(r => r[i] == '1') >= report.Count / 2.0 ? '1' : '0';
|
||||
|
||||
var i = 0;
|
||||
while (o.Count > 1)
|
||||
{
|
||||
|
@ -56,5 +53,8 @@ public sealed class Day03() : Day(2021, 3, "Binary Diagnostic")
|
|||
var co2 = c.Single().BigIntegerFromBinaryString();
|
||||
|
||||
return o2 * co2;
|
||||
|
||||
char MostCommon(int index, IReadOnlyCollection<string> report) =>
|
||||
report.Count(r => r[index] == '1') >= report.Count / 2.0 ? '1' : '0';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ public sealed class Day08() : Day(2021, 8, "Seven Segment Search")
|
|||
{
|
||||
private static readonly List<char[]> PossibleMappings =
|
||||
"abcdefg".ToCharArray().Permute().Select(m => m.ToArray()).ToList();
|
||||
private static readonly int[] SearchValues = { 2, 3, 4, 7 };
|
||||
|
||||
public override void ProcessInput()
|
||||
{
|
||||
|
@ -78,7 +79,7 @@ public sealed class Day08() : Day(2021, 8, "Seven Segment Search")
|
|||
public override object Part1() =>
|
||||
Input
|
||||
.Select(line => line.Split(" | ")[1].Split(' '))
|
||||
.Select(outputs => outputs.Count(o => new[] { 2, 3, 4, 7 }.Contains(o.Length)))
|
||||
.Select(outputs => outputs.Count(o => SearchValues.Contains(o.Length)))
|
||||
.Sum();
|
||||
|
||||
public override object Part2() => Input.Select(Decode).Sum();
|
||||
|
|
|
@ -41,12 +41,15 @@ public sealed class Day09() : Day(2021, 9, "Smoke Basin")
|
|||
var s = 0;
|
||||
var seen = new HashSet<(int x, int y)>();
|
||||
|
||||
MoreEnumerable.TraverseBreadthFirst((x, y), Traverse).Consume();
|
||||
sizes.Add(s);
|
||||
continue;
|
||||
|
||||
IEnumerable<(int x, int y)> Traverse((int x, int y) p)
|
||||
{
|
||||
var (i, j) = p;
|
||||
if (_map![j][i] == '9') yield break;
|
||||
if (seen.Contains((i, j))) yield break;
|
||||
seen.Add((i, j));
|
||||
if (!seen.Add((i, j))) yield break;
|
||||
s++;
|
||||
|
||||
if (j > 0)
|
||||
|
@ -58,9 +61,6 @@ public sealed class Day09() : Day(2021, 9, "Smoke Basin")
|
|||
if (i < _map[j].Length - 1)
|
||||
yield return (i + 1, j);
|
||||
}
|
||||
|
||||
MoreEnumerable.TraverseBreadthFirst((x, y), Traverse).Consume();
|
||||
sizes.Add(s);
|
||||
}
|
||||
|
||||
return sizes
|
||||
|
|
|
@ -13,10 +13,10 @@ public sealed class Day12() : Day(2021, 12, "Passage Pathing")
|
|||
{
|
||||
var s = line.Split('-', 2);
|
||||
|
||||
if (_edges.ContainsKey(s[0])) _edges[s[0]].Add(s[1]);
|
||||
if (_edges.TryGetValue(s[0], out var edge)) edge.Add(s[1]);
|
||||
else _edges[s[0]] = [s[1]];
|
||||
|
||||
if (_edges.ContainsKey(s[1])) _edges[s[1]].Add(s[0]);
|
||||
if (_edges.TryGetValue(s[1], out var edge2)) edge2.Add(s[0]);
|
||||
else _edges[s[1]] = [s[0]];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,10 +21,10 @@ public sealed class Day14() : Day(2021, 14, "Extended Polymerization")
|
|||
for (var i = 0; i < input.Length - 1; i++)
|
||||
{
|
||||
var k = input.Substring(i, 2);
|
||||
if (_substitutionPairs!.ContainsKey(k))
|
||||
if (_substitutionPairs!.TryGetValue(k, out var value))
|
||||
{
|
||||
result.Append(k[0]);
|
||||
result.Append(_substitutionPairs[k]);
|
||||
result.Append(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@ namespace AOC2023;
|
|||
|
||||
public class Day01() : Day(2023, 1, "Trebuchet?!")
|
||||
{
|
||||
private static readonly List<string> _singleDigits =
|
||||
private static readonly List<string> SingleDigits =
|
||||
["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
|
||||
|
||||
public override void ProcessInput()
|
||||
|
@ -25,7 +25,7 @@ public class Day01() : Day(2023, 1, "Trebuchet?!")
|
|||
continue;
|
||||
}
|
||||
|
||||
foreach (var (digit, spelled) in _singleDigits.Indexed())
|
||||
foreach (var (digit, spelled) in SingleDigits.Indexed())
|
||||
{
|
||||
if (i + spelled.Length - 1 < line.Length && line[i..(i + spelled.Length)] == spelled)
|
||||
{
|
||||
|
|
|
@ -27,9 +27,12 @@ EndProject
|
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FD88DFA6-FE18-466D-B249-14FE2817D45A}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.drone.yml = .drone.yml
|
||||
.editorconfig = .editorconfig
|
||||
.gitignore = .gitignore
|
||||
DayXX.cs.txt = DayXX.cs.txt
|
||||
getday.sh = getday.sh
|
||||
global.json = global.json
|
||||
LICENSE = LICENSE
|
||||
README.md = README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
|
Loading…
Reference in New Issue