Microsoft takes on IFTTT with Flow

microsoft-flow

IFTTT is one of the most useful online services. Today, Microsoft is taking on IFTTT with its new service called “Flow”. The company is launching the preview of Flow today, and it works almost like IFTTT.

Unlike IFTTT, Flow isn’t mostly focused on consumers — instead, it’s mostly focused on enterprise integrations. Flow lets you automate your workflow, and be more productive. With Flow, you can setup GitHub to automatically send a Slack notification and add a card in Trello when a new issue is submitted. Additionally, you can also archive your tweets to OneDrive, which is also an interesting flow. There are more than 35 connections available on Flow.

Microsoft Flow is live right now, and you can check it out here.

Microsoft open sources Xamarin's software development kit

XamarinOpne

Two months after being acquired by Microsoft, cross-platform development-tool vendor Xamarin is continuing to push the open-source envelope.

On April 27 at Xamarin's Evolve developer conference in Orlando, officials announced Microsoft has open-sourced the Xamarin software development kit (SDK).

At Microsoft's Build 2016 developers conference last month, Microsoft announced intentions to open source the Xamarin SDK, runtime, libraries and command line tools. Microsoft also announced it would make Xamarin part of the various Visual Studio releases at no additional cost.

Today, company officials said Microsoft has open sourced and contributed to the .NET Foundation the Xamarin SDK for Android, iOS and Mac under the same MIT license used for the Mono project. The native application program interface (API) bindings for iOS, Android and Mac, the command-line tools necessary to build for these platforms, and the cross-platform UI framework Xamarin.Forms are all part of what's now open sourced.

Microsoft also is working to help Xamarin developers more easily connect Visual Studio to Mac so they can create iOS apps natively in C#. Xamarin's iOS Simulator remoting allows developers to simulate and interact with their iOS apps in Visual Studio, with support for touch screens. And its iOS USB remoting allows devs to deploy and debug apps from Visual Studio to an iPad or iPhone plugged into their Windows PCs.

Microsoft also unveiled some new Xamarin.Forms features; enhancements to the Xamarin Studio IDE to bring it closer to Visual Studio; and a Test Recorder Visual Studio plug-in at Evolve.

Windows 10 Anniversary Update Targeted For Late July Release

Hero-Desktop-1024x576

It may seem obvious but Microsoft is planning to release the Anniversary update for Windows 10 in late July. While the company has not explicitly said when it will be released, insiders at the company have acknowledged that the current road map is for the update to be finalized in mid-July.

As with all timelines, the release date could change, especially since we are a few months out and road maps are used for guidance and are not always hard dates. Considering that Windows 10 was released on July 29th, it would make sense that the company would release the Anniversary update on or around that date; the 29th is a Friday.

The last couple of Windows 10 builds have been packed with new features that should make most end-users happy. Everything from a new dark theme, although it’s far from perfect, to new Cortana features, enhancements to the Action Center, an updated Start menu and a lot more are coming in this release.

At this time, Microsoft still has a few more tricks up its sleeve, although they are small features, that will be coming with the update when it arrives. But, as we get closer to the release date, expect new feature introduction to slow down and a focus on bug bashing to spin up.

Earlier this week, Microsoft released a new build of Windows 10, 14332, that you can view here.

Remove multiple line in the same file with C#

Read the file, remove the multiple line (but it saves one of them) in memory and put the contents back to the file (overwriting) and create a backup file with the original file.

 

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace DelMultiLine {
   class Program {
      static void Main(string[] args) {
         if (args.Count() == 0 || args.Count() > 2) {
            Console.WriteLine("\nDelMultiLine (by Enrico Rossini - puresourcecode.com)");
            Console.WriteLine("-----------------------------------------------------------------------");
            Console.WriteLine("Remove duplicate line in a file\n");
            Console.WriteLine("Usage:");
            Console.WriteLine("   delmultiline <Filename> <resultFilename>\n");
            Console.WriteLine("filename:       define a full path for the file you want to elaborate");
            Console.WriteLine("resultFilename: define the full path for the original file for a backup");
            Environment.Exit(0);
         }

         string file1 = args[0];
         string file2 = "";

         if (args.Count() == 1) {
            if (string.IsNullOrEmpty(file2)) {
               file2 = file1 + ".old";
            }
            else {
               file2 = args[1];
            }
         }

         Console.WriteLine(string.Format("Reading {0} in progress...", args[0]));
         string[] lines = File.ReadAllLines(file1);
         List<string> newline = new List<string>();

         for (int i = 0; i < lines.Length; i++) {
            newline.Add(lines[i]);
         }

         Console.WriteLine("Deleting multiple line in progress...");
         for (int i = 0; i < lines.Length; i++) {
            List<string> temp = new List<string>();
            int duplicate_count = 0;

            for (int j = newline.Count - 1; j >= 0; j--) {
               //checking for duplicate records
               if (lines[i] != newline[j])
                  temp.Add(newline[j]);
               else {
                  duplicate_count++;
                  if (duplicate_count == 1)
                     temp.Add(lines[i]);
               }
            }
            newline = temp;
         }

         // reverse the array
         newline.Reverse();

         //assigning into a string array
         string[] newFile = newline.ToArray();
         newline.Sort();

         // move the original file in a new location
         Console.WriteLine(string.Format("Copying original file in {0}", args[0]));
         File.Move(file1, file2);

         //now writing the data to a text file
         Console.WriteLine(string.Format("Write new file {0}", args[0]));
         File.WriteAllLines(file1, newFile);

         Console.WriteLine("Convertion is finished.");
         Console.WriteLine("\nPress any key to continue...");
         Console.ReadLine();
      }
   }
}

Happy coding!

Under the hood of Microsoft's Windows Subsystem for Linux

Bash on Windows 10 was one of the big reveals at Microsoft's recent Build conference. Since then, there's been a lot of speculation about what Microsoft did to make this possible.

Microsoft is starting to provide more details via blog posts and a new Channel 9 video on what's going on under the covers.

bashlinuxwin10

Spoiler alert: There's no secret Linux kernel hidden in Windows 10. Instead, it's the Windows Subsystem for Linux (WSL) that was developed by the Windows Kernel team is what provides the foundation that enabled the Linux binaries to run on Windows.

WSL includes a user mode session manager, pico provider drivers that emulate a Linux kernel and pico processes that host the unmodified user mode Linux, like Bash, as Microsoft officials explain in an April 22 blog post.

"It is the space between the user mode Linux binaries and the Windows kernel components where the magic happens," according to Microsoft's post."By placing unmodified Linux binaries in Pico processes we enable Linux system calls to be directed into the Windows kernel. The lxss.sys and lxcore.sys drivers translate the Linux system calls into NT APIs and emulate the Linux kernel."

The Channel 9 architectural overview video and the related blog post both note that the Windows kernel does include the Drawbridge pico process/pico driver concepts. And it's these pico processes and drivers that "provide the foundation for the Windows Subsystem for Linux."

The post and video are worth checking out for those whose hearts beat just a little quicker when they see an OS architectural diagram.

Steve Jobs and Bill Gates Face Off

For a different Sunday morning, this is a best way to spend your two hours.

In this video Bill Gates and Steve Jobs are speaking about their companies, their and our life, the future of the world with different point of view.

Dijkstra's Algorithm in C# with Generics

I recently needed to to implement a shortest-path algorithm (to identify preferred domain controllers using site link costs) and I found Dijkstra's Algorithm

Path class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DijkstraAlgorithm {
   public class Path<T> {
      public T Source { get; set; }

      public T Destination { get; set; }

      /// <summary>
      /// Cost of using this path from Source to Destination
      /// </summary>
      /// 
      /// Lower costs are preferable to higher costs
      /// </remarks>
      public int Cost { get; set; }
   }
}

ExtensionMethods class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DijkstraAlgorithm {
   public static class ExtensionMethods {
      /// <summary>
      /// Adds or Updates the dictionary to include the destination and its associated cost 
      /// and complete path (and param arrays make paths easier to work with)
      /// </summary>
      public static void Set<T>(this Dictionary<T, KeyValuePair<int, LinkedList<Path<T>>>> Dictionary, 
                                T destination, int Cost, params Path<T>[] paths) {
         var CompletePath = paths == null ? new LinkedList<Path<T>>() : new LinkedList<Path<T>>(paths);
         Dictionary[destination] = new KeyValuePair<int, LinkedList<Path<T>>>(Cost, CompletePath);
      }
   }
}

Engine class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DijkstraAlgorithm {
   /// <summary>
   /// Calculates the best route between various paths, using Dijkstra's algorithm
   /// </summary>
   public static class Engine {
      public static LinkedList<Path<T>> CalculateShortestPathBetween<T>(T source, T destination, IEnumerable<Path<T>> Paths) {
         return CalculateFrom(source, Paths)[destination];
      }

      public static Dictionary<T, LinkedList<Path<T>>> CalculateShortestFrom<T>(T source, IEnumerable<Path<T>> Paths) {
         return CalculateFrom(source, Paths);
      }

      private static Dictionary<T, LinkedList<Path<T>>> CalculateFrom<T>(T source, IEnumerable<Path<T>> Paths) {
         // validate the paths
         if (Paths.Any(p => p.Source.Equals(p.Destination)))
            throw new ArgumentException("No path can have the same source and destination");

         // keep track of the shortest paths identified thus far
         Dictionary<T, KeyValuePair<int, LinkedList<Path<T>>>> ShortestPaths = new Dictionary<T, KeyValuePair<int, LinkedList<Path<T>>>>();

         // keep track of the locations which have been completely processed
         List<T> LocationsProcessed = new List<T>();

         // include all possible steps, with Int.MaxValue cost
         Paths.SelectMany(p => new T[] { p.Source, p.Destination })           // union source and destinations
                 .Distinct()                                                  // remove duplicates
                 .ToList()                                                    // ToList exposes ForEach
                 .ForEach(s => ShortestPaths.Set(s, Int32.MaxValue, null));   // add to ShortestPaths with MaxValue cost

         // update cost for self-to-self as 0; no path
         ShortestPaths.Set(source, 0, null);

         // keep this cached
         var LocationCount = ShortestPaths.Keys.Count;

         while (LocationsProcessed.Count < LocationCount) {
            T _locationToProcess = default(T);

            //Search for the nearest location that isn't handled
            foreach (T _location in ShortestPaths.OrderBy(p => p.Value.Key).Select(p => p.Key).ToList()) {
               if (!LocationsProcessed.Contains(_location)) {
                  if (ShortestPaths[_location].Key == Int32.MaxValue)
                     return ShortestPaths.ToDictionary(k => k.Key, v => v.Value.Value); //ShortestPaths[destination].Value;

                  _locationToProcess = _location;
                  break;
               }
            } // foreach

            var _selectedPaths = Paths.Where(p => p.Source.Equals(_locationToProcess));

            foreach (Path<T> path in _selectedPaths) {
               if (ShortestPaths[path.Destination].Key > path.Cost + ShortestPaths[path.Source].Key) {
                  ShortestPaths.Set(
                      path.Destination,
                      path.Cost + ShortestPaths[path.Source].Key,
                      ShortestPaths[path.Source].Value.Union(new Path<T>[] { path }).ToArray());
               }
            }

            //Add the location to the list of processed locations
            LocationsProcessed.Add(_locationToProcess);
         } // while

         return ShortestPaths.ToDictionary(k => k.Key, v => v.Value.Value);
         //return ShortestPaths[destination].Value;
      }
   }
}

Test

using System.Linq;
using DijkstraAlgorithm;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTestProject1 {
   [TestClass]
   public class UnitTest1 {
      [TestMethod]
      public void Calculate_A_to_D_given_AB_BC_CD__should_be__ABCD() {
         var Results = Engine.CalculateShortestPathBetween(
             "A",
             "D",
             new Path<string>[] {
                new Path<string>() { Source = "A", Destination = "B", Cost = 3 },
                new Path<string>() { Source = "B", Destination = "C", Cost = 3 },
                new Path<string>() { Source = "C", Destination = "D", Cost = 3 }
             });

         Results.Sum(r => r.Cost).Should().Be(9);
         Results.Count.Should().Be(3);

         Results.First().Cost.Should().Be(3);
         Results.First().Source.Should().Be("A");
         Results.First().Destination.Should().Be("B");

         Results.Skip(1).First().Cost.Should().Be(3);
         Results.Skip(1).First().Source.Should().Be("B");
         Results.Skip(1).First().Destination.Should().Be("C");

         Results.Skip(2).First().Cost.Should().Be(3);
         Results.Skip(2).First().Source.Should().Be("C");
         Results.Skip(2).First().Destination.Should().Be("D");
      }

      [TestMethod]
      public void Calculate_A_to_D_given_AB_BC_CD_DE__should_be__ABCD() {
         var Results = Engine.CalculateShortestPathBetween(
             "A",
             "D",
             new Path<string>[] {
                new Path<string>() { Source = "A", Destination = "B", Cost = 3 },
                new Path<string>() { Source = "B", Destination = "C", Cost = 3 },
                new Path<string>() { Source = "C", Destination = "D", Cost = 3 },
                new Path<string>() { Source = "D", Destination = "E", Cost = 3 }
             });

         Results.Sum(r => r.Cost).Should().Be(9);
         Results.Count.Should().Be(3);

         Results.First().Cost.Should().Be(3);
         Results.First().Source.Should().Be("A");
         Results.First().Destination.Should().Be("B");

         Results.Skip(1).First().Cost.Should().Be(3);
         Results.Skip(1).First().Source.Should().Be("B");
         Results.Skip(1).First().Destination.Should().Be("C");

         Results.Skip(2).First().Cost.Should().Be(3);
         Results.Skip(2).First().Source.Should().Be("C");
         Results.Skip(2).First().Destination.Should().Be("D");
      }

      [TestMethod]
      public void Calculate_A_to_D_given_AB_AC_AD_AE_BC_CD_DE__should_be__ACD() {
         var Results = Engine.CalculateShortestPathBetween(
             "A",
             "D",
             new Path<string>[] {
                new Path<string>() { Source = "A", Destination = "B", Cost = 3 },
                new Path<string>() { Source = "A", Destination = "C", Cost = 3 },
                new Path<string>() { Source = "A", Destination = "D", Cost = 7 }, // set this just above ABC (3+3=6)
                new Path<string>() { Source = "A", Destination = "E", Cost = 3 },
                new Path<string>() { Source = "B", Destination = "C", Cost = 3 },
                new Path<string>() { Source = "C", Destination = "D", Cost = 3 },
                new Path<string>() { Source = "D", Destination = "E", Cost = 3 }
             });

         Results.Sum(r => r.Cost).Should().Be(6);
         Results.Count.Should().Be(2);

         Results.First().Cost.Should().Be(3);
         Results.First().Source.Should().Be("A");
         Results.First().Destination.Should().Be("C");

         Results.Skip(1).First().Cost.Should().Be(3);
         Results.Skip(1).First().Source.Should().Be("C");
         Results.Skip(1).First().Destination.Should().Be("D");
      }

      [TestMethod]
      public void Calculate_A_to_D_given_AB_AC_AD_AE_BC_CD_DE__should_be__AD() {
         var Results = Engine.CalculateShortestPathBetween(
             "A",
             "D",
             new Path<string>[] {
                new Path<string>() { Source = "A", Destination = "B", Cost = 3 },
                new Path<string>() { Source = "A", Destination = "C", Cost = 3 },
                new Path<string>() { Source = "A", Destination = "D", Cost = 5 }, // set this just below ABC (3+3=6)
                new Path<string>() { Source = "A", Destination = "E", Cost = 3 },
                new Path<string>() { Source = "B", Destination = "C", Cost = 3 },
                new Path<string>() { Source = "C", Destination = "D", Cost = 3 },
                new Path<string>() { Source = "D", Destination = "E", Cost = 3 }
             });

         Results.Sum(r => r.Cost).Should().Be(5);
         Results.Count.Should().Be(1);

         Results.Single().Cost.Should().Be(5);
         Results.Single().Source.Should().Be("A");
         Results.Single().Destination.Should().Be("D");
      }
   }
}

You can find the code on GitHub.

Happy coding!

How To Setup Native Bash On Ubuntu On Windows 10

Alright, this post is for our developer friends only: the latest Windows 10 Insider Preview Build – build 14316 – includes the much-hyped Bash shell from Ubuntu. What’s the Bash shell, and how can you start using it in Windows 10? Find out after the bump.

Start Using Bash In Windows 10

bash-cmd

As of typing this post, you need to be a Windows Insider running Insider Preview Build 14316 on your Windows 10 PC to be able to execute Bash commands and scripts. If you’ve met these requirements, you’re good to go.

Here’s what you need to setup Bash on Ubuntu Linux on Windows 10: first, go to Settings > Update & security > For developers and enable Developer Mode; second, search for Windows Features, and from Turn Windows features on or off  go ahead and enable Windows subsystem for Linux (beta); third and final, open the Command Prompt and type bash to install it. That’s it!

We will update this post later on when Microsoft releases this feature to the general public as part of the Anniversary Update later this year. Until then, happy scripting!

What is Bash, and why is it on Windows 10?

Bash_screenshot

Bash is a hugely popular shell and command language that runs just below the Command Prompt, and it accepts a different, and much more accepted set of commands and scripts. Bash is popular on Linux and OSX where it serves as the primary command line language.

Windows is quite late to the party, but developers are happy because this means they’ll be able to use all their favorite, powerful Bash commands and scripts in Windows 10.

People have made a big deal out of Bash on Windows 10 because in order to bring Bash to their operating system, Microsoft had to develop a Linux subsystem just for Windows. So, in running Bash natively on Windows 10, you are – in a way – running Linux on Windows 10. That’s a big deal!

To make crashes 'friendlier', Microsoft adds QR codes to Windows 10 BSOD

windows10-qrcode

Windows users will no longer be forced to manually Google error messages to figure out why their computer crashed, as development builds of Windows 10 now include a QR code on the Blue Screen of Death.

The QR codes appeared in build 14316 of the Windows 10 Insider Preview. Though it currently points to a generic help page, the QR code will presumably eventually direct users to specific Windows support articles.

Microsoft's Blue Screen of Death was long a spartan, utilitarian affair. It displayed a generic message and an often unintelligible crash code in a monospaced font.

That changed with Windows 8, when the BSOD was redesigned to add a sad emoticon and more nuanced error instructions.

Apple's modern equivalent — the OS X kernel panic screen — has always been somewhat more refined, though less helpful. Until OS X 10.8, rather than providing a reason, the kernel panic screen simply instructed users to perform a hard reset of their system; more recent revisions perform the reboot automatically.

C# 7 Features Previewed

Over the last year we've shown you various features that were being considered for C# 7. With the preview of Visual Studio 15, Microsoft has decided to demonstrate the features to make it into the final release of C# 7.

Tuple Value Types

.NET has a tuple type, but in the context of C# there are a lot of problems. Being a reference type, you probably want to avoid using it in performance sensitive code as you have to pay for GC costs. And as they are immutable, while making it safer for sharing across threads, making any changes requires allocating a new object.

C# 7 will address this by offering a tuple as a value type. This will be a mutable type, making it more efficient when performance is essential. And as a value type, it makes a copy on assignment so there is little risk of threading issues.

To create a tuple, you can use this syntax:

var result = (5, 20);

Optionally, you can name the values. This isn't necessary, it just makes the code more readable.

var result = (count: 5, sum: 20);

Multi-value Returns

Returning two values from one function has always been a pain in C-style languages. You have to either wrap the results in some sort of structure or use output parameters. Like many functional languages, C# 7 will do the first option for you:

(int, int) Tally (IEnumerable<int> list)

Here we see the basic problem with using generic tuples: there is no way to know what each field is for. So C# is offering a compiler trick to name the results:

(int Count, int Sum) Tally (IEnumerable<int> list)

We'd like to stress that C# isn't generating a new anonymous type. You are still getting back a tuple, but the compiler is pretending its properties are Count and Sum instead of Item1 and Item2. Thus these lines of code are equivalent:

var result = Tally(list);
Console.WriteLine(result.Item1);
Console.WriteLine(result.Count);

Note that we do not yet have a syntax for multi-assignment. Presumably when it happens, it will look something like this:

(count, sum) = Tally(list);

Beyond simple utility functions such as this, multi-value returns will be useful for writing asynchronous code, as async functions aren't allowed to use out parameters.

Pattern Matching: Enhanced Switch Blocks

One of the long standing complaints of VB and functional programmers alike is that C#'s switch statement is extremely limited. VB developers want ranges, while those who used to F# or Haskell want decomposition-style pattern matching. C# 7 intends to offer both.

When pattern matching on types, you can create variables to hold the result of the cast. For example, when using a switch on a System.Object you could write:

case int x:

If the object is an integer, the variable x will be populated. Otherwise it will check the next case block in a top to bottom fashion. If you want to be more specific, you can use range checks:

case int x when x > 0:
case int y:

In this example, if the object is a positive integer the x block will be executed. If the object is zero or a negative integer, the y block will be executed.

If you want to check for null, simply use this syntax:

case null;

Pattern Matching: Decomposition

So far we've just seen an incremental improvement over what is available in VB. The real power of pattern matching comes from decomposition, where you can tear apart an object. Consider this syntax:

if (person is Professor {Subject is var s, FirstName is "Scott"})

This does two things:

  1. It creates a local variable named s with the value of
    ((Professor)person).Subject
  2. It performs the equality check
    ((Professor)person).FirstName == "Scott"

Translated into C# 6 code:

var temp = person as Professor;
if (temp != null && temp.FirstName == "Scott")
{
   var s = temp.Subject
}

Presumably we'll be able to combine enhanced switch blocks in the final release.

Ref Returns

Passing large structures by reference can be significantly faster than passing them by value, as the latter requires copying the whole structure. Likewise, returning a large structure by reference can be faster.

In languages such as C, you return a structure by reference using a pointer. This brings in the usual problems with pointers such as pointing to a piece of memory after it has been recycled for another purpose.

C# avoids this problem by using a reference, which is essentially a pointer with rules. The most important rule is that you can't return a reference to a local variable. If you tried, that variable would be on a portion of the stack that is no longer valid as soon as the function returns.

In the demonstration, they instead returned a reference to a structure inside an array. Since it is effectively a pointer to an element in the array, the array itself can be modified. For example:

var x = ref FirstElement(myArray)
x = 5; //MyArray[0] now equals 5

The use case for this is highly performance sensitive code. You wouldn't use it in most applications.

Binary Literals

A minor feature is the addition of binary literals. The syntax is simple prefix, for example 5 would be "0b0101". The main use cases for this would be setting up flag based enumerations and creating bitmasks for working with C-style interop.

Local Functions

Local functions are functions that you define inside another function. At first glance, local functions look like a slightly nicer syntax for anonymous functions. But they have some advantages.

  • First, they don't require you to allocate a delegate to hold them. Not only does this reduce memory pressure, it also allows the function to be in-lined by the compiler.
  • Secondly, they don't require you to allocate an object when creating a closure. Instead it just has access to the local variables. Again, this improves performance by reducing GC pressure.

Presumably the second rule means that you can't create a delegate that points to a local function. Still, this offers organizational benefits over creating separate private functions to which you pass the current function's state as explicit parameters.

Partial Class Enhancements

The final feature demonstrated was a new way to handle partial classes. In the past, partial classes were based around the concept of code-generation first. The generated code would include a set of partial methods that the developer could implement as needed to refine behavior.

With the new "replace" syntax, you can go the other way. The developer writes code in a straight forward fashion first and then the code generator comes in and rewrites it. Here is a simple example of what the developer may write,

public string FirstName {get; set;}

Simple, clean, and completely wrong for a XAML style application. So here's what the code generator will produce:

private string m_FirstName;
static readonly PropertyChangedEventArgs s_FirstName_EventArgs 
                   = new PropertyChangedEventArgs("FirstName")

replace public string FirstName {
   get {
      return m_FirstName;
   }
   set {
      if (m_FirstName == value)
         return;
      m_FirstName = value;
      PropertyChanged?.Invoke(this, m_FirstName_EventArg);
   }
}

By using the "replace" keyword, the generated code can literally replace the hand-written code with the missing functionality. In this example, we can even handle the tedious parts that developers often skip such as caching EventArgs objects.

While the canonical example is property change notifications, this technique could be used for many "Aspect Oriented Programming" scenarios such as injecting logging, security checks, parameter validation, and other tedious boilerplate code.

Advertsing

125X125_06

Planet Xamarin

Planet Xamarin

Calendar

<<  July 2017  >>
MonTueWedThuFriSatSun
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar

Month List