Aspose.Slides.NET 17.7.0

Aspose.Slides for .NET

Aspose.Slides is a PowerPoint management library for working with Microsoft PowerPoint files without using Microsoft PowerPoint. It allows developers to work with PPT, PPS, POT, PPTX, PPSX, POTX and ODP files on ASP.NET web applications, web services and Windows applications.

There is a newer version of this package available.
See the version list below for details.
Install-Package Aspose.Slides.NET -Version 17.7.0
dotnet add package Aspose.Slides.NET --version 17.7.0
<PackageReference Include="Aspose.Slides.NET" Version="17.7.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Aspose.Slides.NET --version 17.7.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

Release Notes

SLIDESNET-38556 - IOleObjectFrame.ObjectData returns byte stream of the entire ole objects
SLIDESNET-39011 - PPTX to PDF failed in Aspose.Slides for .NET 15.2
SLIDESNET-39100 - Support for explicitly setting PNG image format when adding image into presentation
SLIDESNET-34027 - Support for adding columns in text box
SLIDESNET-38595 - Optimize the memory consumption caused by BLOB objects
SLIDESNET-37660 - SVG Import
SLIDESNET-38554 - Get text added to the shapes associated with the SmartArt nodes
SLIDESNET-38558 - Get the shape Id property set by Microsoft using Aspose library
SLIDESNET-39110 - Support for inserting SVG in slide
SLIDESNET-38015 - When PPTX is converted to PDF, the values in chart are missing
SLIDESNET-39052 - When PPTX is converted to PDF, font size in output is increased.
SLIDESNET-38905 - Exception while setting Frame settings for shape of SmartArtNode
SLIDESNET-39050 - Image replacement doesn't work if jpeg picture is passed
SLIDESNET-35162 - Text improperly rendered in generated PDF
SLIDESNET-35812 - Chart Labels are not coming fine after conversion from PPTX to PDF
SLIDESNET-38357 - Pptx not converted properly to pdf
SLIDESNET-38427 - Out of Memory Exception thrown on loading huge presentations and Improving memory consumption
SLIDESNET-34377 - Arrow lines are missing or improperly rendered in generated PDF
SLIDESNET-34740 - Text failed to render in PDF for PPT when using PresentationEx class
SLIDESNET-34741 - Text failed to render in PDF for PPT
SLIDESNET-34797 - Text is improperly rendered in generated thumbnail
SLIDESNET-35621 - Shapes move when existing file is opened and saved
SLIDESNET-35736 - Improper chart rendering in Pdf and thumbnails
SLIDESNET-37579 - Shadow effect on a text disappears after saving a ppt
SLIDESNET-38258 - Font substitution does not work when converting pptx to png
SLIDESNET-38259 - Exception on converting pptx to pdf
SLIDESNET-38508 - Font becomes bold after converting ppt to pdf
SLIDESNET-38525 - Pptx not converted properly to pdf
SLIDESNET-38561 - Unexpected text shadow effect shows up
SLIDESNET-38607 - Text missing in generated result svg format
SLIDESNET-38908 - PptxRead exception on loading presentaiton
SLIDESNET-38916 - Text on chart is missing in generated thumbnail
SLIDESNET-38941 - Performance of ISmartArtNode.TextFrame is decreased for each next Node
SLIDESNET-38957 - Pptx not converted properly to pdf and thumbnails
SLIDESNET-38960 - Exception on loading presentation
SLIDESNET-38991 - Exception when converting Pptx to Pdf
SLIDESNET-39002 - Image color missing in generated thumbnail
SLIDESNET-39014 - Wrong coordinates are returned for paragraph position
SLIDESNET-39030 - Setting label value for workbook cell not working for data point
SLIDESNET-39044 - Comments are missing in exported PDF
SLIDESNET-39056 - Invalid file generated when converting PPT file to PPTX
SLIDESNET-39058 - Images not properly generated from presentation file

Public API Changes
AddFromSvg methods were added to IImageCollection interface and ImageCollection class

/// <summary>
/// Add an image to a presentation from Svg.
/// </summary>
/// <remarks>Svg to Metafile(EmfPlusOnly) conversion will be performed</remarks>
/// <param name="svgContent">Svg content.</param>
/// <returns>Added image.</returns>
IPPImage AddFromSvg(string svgContent);

/// <summary>
/// Add an image to a presentation from Svg.
/// </summary>
/// <remarks>Svg to Metafile(EmfPlusOnly) conversion will be performed</remarks>
/// <param name="svgContent">Svg content.</param>
/// <param name="externalResResolver">A callback object used to fetch external objects. If this parameter is null all external objects will be ignored.</param>
/// <param name="baseUri">Base URI of the specified Svg. Used to resolve relative links.</param>
/// <returns>Added image.</returns>
IPPImage AddFromSvg(string svgContent, IExternalResourceResolver externalResResolver, string baseUri);

These methods provide ability to insert Svg fragment to the presentation's image collection.

Sample 1

using (var p = new Presentation())
{
   var svgContent = File.ReadAllText(svgPath);
   var emfImage = p.Images.AddFromSvg(svgContent);
   p.Slides[0].Shapes.AddPictureFrame(ShapeType.Rectangle, 0, 0, emfImage.Width, emfImage.Height, emfImage);
   p.Save(outPptxPath, SaveFormat.Pptx);
}

Sample 2 (with default external resources resolver)

using (var p = new Presentation())
{
   var svgContent = File.ReadAllText(new Uri(new Uri(baseDir), "image1.svg").AbsolutePath);
   var emfImage = p.Images.AddFromSvg(svgContent, new ExternalResourceResolver(), baseDir);
   p.Slides[0].Shapes.AddPictureFrame(ShapeType.Rectangle, 0, 0, emfImage.Width, emfImage.Height, emfImage);
   p.Save(outPptxPath, SaveFormat.Pptx);
}

Please note: Using this default external resource resolver could create a vulnerability when client provided HTML or SVG file will make server software to obtain local or network file. Use with caution. It is recommended not to specify ExternalResourceResolver at all (only embedded objects will be read - see "Sample 1") or create some subclass which checks if specified uri is valid.
ColumnCount and ColumnSpacing properties have been added to ITextFrameFormat interface and to TextFrameFormat class

Property ColumnCount and ColumnSpacing has been added to ITextFrameFormat interface and TextFrameFormat class respectively.

These properties specify the number of columns in textbox and set an amount of spacing in points between columns.

Code example:

using (Presentation presentation = new Presentation())
{
   // Get the first slide of presentation
   ISlide slide = presentation.Slides[0];

   // Add an AutoShape of Rectangle type
   IAutoShape aShape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 100, 100, 300, 300);

   // Add TextFrame to the Rectangle
   aShape.AddTextFrame("All these columns are limited to be within a single text container -- " +
       "you can add or delete text and the new or remaining text automatically adjusts " +
       "itself to flow within the container. You cannot have text flow from one container " +
       "to other though -- we told you PowerPoint's column options for text are limited!");

   // Get text format of TextFrame
   ITextFrameFormat format = aShape.TextFrame.TextFrameFormat;

   // Specify number of columns in TextFrame
   format.ColumnCount = 3;

   // Specify spacing between columns
   format.ColumnSpacing = 10;

   // Save created presentation
   presentation.Save("ColumnCount.pptx", SaveFormat.Pptx);
}

IHtmlExternalResolver interface and HtmlExternalResolver class become obsolete

Use IExternalResourceResolver/ExternalResourceResolver instead. Will be removed in 17.12 release.
New API related to the BLOBs management has been added

New BLOBs API

Overview

A Binary Large Object (BLOB) is a binary data stored as a single entity, that must be handled in a special way because of its size. It cannot be considered that any BLOB object may fit in the process's memory - or, even if it can, it may lead to an issues like undesirable high memory consumption or increase the chances of "out of memory" exceptions, and other inappropriate effects.
Presentaion can be considered as BLOB itself or can contain BLOBs - such as large video or audio files. To prevent unwanted memory consumption and other issues a new BLOBs management functionality was introduced.

The way to avoid BLOBs loading into memory is to use streams - the instances of classes inherited from the base Stream class. A new functions were added to the public API to support passing streams as arguments - to treat these streams as BLOBs and guarantee that no process's memory will be wasted to store them.

What is important about streams is who owns them. As an example, you may open the FileStream and pass this stream to Presentation's instance. You may want to delete this file later, while the Presentation's instance is still here - but if it is deleted, how will this instance use it to save the presentation in the other format, for example?

To solve this possible conflict an idea of "possession" of the stream was introduced. When you pass a stream to Presentation, you may choose the behavior the most suitable for you - either let Presentation lock the stream and use it later or read the whole stream and then release it. Under the hood a different techniques might be used to handle large streams - including copying the whole stream in a temporary file and cleanup later when Presentation's instance will be disposed. Obviously, passing the stream to Presentation and let it be locked is more effective and not introduce an overhead related to the file system operations, but it may be inappropriate if you can't let this stream be locked and want close it before Presentation's instance will be disposed. So here the choice is up to the Presentation's instance owner.
Presentation source locking behavior

The source of the presentation is the data from which this presentation will be loaded and an instance of the Presentation class will be created. It can be a file or an instance of the Stream. There're two options that can be selected for the Presentation construction - they represented by PresentationLockingBehavior enumeration members.

LoadAndRelease - the source will be released immediately after Presentation's object will be constructed. If usage of the temporary files is disabled (IBlobManagementOptions.IsTemporaryFilesAllowed is set to false), the whole presentation will be loaded into memory.

KeepLocked - the source (file or Stream) will be locked. One of the major property of streams is that they might be seekable or not. In some cases like parsing the whole presentation, we must have the whole stream to build the DOM. So in this case the source might not be seekable (e.g. in case of NetworkStream), and it's needed to load the whole stream in temporary storage to parse the presentation. Usage of the temporary files must be enabled in this mode (IBlobManagementOptions.IsTemporaryFilesAllowed is set to true), an exception will be thrown otherwise.
Customizations of BLOBs management behavior

A number of options can be customized to provide the behavior most suitable for a specific environment and achieve the optimal ratio of performance and memory consumption in any particular case.

In a number of cases BLOB management uses a temporary files to handle situations when the source stream can't be locked by Presentation object. You may disable the usage of temporary files using IBlobManagementOptions.IsTemporaryFilesAllowed property. In this case any stream that can't be locked will be downloaded in memory.

Beside that, the root path of the temporary files can be changed. By default, the system's default temporary files folder is used.

The other option that can be customized is the amount of process's memory that can be safely used to store the BLOBs before it will be dumped to a temporary files. It's faster to avoid the file system operations if there is no memory pressure, and the IBlobManagementOptions.MaxBlobsBytesInMemory property can be used to set the value the most appropriate for every particular case. The default value is 600Mb.
Working with BLOBs

Open and save the large presentation

Here's is the sample of opening and saving the very large presentation:

static void OpenAndSaveLargePresentation()
{
   // supposed the size of presentation is very large, let's say more than 2Gb
   const string pathToVeryLargePresentationFile = "veryLargePresentation.pptx";

   LoadOptions loadOptions = new LoadOptions
   {
       BlobManagementOptions = {
           // let's choose the KeepLocked behavior - the "veryLargePresentation.pptx" will be locked for
           // the Presentation's instance lifetime, but we don't need to load it into memory or copy into
           // thetemporary file
           PresentationLockingBehavior = PresentationLockingBehavior.KeepLocked,
       }
   };

   using (Presentation pres = new Presentation(pathToVeryLargePresentationFile, loadOptions))
   {
       // the huge presentation is loaded and ready to use, but the memory consumption is still low.

       // make any changes to the presentation.
       pres.Slides[0].Name = "Very large presentation";

       // presentation will be saved to the other file, the memory consumptions still low during saving.
       pres.Save("veryLargePresentation-copy.pptx", SaveFormat.Pptx);

       // can't do that! IO exception will be thrown, because the file is locked while pres objects will
       // not be disposed
       File.Delete(pathToVeryLargePresentationFile);
   }

   // it's ok to do it here, the source file is not locked by pres object
   File.Delete(pathToVeryLargePresentationFile);
}

Adding new BLOB to the presentation

This example demonstrates how to include the large BLOB (video file in that case) and prevent a high memory consumption.

static void AddingNewBlobToPresentation()
{
   // supposed we have the very large video file we want to include into the presentation
   const string pathToVeryLargeVideo = "veryLargeVideo.avi";

   // create a new presentation which will contain this video
   using (Presentation pres = new Presentation())
   {
       using (FileStream fileStream = new FileStream(pathToVeryLargeVideo, FileMode.Open))
       {
           // let's add the video to the presentation - we choose KeepLocked behavior, because we not
           // have an intent to access the "veryLargeVideo.avi" file.
           IVideo video = pres.Videos.AddVideo(fileStream, LoadingStreamBehavior.KeepLocked);
           pres.Slides[0].Shapes.AddVideoFrame(0, 0, 480, 270, video);

           // save the presentation. Despite that the output presentation will be very large, the memory
           // consumption will be low the whole lifetime of the pres object
           pres.Save("presentationWithLargeVideo.pptx", SaveFormat.Pptx);
       }
   }
}

Exporting BLOB from presentation into stream

Consider that we have a very large presentation containing multiple large BLOBs - audio and video files. We want to extract these files from presentation and don't want to load this presentation into memory to keep our memory consumption low. Here's is an example how we can achieve that:

static void ExportBlobsFromPresentaion()
{
   // supposed the presentation contains a multiple audios and videos and it size is huge.
   const string hugePresentationWithAudiosAndVideosFile = @"c:\bin\aspose\Tasks\020, 38595\orig\Large  Video File Test1.pptx";

   LoadOptions loadOptions = new LoadOptions
   {
       BlobManagementOptions =
       {
           // lock the source file and don't load it into memory
           PresentationLockingBehavior = PresentationLockingBehavior.KeepLocked,
       }
   };

   // create the Presentation's instance, lock the "hugePresentationWithAudiosAndVideos.pptx" file.
   using (Presentation pres = new Presentation(hugePresentationWithAudiosAndVideosFile, loadOptions))
   {
       // let's save each video to a file. to prevent memory usage we need a buffer which will be used
       // to exchange tha data from the presentation's video stream to a stream for newly created video file.
       byte[] buffer = new byte[8 * 1024];

       // iterate through the videos
       for (var index = 0; index < pres.Videos.Count; index++)
       {
           IVideo video = pres.Videos[index];

           // open the presentation video stream. Please note that we intentionally avoid accessing properties
           // like video.BinaryData - this property returns a byte array containing full video, and that means
           // this bytes will be loaded into memory. We will use video.GetStream, which will return Stream and
           // that allows us to not load the whole video into memory.
           using (Stream presVideoStream = video.GetStream())
           {
               using (FileStream outputFileStream = File.OpenWrite($"video{index}.avi"))
               {
                   int bytesRead;
                   while ((bytesRead = presVideoStream.Read(buffer, 0, buffer.Length)) > 0)
                   {
                       outputFileStream.Write(buffer, 0, bytesRead);
                   }
               }
           }

           // memory consumption will stay low no matter what size the videos or presentation is.
       }

       // do the same for audios if needed.
   }
}

API

A number of the new properties, classes and enums has been added to support BLOBs handling.
ILoadOptions

BlobManagementOptions property of type IBlobManagementOptions has been added. It represents the options which can be used to manage Binary Large Objects (BLOBs) handling behavior, such as using of temporary files or max BLOBs bytes in memory.
IBlobManagementOptions interface

A new interface IBlobManagementOptions has been added. It inteded to configure a a different behavior aspects regarding BLOBs handling for the IPresentation instance lifetime.

PresentationLockingBehavior property of PresentationLockingBehavior enum. This property defines if an instance of the Presentation class can be an owner of the source - file or stream during the instance lifetime. If the instance is an owner, it locks the source.
IsTemporaryFilesAllowed of type bool. This property defines if temporary files can be created while working with BLOBs, what greatly decreases the memory consumption but requires permissions to create files.
TempFilesRootPath of type string. The root path where temporary files will be created. Hosting process should have permissions to create files and folders there.
MaxBlobsBytesInMemory of type ulong. Defines the maximum amount (in bytes) that all BLOBs in total may occupy in memory.

PresentationLockingBehavior enum

The new PresentationLockingBehavior enum has been added, it values represents the behavior regarding treating the IPresentation source (file or Stream) while loading and working with an instance of IPresentation. It has the following members:

LoadAndRelease - The source will be locked only for a time of IPresentation constructor execution.
KeepLocked - The source will be locked for a whole lifetime of IPresentation instance, until it will be disposed.

IVideoCollection and IAudioCollection

A new method has been added to IVideoCollection and IAudioCollection to support adding large videos and audios as streams to treat them as BLOBs:

IVideo AddVideo(Stream stream, LoadingStreamBehavior loadingStreamBehavior)
IAudio AddAudio(Stream stream, LoadingStreamBehavior loadingStreamBehavior)
LoadingStreamBehavior

This new enum is used to select proper behavior to handle the stream. It contains the following possible values:

ReadStreamAndRelease - the stream will be read to the end and then released - i.e. it will be guaranteed that this stream will not be used by IPresentation instance in the future.
KeepLocked - the stream will be locked inside the IPresentation object, i.e. the ownership of the stream will be transferred. The IPresentation object will be responsible to correctly dispose the stream when this object will be disposed itself.

IVideo and IAudio

To support getting large BLOBs inside presentation as Stream a new method has been added:

Stream GetStream()

It returns Stream stream for reading. Please note that you must use 'using' or close stream after using.
New IExternalResourceResolver interface and ExternalResourceResolver class were added

New IExternalResourceResolver interface was added as a replacement of existing IHtmlExternalResolver (become obsolete).
This is a callback interface used to resolve external resources during Html, Svg documents import.

/// <summary>
/// Callback interface used to resolve external resources during Html, Svg documents import.
/// </summary>
[ComVisible(true), Guid("88ff6edd-d6d4-43e4-b25a-7806671fe7ca")]
public interface IExternalResourceResolver
{
   /// <summary>
   /// Resolves the absolute URI from the base and relative URIs.
   /// </summary>
   /// <param name="baseUri">Base URI of linking objects</param>
   /// <param name="relativeUri">Relative URI to the linked object.</param>
   /// <returns>Absolute URI or null if the relative URI cannot be resolved.</returns>
   string ResolveUri(string baseUri, string relativeUri);

   /// <summary>
   /// Maps a URI to an object containing the actual resource.
   /// </summary>
   /// <param name="absoluteUri">Absolute URI to the object.</param>
   /// <returns> A <see cref="System.IO.Stream"/> object or null if resource cannot be streamed.</returns>
   System.IO.Stream GetEntity(string absoluteUri);
}

ExternalResourceResolver is default implementation of IExternalResourceResolver.

Please note: Using ExternalResourceResolver could create a vulnerability when client provided HTML or SVG file will make server software to obtain local or network file. Use with caution. It is recommended not to specify ExternalResourceResolver at all (only embedded objects will be read - see "Sample 1") or create some subclass which checks if specified uri is valid.
New property EmbeddedFileData has been added to IOleObjectFrame

A new property EmbeddedFileData has been added to IOleObjectFrame. It's needed to retrieve the file data of embedded OLE object.

For example, when an image has been embedded into presentation, its data can be accessed through EmbeddedFileData property:

using (Presentation pres = new Presentation(pptxFileName))
{
 IOleObjectFrame oleObjectFrame = (IOleObjectFrame)pres.Slides[0].Shapes[0];
 string fileName = oleObjectFrame.EmbeddedFileName;
 byte[] data = oleObjectFrame.EmbeddedFileData;
}

OfficeInteropShapeId property was added to IShape interface and Shape class respectively

Property OfficeInteropShapeId was added to IShape interfaces and Shape class respectively.

This property allows getting unique shape identifier in slide scope in contrast to the UniqueId property, which allows obtaining a unique identifier in presentation scope.

The value returned by OfficeInteropShapeId property corresponds to the value of the Id of the Microsoft.Office.Interop.PowerPoint.Shape object.

Code example:

using (Presentation presentation = new Presentation("Presentation.pptx"))
{
   // Getting unique shape identifier in slide scope
   long officeInteropShapeId = presentation.Slides[0].Shapes[0].OfficeInteropShapeId;
}

TextFrame property has been added to ISmartArtShape interface and SmartArtShape class

TextFrame property has been added to ISmartArtShape interface and SmartArtShape class respectively.

This property allows you to get all text from SmartArt if it has not only nodes text.

using (Presentation pres = new Presentation("Presentation.pptx"))
{
           ISlide slide = presentation.Slides[0];
           ISmartArt smartArt = (ISmartArt)slide.Shapes[0];

           ISmartArtNodeCollection smartArtNodes = smartArt.AllNodes;
           foreach (ISmartArtNode smartArtNode in smartArtNodes)
           {
               foreach (ISmartArtShape nodeShape in smartArtNode.Shapes)
               {
                   if (nodeShape.TextFrame != null)
                       Console.WriteLine(nodeShape.TextFrame.Text);
               }
           }
}

Dependencies

This package has no dependencies.

This package is not used by any popular GitHub repositories.

Version History

Version Downloads Last updated
19.6.0 1,000 6/25/2019
19.5.0 2,238 5/31/2019
19.4.0 3,524 4/26/2019
19.3.0 2,210 4/3/2019
19.2.0 6,217 2/28/2019
19.1.0 6,972 1/30/2019
18.12.0 4,228 12/27/2018
18.11.0 3,613 11/30/2018
18.10.0 10,691 10/30/2018
18.9.0 3,154 9/30/2018
18.8.0 3,457 8/29/2018
18.7.0 9,228 7/27/2018
18.6.0 10,032 7/1/2018
18.5.0 5,548 5/30/2018
18.4.0 2,371 5/3/2018
18.3.0 3,088 4/1/2018
18.2.1 3,505 3/7/2018
18.2.0 1,885 2/28/2018
18.1.0 2,882 1/30/2018
17.12.1 4,790 12/26/2017
17.12.0 807 12/16/2017
17.11.0 1,279 11/30/2017
17.10.0 3,965 10/31/2017
17.9.1 3,456 10/12/2017
17.9.0 1,405 10/2/2017
17.8.0 9,273 8/30/2017
17.7.0 6,093 7/31/2017
17.6.0 2,218 7/1/2017
17.5.0 1,995 5/31/2017
17.4.0 2,564 4/28/2017
17.3.0 2,965 4/2/2017
17.2.0 7,216 3/1/2017
17.1.0 3,131 1/31/2017
16.12.1 3,115 1/16/2017
16.12.0 1,531 12/27/2016
16.11.0 2,340 11/30/2016
16.10.0 2,316 11/4/2016
16.9.0 2,935 10/12/2016
16.8.0 2,871 9/27/2016
16.7.0 1,501 8/22/2016
16.6.0 16,099 7/15/2016
16.5.0 3,113 6/16/2016
16.4.0 3,339 5/16/2016
16.3.0 7,771 4/11/2016
16.2.0 4,259 3/17/2016
16.1.0 5,855 2/4/2016
15.11.0 9,139 1/11/2016
15.10.0 9,179 12/10/2015
15.9.0 5,462 11/6/2015
15.8.1 913 10/16/2015
15.8.0 1,208 10/5/2015
15.7.0 3,131 9/3/2015
15.6.0 7,084 7/22/2015
15.5.0 2,684 6/16/2015
15.4.0 1,797 5/14/2015
15.3.1 1,001 4/23/2015
15.3.0 665 4/14/2015
15.2.0 8,612 3/6/2015
15.1.0 1,219 2/3/2015
14.10.0 4,566 11/28/2014
14.9.0 1,479 11/11/2014
14.8.1 1,378 10/24/2014
14.8.0 620 10/16/2014
14.7.0 1,822 9/7/2014
14.6.0 1,129 8/6/2014
14.5.0 3,062 7/16/2014
14.4.0 1,740 6/2/2014
14.3.0 1,956 5/6/2014
14.2.0 1,135 3/24/2014
14.1.2 1,545 2/17/2014
14.1.1 619 2/10/2014
14.1.0.2 537 2/6/2014
13.12.0 1,475 12/30/2013
8.4.2 4,459 6/5/2014
8.4.1 1,130 5/6/2014
8.4.0 757 3/3/2014
8.3.0.1 645 2/3/2014
8.2.0 592 12/27/2013
8.1.0 4,869 12/16/2013
8.0.0 1,622 10/25/2013
7.9.0 986 10/8/2013
7.8.0 709 9/3/2013
7.7.0 2,947 8/4/2013
7.6.0 777 7/5/2013
7.5.0 1,015 5/27/2013
7.4.0 7,295 4/24/2013
7.3.0 802 4/10/2013
7.2.0 1,028 3/8/2013
7.1.0 3,106 1/28/2013
7.0.0 829 12/31/2012
6.9.0 777 12/10/2012
6.8.0 844 10/30/2012
6.7.0 1,098 10/4/2012
6.6.0 707 9/13/2012
6.5.0 818 7/27/2012
6.4.0 737 6/27/2012
6.3.0 663 5/29/2012
6.2.0 706 5/7/2012
6.1.0 730 3/28/2012
6.0.0 702 3/2/2012
5.9.0.1 722 2/16/2012
5.9.0 1,122 2/16/2012
Show less