diff --git a/FractalPainter/App/Program.cs b/FractalPainter/App/Program.cs index fc0c5bb28..c6aa3c128 100644 --- a/FractalPainter/App/Program.cs +++ b/FractalPainter/App/Program.cs @@ -1,6 +1,5 @@ using System; using System.Windows.Forms; -using Ninject; namespace FractalPainting.App { diff --git a/FractalPainter/fractalPainter.csproj b/FractalPainter/fractalPainter.csproj index b30602f95..a6aad5cb9 100644 --- a/FractalPainter/fractalPainter.csproj +++ b/FractalPainter/fractalPainter.csproj @@ -36,10 +36,16 @@ FractalPainting.App.Program + + ..\packages\Autofac.4.2.1\lib\net45\Autofac.dll + ..\packages\Castle.Core.3.2.0\lib\net45\Castle.Core.dll True + + ..\packages\FakeItEasy.3.0.0-beta002-build000066\lib\net40\FakeItEasy.dll + ..\packages\FluentAssertions.4.15.0\lib\net45\FluentAssertions.dll True diff --git a/FractalPainter/packages.config b/FractalPainter/packages.config index c4c2a676a..08ed79206 100644 --- a/FractalPainter/packages.config +++ b/FractalPainter/packages.config @@ -1,6 +1,8 @@  + + diff --git a/TagsCloudApp/TagsCloudApp/Core/CloudCreator.cs b/TagsCloudApp/TagsCloudApp/Core/CloudCreator.cs new file mode 100644 index 000000000..1af1b8f5d --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/CloudCreator.cs @@ -0,0 +1,31 @@ +using System.Drawing; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Core +{ + public class CloudCreator + { + private readonly ICloudBuilder cloudBuilder; + private readonly IFileReader reader; + private readonly IPrioritySetter prioritySetter; + private readonly ITextPreprocessor textPreprocessor; + + public CloudCreator(ICloudBuilder cloudBuilder, IFileReader reader, IPrioritySetter prioritySetter, + ITextPreprocessor textPreprocessor) + { + this.cloudBuilder = cloudBuilder; + this.reader = reader; + this.prioritySetter = prioritySetter; + this.textPreprocessor = textPreprocessor; + } + + public TagCloud Create(TagCloudSettings settings) + { + var words = reader.GetFileContetByWords(settings.PathToWords); + var processedWords = textPreprocessor.ProcessWords(words); + var priorities = prioritySetter.SetPriorities(processedWords, settings); + var size = settings.Size; + return new TagCloud(cloudBuilder.BuildCloud(priorities, new Point(size.Width / 2, size.Height / 2)), size); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Extensions/PointExtensions.cs b/TagsCloudApp/TagsCloudApp/Core/Extensions/PointExtensions.cs new file mode 100644 index 000000000..0f9f4c0c8 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Extensions/PointExtensions.cs @@ -0,0 +1,18 @@ +using System; +using System.Drawing; + +namespace TagsCloudApp.Core.Extensions +{ + public static class PointExtensions + { + public static Point SnapByX(this Point p) + { + return new Point(p.X / (p.X != 0 ? Math.Abs(p.X) : 1), 0); + } + + public static Point SnapByY(this Point p) + { + return new Point(0, p.Y / (p.Y != 0 ? Math.Abs(p.Y) : 1)); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Extensions/RectangleExtension.cs b/TagsCloudApp/TagsCloudApp/Core/Extensions/RectangleExtension.cs new file mode 100644 index 000000000..1939d57b9 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Extensions/RectangleExtension.cs @@ -0,0 +1,9 @@ +using System.Drawing; + +namespace TagsCloudApp.Core.Extensions +{ + public static class RectangleExtension + { + public static Point GetCenter(this Rectangle rect) => rect.Location + new Size(rect.Width / 2, rect.Height / 2); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/ICloudBuilder.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/ICloudBuilder.cs new file mode 100644 index 000000000..1af53567d --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/ICloudBuilder.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using System.Drawing; + +namespace TagsCloudApp.Core.Interfaces +{ + public interface ICloudBuilder + { + List BuildCloud(List cloudItems, Point newCenter); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IFileReader.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IFileReader.cs new file mode 100644 index 000000000..1a68ede63 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IFileReader.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace TagsCloudApp.Core.Interfaces +{ + public interface IFileReader + { + IEnumerable GetFileContetByWords(string path); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IPrioritySetter.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IPrioritySetter.cs new file mode 100644 index 000000000..5436acafa --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IPrioritySetter.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace TagsCloudApp.Core.Interfaces +{ + public interface IPrioritySetter + { + List SetPriorities(IEnumerable words, TagCloudSettings settings); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IRenderer.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IRenderer.cs new file mode 100644 index 000000000..6681e2fbd --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IRenderer.cs @@ -0,0 +1,10 @@ +using System.Drawing; + +namespace TagsCloudApp.Core.Interfaces +{ + public interface IRenderer + { + Image RenderImage(TagCloud cloud); + void SaveImageTo(string path, Image image); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/ITextPreprocessor.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/ITextPreprocessor.cs new file mode 100644 index 000000000..c5c90a843 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/ITextPreprocessor.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace TagsCloudApp.Core.Interfaces +{ + public interface ITextPreprocessor + { + List ProcessWords(IEnumerable words); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IVizualizer.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IVizualizer.cs new file mode 100644 index 000000000..901c1536f --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IVizualizer.cs @@ -0,0 +1,7 @@ +namespace TagsCloudApp.Core.Interfaces +{ + public interface IVizualizer + { + void RunVizualizer(); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/TagCloud.cs b/TagsCloudApp/TagsCloudApp/Core/TagCloud.cs new file mode 100644 index 000000000..39bc6bf8e --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/TagCloud.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.Drawing; + +namespace TagsCloudApp.Core +{ + public class TagCloud + { + private readonly List items; + public Size Size { get; } + public IEnumerable Items => items.AsReadOnly(); + + public TagCloud(List items, Size size) + { + this.items = items; + Size = size; + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/TagCloudItem.cs b/TagsCloudApp/TagsCloudApp/Core/TagCloudItem.cs new file mode 100644 index 000000000..01a680000 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/TagCloudItem.cs @@ -0,0 +1,29 @@ +using System; +using System.Drawing; + +namespace TagsCloudApp.Core +{ + public class TagCloudItem + { + public readonly WordInfo WordInfo; + public readonly Color Color; + public readonly Font Font; + public readonly Rectangle Rectangle; + + public TagCloudItem(Color color, WordInfo wordInfo, Font font, Rectangle rectangle) + { + Color = color; + WordInfo = wordInfo; + Font = font; + Rectangle = rectangle; + } + + public TagCloudItem SetRectangle(Rectangle newRectangle) => new TagCloudItem(Color, WordInfo, Font, newRectangle); + + public static TagCloudItem GetRandomFontSize(Random rnd) + { + return new TagCloudItem(Color.AliceBlue, new WordInfo("", 100), new Font("Menlo", rnd.Next(int.MaxValue)), + default(Rectangle)); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/TagCloudSettings.cs b/TagsCloudApp/TagsCloudApp/Core/TagCloudSettings.cs new file mode 100644 index 000000000..8afe44d0d --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/TagCloudSettings.cs @@ -0,0 +1,25 @@ +using System.Drawing; + +namespace TagsCloudApp.Core +{ + public class TagCloudSettings + { + public static readonly TagCloudSettings DefaultSettings = + new TagCloudSettings(new Font("Meslo", 10), Color.GreenYellow, "test.txt", "test", new Size(500, 500)); + + public Font Font { get; set; } + public Color Color { get; set; } + public string PathToWords { get; set; } + public string PathToSave { get; set; } + public Size Size { get; set; } + + public TagCloudSettings(Font font, Color color, string pathToWords, string pathToSave, Size size) + { + Font = font; + Color = color; + PathToWords = pathToWords; + PathToSave = pathToSave; + Size = size; + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/WordInfo.cs b/TagsCloudApp/TagsCloudApp/Core/WordInfo.cs new file mode 100644 index 000000000..a4604d107 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/WordInfo.cs @@ -0,0 +1,41 @@ +namespace TagsCloudApp.Core +{ + public class WordInfo + { + public readonly string Word; + public readonly double Frequency; + + public WordInfo(string word, double frequency) + { + Word = word; + Frequency = frequency; + } + + private bool Equals(WordInfo other) + { + return string.Equals(Word, other.Word); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + return obj.GetType() == GetType() && Equals((WordInfo) obj); + } + + public override int GetHashCode() + { + return Word?.GetHashCode() ?? 0; + } + + public static bool operator ==(WordInfo left, WordInfo right) + { + return Equals(left, right); + } + + public static bool operator !=(WordInfo left, WordInfo right) + { + return !Equals(left, right); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/CircularCloudBuilder.cs b/TagsCloudApp/TagsCloudApp/Implementations/CircularCloudBuilder.cs new file mode 100644 index 000000000..0acc9b178 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/CircularCloudBuilder.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Extensions; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + public class CircularCloudBuilder : ICloudBuilder + { + private Point center; + private Spiral spiral; + private Rectangle cloudBorders; + + private List PlacedRectangles { get; set; } + + private Point Center + { + set + { + if (value.X < 0 || value.Y < 0) + throw new ArgumentException("Center point should be non-negative"); + center = value; + } + } + + public CircularCloudBuilder() + { + PlacedRectangles = new List(); + } + + private void InitCloud(Point newCenter) + { + Center = newCenter; + spiral = new Spiral(newCenter); + cloudBorders = new Rectangle(0, 0, newCenter.X * 2, newCenter.Y * 2); + PlacedRectangles = new List(); + } + + public List BuildCloud(List cloudItems, Point newCenter) + { + InitCloud(newCenter); + + var placedItems = new List(); + foreach (var cloudItem in cloudItems) + try + { + placedItems.Add(cloudItem.SetRectangle(PutNextRectangle(cloudItem.Rectangle.Size))); + } + catch (ArgumentException) + { + break; + } + return placedItems; + } + + private Rectangle PutNextRectangle(Size rectangleSize) + { + if (rectangleSize.Height <= 0 || rectangleSize.Width <= 0) + throw new ArgumentException($"Size must be positive {rectangleSize}"); + + var nextRectangle = FindNextRectanglePosition(rectangleSize); + if (nextRectangle.IsEmpty) return nextRectangle; + + nextRectangle = MoveToCenter(nextRectangle); + PlacedRectangles.Add(nextRectangle); + return nextRectangle; + } + + private Rectangle FindNextRectanglePosition(Size rectangleSize) + { + var nextRectangle = new Rectangle(GetRectangleCenterLocation(rectangleSize, spiral.GetNextSpiralPoint()), + rectangleSize); + + while (!IsInValidPosition(nextRectangle)) + { + var nextSpiralPoint = spiral.GetNextSpiralPoint(); + nextRectangle = new Rectangle(GetRectangleCenterLocation(rectangleSize, nextSpiralPoint), rectangleSize); + if (!cloudBorders.Contains(nextSpiralPoint)) + throw new ArgumentException("Can't place rectangle because cloud is too small"); + } + + return nextRectangle; + } + + private static Point GetRectangleCenterLocation(Size rectangleSize, Point nextSpiralPoint) + { + return new Point(nextSpiralPoint.X - rectangleSize.Width / 2, nextSpiralPoint.Y - rectangleSize.Height / 2); + } + + private bool IsInValidPosition(Rectangle checkingRectangle) + { + return !PlacedRectangles.Any(rect => rect.IntersectsWith(checkingRectangle)) && + cloudBorders.Contains(checkingRectangle); + } + + private Rectangle MoveToCenter(Rectangle rectangle) + { + var newRectangle = Rectangle.Empty; + while (rectangle != newRectangle) + { + if (!newRectangle.IsEmpty) + rectangle = newRectangle; + var vectorToCenter = center - new Size(rectangle.GetCenter()); + newRectangle = TryMove(rectangle, vectorToCenter.SnapByX()); + newRectangle = TryMove(newRectangle, vectorToCenter.SnapByY()); + } + return rectangle; + } + + private Rectangle TryMove(Rectangle rectangle, Point shift) + { + var newRect = new Rectangle(rectangle.Location + new Size(shift), rectangle.Size); + if (IsInValidPosition(newRect)) + rectangle = newRect; + return rectangle; + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/ConsoleVizualizer.cs b/TagsCloudApp/TagsCloudApp/Implementations/ConsoleVizualizer.cs new file mode 100644 index 000000000..8ce093ee8 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/ConsoleVizualizer.cs @@ -0,0 +1,40 @@ +using System; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + public class ConsoleVizualizer : IVizualizer + { + private readonly CloudCreator creator; + private readonly TagCloudSettings settings; + private string cmd; + + public ConsoleVizualizer(CloudCreator creator, TagCloudSettings settings) + { + this.creator = creator; + this.settings = settings; + cmd = ""; + } + + private void DrawCloud() + { + var cloud = creator.Create(settings); + foreach (var cloudItem in cloud.Items) + Console.WriteLine($"\"{cloudItem.WordInfo.Word}\" count = {cloudItem.WordInfo.Frequency}"); + } + + public void RunVizualizer() + { + while (cmd != "exit") + { + Console.Clear(); + if (cmd == "draw") + DrawCloud(); + else if (cmd == "help") + Console.WriteLine("Type 'draw' to draw cloud"); + cmd = Console.ReadLine(); + } + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/Gui/SettingsForm.cs b/TagsCloudApp/TagsCloudApp/Implementations/Gui/SettingsForm.cs new file mode 100644 index 000000000..8cf2b6b35 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/Gui/SettingsForm.cs @@ -0,0 +1,31 @@ +using System; +using System.Windows.Forms; + +namespace TagsCloudApp.Implementations.Gui +{ + public class SettingsForm : Form + { + public SettingsForm(TSettings settings) + { + var okButton = new Button + { + Text = "OK", + DialogResult = DialogResult.OK, + Dock = DockStyle.Bottom, + }; + Controls.Add(okButton); + Controls.Add(new PropertyGrid + { + SelectedObject = settings, + Dock = DockStyle.Fill + }); + AcceptButton = okButton; + } + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + Text = "Settings"; + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/Gui/WinFormVizualizer.cs b/TagsCloudApp/TagsCloudApp/Implementations/Gui/WinFormVizualizer.cs new file mode 100644 index 000000000..2e321e311 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/Gui/WinFormVizualizer.cs @@ -0,0 +1,65 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations.Gui +{ + public class WinFormVizualizer : IVizualizer + { + private readonly CloudCreator creator; + private readonly IRenderer renderer; + private readonly TagCloudSettings settings; + private Image image; + private readonly Form form; + + public WinFormVizualizer(CloudCreator creator, IRenderer renderer, TagCloudSettings settings) + { + this.creator = creator; + this.renderer = renderer; + this.settings = settings; + form = new Form(); + InitForm(); + MessageBox.Show("To change settings press 'n'\nTo save cloud press 's'"); + DrawCloud(); + } + + private void InitForm() + { + form.KeyPress += (o, e) => + { + if (e.KeyChar == 'n') + { + new SettingsForm(settings).ShowDialog(); + DrawCloud(); + } + else if (e.KeyChar == 's') + renderer.SaveImageTo(settings.PathToSave, image); + }; + form.Paint += (o, e) => { + e.Graphics.DrawImage(image, new Point(0, 0)); + form.Size = image.Size; + }; + } + + private void DrawCloud() + { + try + { + image = renderer.RenderImage(creator.Create(settings)); + form.Invalidate(); + form.Show(); + } + catch (ArgumentException ex) + { + MessageBox.Show(ex.Message); + } + } + + public void RunVizualizer() + { + Application.Run(form); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/LogarithmicPrioritySetter.cs b/TagsCloudApp/TagsCloudApp/Implementations/LogarithmicPrioritySetter.cs new file mode 100644 index 000000000..dcff922f1 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/LogarithmicPrioritySetter.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + public class SamePrioritySetter : IPrioritySetter + { + public List SetPriorities(IEnumerable words, TagCloudSettings settings) + { + var wordInfos = new HashSet(words); + var g = Graphics.FromImage(new Bitmap(1, 1)); + + var minFontSize = settings.Font.Size; + const int offset = 10; + return wordInfos + .Select(word => + { + var font = new Font(settings.Font.FontFamily, (float) (minFontSize * Math.Max(1, Math.Log(word.Frequency)))); + var size = g.MeasureString(word.Word, font).ToSize(); + return new TagCloudItem(settings.Color, word, + font, new Rectangle(0, 0, size.Width + offset, size.Height + offset)); + }) + .ToList(); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/PngRenderer.cs b/TagsCloudApp/TagsCloudApp/Implementations/PngRenderer.cs new file mode 100644 index 000000000..94d647c13 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/PngRenderer.cs @@ -0,0 +1,33 @@ +using System.Drawing; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + public class PngRenderer : IRenderer + { + public Image RenderImage(TagCloud cloud) + { + var image = new Bitmap(cloud.Size.Width, cloud.Size.Height); + var g = Graphics.FromImage(image); + g.FillRectangle(Brushes.Black, new Rectangle(new Point(0, 0), cloud.Size)); + + foreach (var cloudItem in cloud.Items) + g.DrawString(cloudItem); + return image; + } + + public void SaveImageTo(string path, Image image) + { + image.Save(path + ".png"); + } + } + + internal static class GraphicsExtension + { + public static void DrawString(this Graphics g, TagCloudItem item) + { + g.DrawString(item.WordInfo.Word, item.Font, new SolidBrush(item.Color), item.Rectangle); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/SimpleTextPreprocessor.cs b/TagsCloudApp/TagsCloudApp/Implementations/SimpleTextPreprocessor.cs new file mode 100644 index 000000000..196c9104e --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/SimpleTextPreprocessor.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Linq; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + public class SimpleTextPreprocessor : ITextPreprocessor + { + private static readonly HashSet StopWords = new HashSet + { + "he", + "she", + "and", + "it", + "aboard", + "about", + "above", + "across", + "after", + "against", + "along", + "amid", + "among", + "anti", + "around", + "as", + "at", + "before", + "behind", + "below", + "beneath", + "beside", + "besides", + "between", + "beyond", + "but", + "by", + "concerning", + "considering", + "despite", + "down", + "during", + "except", + "excepting", + "excluding", + "following", + "for", + "from", + "in", + "inside", + "into", + "like", + "minus", + "near", + "of", + "off", + "on", + "onto", + "opposite", + "outside", + "over", + "past", + "per", + "plus", + "regarding", + "round", + "save", + "since", + "than", + "the", + "through", + "to", + "toward", + "towards", + "under", + "underneath", + "unlike", + "until", + "up", + "upon", + "versus", + "via", + "with", + "within", + "without" + }; + + public List ProcessWords(IEnumerable words) + { + return words.Select(w => w.ToLowerInvariant()) + .Where(CheckWord) + .GroupBy(word => word) + .Select(kv => new WordInfo(kv.Key, kv.Count())) + .ToList(); + } + + private static bool CheckWord(string word) + { + return !(StopWords.Contains(word) || word.Length < 2 || + string.IsNullOrWhiteSpace(word) || string.IsNullOrEmpty(word)); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/Spiral.cs b/TagsCloudApp/TagsCloudApp/Implementations/Spiral.cs new file mode 100644 index 000000000..fd404ede6 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/Spiral.cs @@ -0,0 +1,39 @@ +using System; +using System.Drawing; + +namespace TagsCloudApp.Implementations +{ + public class Spiral + { + private readonly Point center; + private readonly double deltaAngle; + private readonly double deltaRadius; + private Point currentPoint; + + public double CurrentAngle { get; set; } + + public double CurrentRadius { get; set; } + + public Spiral(Point center, double deltaAngle = Math.PI / 180, double deltaRadius = 0.001) + { + this.center = center; + this.deltaAngle = deltaAngle; + this.deltaRadius = deltaRadius; + currentPoint = this.center; + CurrentAngle = 0; + CurrentRadius = 0; + } + + public Point GetNextSpiralPoint() + { + var prevPoint = currentPoint; + CurrentAngle += deltaAngle; + CurrentRadius += deltaRadius; + + var newX = (int) (CurrentRadius * Math.Cos(CurrentAngle) + center.X); + var newY = (int) (CurrentRadius * Math.Sin(CurrentAngle) + center.Y); + currentPoint = new Point(newX, newY); + return prevPoint; + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/TxtReader.cs b/TagsCloudApp/TagsCloudApp/Implementations/TxtReader.cs new file mode 100644 index 000000000..8b45701d7 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/TxtReader.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.IO; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + public class TxtReader : IFileReader + { + public IEnumerable GetFileContetByWords(string path) + { + return File.ReadAllLines(path); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Program.cs b/TagsCloudApp/TagsCloudApp/Program.cs new file mode 100644 index 000000000..cf7a40650 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Program.cs @@ -0,0 +1,25 @@ +using System.Reflection; +using Autofac; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp +{ + internal static class Program + { + public static void Main() + { + var builder = new ContainerBuilder(); + var asm = Assembly.GetExecutingAssembly(); + builder.RegisterAssemblyTypes(asm) + .AsImplementedInterfaces(); + builder.RegisterType().AsSelf(); + builder.RegisterInstance(TagCloudSettings.DefaultSettings).As().SingleInstance(); + + var container = builder.Build(); + + using (var scope = container.BeginLifetimeScope()) + scope.Resolve().RunVizualizer(); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Properties/AssemblyInfo.cs b/TagsCloudApp/TagsCloudApp/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..fa1d8d4ec --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Properties/AssemblyInfo.cs @@ -0,0 +1,39 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly: AssemblyTitle("TagsCloudApp")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TagsCloudApp")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly: Guid("32340528-0E6D-4CA1-8048-545865F527B1")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] + +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj b/TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj new file mode 100644 index 000000000..510afd2db --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj @@ -0,0 +1,108 @@ + + + + + Debug + AnyCPU + {32340528-0E6D-4CA1-8048-545865F527B1} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Exe + Properties + TagsCloudApp + TagsCloudApp + v4.5 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\Autofac.4.2.1\lib\net45\Autofac.dll + + + ..\..\packages\FakeItEasy.3.0.0-beta002-build000066\lib\net40\FakeItEasy.dll + + + ..\..\packages\FluentAssertions.4.18.0\lib\net45\FluentAssertions.dll + + + ..\..\packages\FluentAssertions.4.18.0\lib\net45\FluentAssertions.Core.dll + + + ..\..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + + + + + + \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Test/CircularCloudLayouter_Should.cs b/TagsCloudApp/TagsCloudApp/Test/CircularCloudLayouter_Should.cs new file mode 100644 index 000000000..d513313aa --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Test/CircularCloudLayouter_Should.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using FluentAssertions; +using NUnit.Framework; +using TagsCloudApp.Core; +using TagsCloudApp.Implementations; + +namespace TagsCloudApp.Test +{ + [TestFixture] + internal class CircularCloudLayouter_Should + { + [Test] + public void PlaceRectWOIntersection_WhenBuildCloudCalls() + { + var cloud = new CircularCloudBuilder(); + + var placed = cloud.BuildCloud(GenerateRectangleSizes(10, 1).ToList(), new Point(1000, 1000)); + + placed + .SelectMany(r1 => placed, + (r2, r1) => r1.Rectangle.IntersectsWith(r2.Rectangle)) + .Any(r => r) + .Should().BeFalse(); + } + + + private static IEnumerable GenerateRectangleSizes(int numberOfRectangles, int seed) + { + var rand = new Random(seed); + return Enumerable.Range(0, numberOfRectangles) + .Select(i => TagCloudItem.GetRandomFontSize(rand)); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Test/CloudCreator_Should.cs b/TagsCloudApp/TagsCloudApp/Test/CloudCreator_Should.cs new file mode 100644 index 000000000..8bbbda7ff --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Test/CloudCreator_Should.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using FakeItEasy; +using NUnit.Framework; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Test +{ + [TestFixture] + public class CloudCreator_Should + { + [Test] + public void DoSomething_WhenSomething() + { + var builder = A.Fake(); + var reader = A.Fake(); + var prioritySetter = A.Fake(); + var textPreprocessor = A.Fake(); + var creator = new CloudCreator(builder, reader, prioritySetter, textPreprocessor); + var random = new Random(1); + + A.CallTo(() => reader.GetFileContetByWords(null)) + .WithAnyArguments() + .Returns(new List {"one", "two", "three"}); + A.CallTo(() => textPreprocessor.ProcessWords(null)) + .WithAnyArguments() + .Returns(new List {new WordInfo("one", 1), new WordInfo("two", 1)}); + A.CallTo(() => prioritySetter.SetPriorities(null, null)) + .WithAnyArguments() + .Returns(new List {TagCloudItem.GetRandomFontSize(random)}); + A.CallTo(() => builder.BuildCloud(null, default(Point))) + .WithAnyArguments() + .Returns(new List {TagCloudItem.GetRandomFontSize(random)}); + + creator.Create(TagCloudSettings.DefaultSettings); + + A.CallTo(() => reader.GetFileContetByWords(null)) + .WithAnyArguments() + .MustHaveHappened(Repeated.Exactly.Once); + A.CallTo(() => textPreprocessor.ProcessWords(null)) + .WithAnyArguments() + .MustHaveHappened(Repeated.Exactly.Once); + A.CallTo(() => prioritySetter.SetPriorities(null, null)) + .WithAnyArguments() + .MustHaveHappened(Repeated.Exactly.Once); + A.CallTo(() => builder.BuildCloud(null, default(Point))) + .WithAnyArguments() + .MustHaveHappened(Repeated.Exactly.Once); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Test/FunctionalTest.cs b/TagsCloudApp/TagsCloudApp/Test/FunctionalTest.cs new file mode 100644 index 000000000..8c4f591b2 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Test/FunctionalTest.cs @@ -0,0 +1,29 @@ +using System.Drawing; +using System.IO; +using System.Linq; +using FluentAssertions; +using NUnit.Framework; +using TagsCloudApp.Core; +using TagsCloudApp.Implementations; + +namespace TagsCloudApp.Test +{ + [TestFixture] + public class FunctionalTest + { + [Test] + public void TestCloudCreation() + { + var creator = new CloudCreator(new CircularCloudBuilder(), new TxtReader(), new SamePrioritySetter(), + new SimpleTextPreprocessor()); + var tagCloudSettings = new TagCloudSettings(new Font("Arial", 5), Color.Beige, + Path.Combine(TestContext.CurrentContext.TestDirectory, "Test", "test.txt"), + "for_test", new Size(1000, 1000)); + + var cloud = creator.Create(tagCloudSettings); + + cloud.Items.Any().Should().BeTrue(); + cloud.Size.Should().Be(tagCloudSettings.Size); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Test/SimpleTextPreprocessor_Should.cs b/TagsCloudApp/TagsCloudApp/Test/SimpleTextPreprocessor_Should.cs new file mode 100644 index 000000000..012a0107f --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Test/SimpleTextPreprocessor_Should.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using NUnit.Framework; +using TagsCloudApp.Implementations; + +namespace TagsCloudApp.Test +{ + [TestFixture] + public class SimpleTextPreprocessor_Should + { + private SimpleTextPreprocessor proc; + + [SetUp] + public void SetUp() + { + proc = new SimpleTextPreprocessor(); + } + + [Test] + public void RemoveStopWords() + { + var words = new List {"He", "was", "shocked", "off"}; + + var processed = proc.ProcessWords(words); + + processed.Select(w => w.Word).Should().NotContain("He"); + } + + [Test] + public void CalculateWordCount() + { + var words = new List {"He", "was", "He", "was", "He", "He", "He"}; + + var processed = proc.ProcessWords(words); + + Console.WriteLine(1); + processed.First(w => w.Word == "was").Frequency.Should().Be(2); + } + + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Test/Spiral_Should.cs b/TagsCloudApp/TagsCloudApp/Test/Spiral_Should.cs new file mode 100644 index 000000000..d1bee50e2 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Test/Spiral_Should.cs @@ -0,0 +1,24 @@ +using System.Drawing; +using FluentAssertions; +using NUnit.Framework; +using TagsCloudApp.Implementations; + +namespace TagsCloudApp.Test +{ + [TestFixture] + public class Spiral_Should + { + [Test] + public void IncrementAngleAndRadiusByDelta_OnNextStep() + { + const int deltaAngle = 1; + const int deltaRadius = 2; + var spiral = new Spiral(new Point(100, 100), deltaAngle, deltaRadius); + var previousAngle = spiral.CurrentAngle; + var previousRadius = spiral.CurrentRadius; + spiral.GetNextSpiralPoint(); + (spiral.CurrentAngle - previousAngle).Should().Be(deltaAngle); + (spiral.CurrentRadius - previousRadius).Should().Be(deltaRadius); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Test/test.txt b/TagsCloudApp/TagsCloudApp/Test/test.txt new file mode 100644 index 000000000..dbf9ceb7c --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Test/test.txt @@ -0,0 +1,1716 @@ +Twenty +miles +west +of +Tucson +the +Sunset +Express +stopped +at +a +tank +to +take +on +water +Besides +the +aqueous +addition +the +engine +of +that +famous +flyer +acquired +some +other +things +that +were +not +good +for +it +While +the +fireman +was +lowering +the +feeding +hose +Bob +Tidball +Shark +Dodson +and +a +quarterbred +Creek +Indian +called +John +Big +Dog +climbed +on +the +engine +and +showed +the +engineer +three +round +orifices +in +pieces +of +ordnance +that +they +carried +These +orifices +so +impressed +the +engineer +with +their +possibilities +that +he +raised +both +hands +in +a +gesture +such +as +accompanies +the +ejaculation +Do +tell +At +the +crisp +command +of +Shark +Dodson +who +was +leader +of +the +attacking +force +the +engineer +descended +to +the +ground +and +uncoupled +the +engine +and +tender +Then +John +Big +Dog +perched +upon +the +coal +sportively +held +two +guns +upon +the +engine +driver +and +the +fireman +and +suggested +that +they +run +the +engine +fifty +yards +away +and +there +await +further +orders +Shark +Dodson +and +Bob +Tidball +scorning +to +put +such +lowgrade +ore +as +the +passengers +through +the +mill +struck +out +for +the +rich +pocket +of +the +express +car +They +found +the +messenger +serene +in +the +belief +that +the +Sunset +Express +was +taking +on +nothing +more +stimulating +and +dangerous +than +aqua +pura +While +Bob +was +knocking +this +idea +out +of +his +head +with +the +buttend +of +his +sixshooter +Shark +Dodson +was +already +dosing +the +expresscar +safe +with +dynamite +The +safe +exploded +to +the +tune +of +30000 +all +gold +and +currency +The +passengers +thrust +their +heads +casually +out +of +the +windows +to +look +for +the +thundercloud +The +conductor +jerked +at +the +bellrope +which +sagged +down +loose +and +unresisting +at +his +tug +Shark +Dodson +and +Bob +Tidball +with +their +booty +in +a +stout +canvas +bag +tumbled +out +of +the +express +car +and +ran +awkwardly +in +their +highheeled +boots +to +the +engine +The +engineer +sullenly +angry +but +wise +ran +the +engine +according +to +orders +rapidly +away +from +the +inert +train +But +before +this +was +accomplished +the +express +messenger +recovered +from +Bob +Tidballs +persuader +to +neutrality +jumped +out +of +his +car +with +a +Winchester +rifle +and +took +a +trick +in +the +game +Mr +John +Big +Dog +sitting +on +the +coal +tender +unwittingly +made +a +wrong +lead +by +giving +an +imitation +of +a +target +and +the +messenger +trumped +him +With +a +ball +exactly +between +his +shoulder +blades +the +Creek +chevalier +of +industry +rolled +off +to +the +ground +thus +increasing +the +share +of +his +comrades +in +the +loot +by +onesixth +each +Two +miles +from +the +tank +the +engineer +was +ordered +to +stop +The +robbers +waved +a +defiant +adieu +and +plunged +down +the +steep +slope +into +the +thick +woods +that +lined +the +track +Five +minutes +of +crashing +through +a +thicket +of +chaparral +brought +them +to +open +woods +where +three +horses +were +tied +to +lowhanging +branches +One +was +waiting +for +John +Big +Dog +who +would +never +ride +by +night +or +day +again +This +animal +the +robbers +divested +of +saddle +and +bridle +and +set +free +They +mounted +the +other +two +with +the +bag +across +one +pommel +and +rode +fast +and +with +discretion +through +the +forest +and +up +a +primeval +lonely +gorge +Here +the +animal +that +bore +Bob +Tidball +slipped +on +a +mossy +boulder +and +broke +a +foreleg +They +shot +him +through +the +head +at +once +and +sat +down +to +hold +a +council +of +flight +Made +secure +for +the +present +by +the +tortuous +trail +they +had +travelled +the +question +of +time +was +no +longer +so +big +Many +miles +and +hours +lay +between +them +and +the +spryest +posse +that +could +follow +Shark +Dodsons +horse +with +trailing +rope +and +dropped +bridle +panted +and +cropped +thankfully +of +the +grass +along +the +stream +in +the +gorge +Bob +Tidball +opened +the +sack +drew +out +double +handfuls +of +the +neat +packages +of +currency +and +the +one +sack +of +gold +and +chuckled +with +the +glee +of +a +child +Say +you +old +doubledecked +pirate +he +called +joyfully +to +Dodson +you +said +we +could +do +it +you +got +a +head +for +financing +that +knocks +the +horns +off +of +anything +in +Arizona +What +are +we +going +to +do +about +a +hoss +for +you +Bob +We +aint +got +long +to +wait +here +Theyll +be +on +our +trail +before +daylight +in +the +mornin +Oh +I +guess +that +cayuse +of +yournll +carry +double +for +a +while +answered +the +sanguine +Bob +Well +annex +the +first +animal +we +come +across +By +jingoes +we +made +a +haul +didnt +we +Accordin +to +the +marks +on +this +money +theres +30000 +15000 +apiece +Its +short +of +what +I +expected +said +Shark +Dodson +kicking +softly +at +the +packages +with +the +toe +of +his +boot +And +then +he +looked +pensively +at +the +wet +sides +of +his +tired +horse +Old +Bolivars +mighty +nigh +played +out +he +said +slowly +I +wish +that +sorrel +of +yours +hadnt +got +hurt +So +do +I +said +Bob +heartily +but +it +cant +be +helped +Bolivars +got +plenty +of +bottom +hell +get +us +both +far +enough +to +get +fresh +mounts +Dang +it +Shark +I +cant +help +thinkin +how +funny +it +is +that +an +Easterner +like +you +can +come +out +here +and +give +us +Western +fellows +cards +and +spades +in +the +desperado +business +What +part +of +the +East +was +you +from +anyway +New +York +State +said +Shark +Dodson +sitting +down +on +a +boulder +and +chewing +a +twig +I +was +born +on +a +farm +in +Ulster +County +I +ran +away +from +home +when +I +was +seventeen +It +was +an +accident +my +coming +West +I +was +walkin +along +the +road +with +my +clothes +in +a +bundle +makin +for +New +York +City +I +had +an +idea +of +goin +there +and +makin +lots +of +money +I +always +felt +like +I +could +do +it +I +came +to +a +place +one +evenin +where +the +road +forked +and +I +didnt +know +which +fork +to +take +I +studied +about +it +for +half +an +hour +and +then +I +took +the +lefthand +That +night +I +run +into +the +camp +of +a +Wild +West +show +that +was +travellin +among +the +little +towns +and +I +went +West +with +it +Ive +often +wondered +if +I +wouldnt +have +turned +out +different +if +Id +took +the +other +road +Oh +I +reckon +youd +have +ended +up +about +the +same +said +Bob +Tidball +cheerfully +philosophical +It +aint +the +roads +we +take;its +whats +inside +of +us +that +makes +us +turn +out +the +way +we +do +Shark +Dodson +got +up +and +leaned +against +a +tree +Id +a +good +deal +rather +that +sorrel +of +yourn +hadnt +hurt +himself +Bob +he +said +again +almost +pathetically +Same +here +agreed +Bob;he +was +sure +a +firstrate +kind +of +a +crowbait +But +Bolivar +hell +pull +us +through +all +right +Reckon +wed +better +be +movin +on +hadnt +we +Shark +Ill +bag +this +boodle +agin +and +well +hit +the +trail +for +higher +timber +Bob +Tidball +replaced +the +spoil +in +the +bag +and +tied +the +mouth +of +it +tightly +with +a +cord +When +he +looked +up +the +most +prominent +object +that +he +saw +was +the +muzzle +of +Shark +Dodsons +45 +held +upon +him +without +a +waver +Stop +your +funnin +said +Bob +with +a +grin +We +got +to +be +hittin +the +breeze +Set +still +said +Shark +You +aint +goin +to +hit +no +breeze +Bob +I +hate +to +tell +you +but +there +aint +any +chance +for +but +one +of +us +Bolivar +hes +plenty +tired +and +he +cant +carry +double +We +been +pards +me +and +you +Shark +Dodson +for +three +year +Bob +said +quietly +Weve +risked +our +lives +together +time +and +again +Ive +always +give +you +a +square +deal +and +I +thought +you +was +a +man +Ive +heard +some +queer +stories +about +you +shootin +one +or +two +men +in +a +peculiar +way +but +I +never +believed +em +Now +if +youre +just +havin +a +little +fun +with +me +Shark +put +your +gun +up +and +well +get +on +Bolivar +and +vamose +If +you +mean +to +shoot +shoot +you +blackhearted +son +of +a +tarantula +Shark +Dodsons +face +bore +a +deeply +sorrowful +look +You +dont +know +how +bad +I +feel +he +sighed +about +that +sorrel +of +yourn +breakin +his +leg +Bob +The +expression +on +Dodsons +face +changed +in +an +instant +to +one +of +cold +ferocity +mingled +with +inexorable +cupidity +The +soul +of +the +man +showed +itself +for +a +moment +like +an +evil +face +in +the +window +of +a +reputable +house +Truly +Bob +Tidball +was +never +to +hit +the +breeze +again +The +deadly +45 +of +the +false +friend +cracked +and +filled +the +gorge +with +a +roar +that +the +walls +hurled +back +with +indignant +echoes +And +Bolivar +unconscious +accomplice +swiftly +bore +away +the +last +of +the +holdersup +of +the +Sunset +Express +not +put +to +the +stress +of +carrying +double +But +as +Shark +Dodson +galloped +away +the +woods +seemed +to +fade +from +his +view;the +revolver +in +his +right +hand +turned +to +the +curved +arm +of +a +mahogany +chair;his +saddle +was +strangely +upholstered +and +he +opened +his +eyes +and +saw +his +feet +not +in +stirrups +but +resting +quietly +on +the +edge +of +a +quarteredoak +desk +I +am +telling +you +that +Dodson +of +the +firm +of +Dodson +&Decker +Wall +Street +brokers +opened +his +eyes +Peabody +the +confidential +clerk +was +standing +by +his +chair +hesitating +to +speak +There +was +a +confused +hum +of +wheels +below +and +the +sedative +buzz +of +an +electric +fan +Ahem +Peabody +said +Dodson +blinking +I +must +have +fallen +asleep +I +had +a +most +remarkable +dream +What +is +it +Peabody +Mr +Williams +sir +of +Tracy +&Williams +is +outside +He +has +come +to +settle +his +deal +in +X +Y +Z +The +market +caught +him +short +sir +if +you +remember +Yes +I +remember +What +is +X +Y +Z +quoted +at +today +Peabody +One +eightyfive +sir +Then +thats +his +price +Excuse +me +said +Peabody +rather +nervously +for +speaking +of +it +but +Ive +been +talking +to +Williams +Hes +an +old +friend +of +yours +Mr +Dodson +and +you +practically +have +a +corner +in +X +Y +Z +I +thought +you +might +that +is +I +thought +you +might +not +remember +that +he +sold +you +the +stock +at +98 +If +he +settles +at +the +market +price +it +will +take +every +cent +he +has +in +the +world +and +his +home +too +to +deliver +the +shares +The +expression +on +Dodsons +face +changed +in +an +instant +to +one +of +cold +ferocity +mingled +with +inexorable +cupidity +The +soul +of +the +man +showed +itself +for +a +moment +like +an +evil +face +in +the +window +of +a +reputable +house +He +will +settle +at +one +eightyfive +said +Dodson +Bolivar +cannot +carry +double \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/packages.config b/TagsCloudApp/TagsCloudApp/packages.config new file mode 100644 index 000000000..b7ecabef7 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/di.sln b/di.sln index 9e820827b..638b84521 100644 --- a/di.sln +++ b/di.sln @@ -10,6 +10,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution README.md = README.md EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TagsCloudApp", "TagsCloudApp\TagsCloudApp\TagsCloudApp.csproj", "{32340528-0E6D-4CA1-8048-545865F527B1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -20,6 +22,10 @@ Global {2A3ACF0E-1D07-4A1A-8320-F99DC2DE791F}.Debug|Any CPU.Build.0 = Debug|Any CPU {2A3ACF0E-1D07-4A1A-8320-F99DC2DE791F}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A3ACF0E-1D07-4A1A-8320-F99DC2DE791F}.Release|Any CPU.Build.0 = Release|Any CPU + {32340528-0E6D-4CA1-8048-545865F527B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {32340528-0E6D-4CA1-8048-545865F527B1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {32340528-0E6D-4CA1-8048-545865F527B1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {32340528-0E6D-4CA1-8048-545865F527B1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE