diff --git a/wordcloud/wordcloud-tests.ts b/wordcloud/wordcloud-tests.ts
new file mode 100644
index 0000000000..2eecca3b8a
--- /dev/null
+++ b/wordcloud/wordcloud-tests.ts
@@ -0,0 +1,196 @@
+///
+///
+
+'use strict';
+//declare function test(name: string, test: Function);
+var element: HTMLElement | HTMLElement[];
+
+if (!WordCloud.isSupported)
+ console.log('WordCloud is not supported.');
+
+WordCloud.miniumFontSize = 20;
+
+var list = (function () {
+ var string = 'Grumpy wizards make toxic brew for the evil Queen and Jack';
+
+ var list: WordCloud.ListEntry[] = [];
+ string.split(' ').forEach(function(word) {
+ list.push([word, word.length * 5]);
+ });
+
+ return list;
+})();
+
+function getTestOptions(): WordCloud.Options {
+ return {
+ shuffle: false,
+ rotateRatio: 0,
+ color: '#000',
+ fontFamily: 'sans-serif',
+ list: list
+ };
+};
+
+test('Test runs without any extra parameters.', function() {
+ var options = getTestOptions();
+ WordCloud(element, options);
+});
+
+test('Empty list results no output.', function() {
+ var options = getTestOptions();
+ options.list = [];
+
+ WordCloud(element, options);
+});
+
+test('gridSize can be set', function() {
+ var options = getTestOptions();
+ options.gridSize = 15;
+
+ WordCloud(element, options);
+});
+
+test('ellipticity can be set', function() {
+ var options = getTestOptions();
+ options.ellipticity = 1.5;
+
+ WordCloud(element, options);
+});
+
+test('origin can be set', function() {
+ var options = getTestOptions();
+ options.origin = [300, 0];
+
+ WordCloud(element, options);
+});
+
+test('minSize can be set', function() {
+ var options = getTestOptions();
+ options.minSize = 10;
+
+ WordCloud(element, options);
+});
+
+test('rotation can be set and locked', function() {
+ var options = getTestOptions();
+ options.rotateRatio = 1;
+ options.minRotation = options.maxRotation = Math.PI / 6;
+
+ WordCloud(element, options);
+});
+
+test('drawMask can be set', function() {
+ var options = getTestOptions();
+ options.drawMask = true;
+
+ WordCloud(element, options);
+});
+
+test('maskColor can be set', function() {
+ var options = getTestOptions();
+ options.drawMask = true;
+ options.maskColor = 'rgba(0, 0, 255, 0.8)';
+
+ WordCloud(element, options);
+});
+
+test('backgroundColor can be set', function() {
+ var options = getTestOptions();
+ options.backgroundColor = 'rgb(0, 0, 255)';
+
+ WordCloud(element, options);
+});
+
+test('semi-transparent backgroundColor can be set', function() {
+ var options = getTestOptions();
+ options.backgroundColor = 'rgba(0, 0, 255, 0.3)';
+
+ WordCloud(element, options);
+});
+
+test('weightFactor can be set', function() {
+ var options = getTestOptions();
+ options.weightFactor = 2;
+
+ WordCloud(element, options);
+});
+
+test('weightFactor can be set as a function', function() {
+ var options = getTestOptions();
+ options.weightFactor = function (w) { return Math.sqrt(w); };
+
+ WordCloud(element, options);
+});
+
+test('color can be set as a function', function() {
+ var options = getTestOptions();
+ options.color = function (word, weight, fontSize, radius, theta) {
+ if (theta < 2*Math.PI/3) {
+ return '#600';
+ } else if (theta < 2*Math.PI*2/3) {
+ return '#060';
+ } else {
+ return '#006';
+ }
+ };
+
+ WordCloud(element, options);
+});
+
+test('shape can be set to circle', function() {
+ var options = getTestOptions();
+ options.shape = 'circle';
+
+ WordCloud(element, options);
+});
+
+test('shape can be set to cardioid', function() {
+ var options = getTestOptions();
+ options.shape = 'cardioid';
+
+ WordCloud(element, options);
+});
+
+test('shape can be set to diamond', function() {
+ var options = getTestOptions();
+ options.shape = 'diamond';
+
+ WordCloud(element, options);
+});
+
+test('shape can be set to triangle', function() {
+ var options = getTestOptions();
+ options.shape = 'triangle';
+
+ WordCloud(element, options);
+});
+
+test('shape can be set to triangle-forward', function() {
+ var options = getTestOptions();
+ options.shape = 'triangle-forward';
+
+ WordCloud(element, options);
+});
+
+test('shape can be set to pentagon', function() {
+ var options = getTestOptions();
+ options.shape = 'pentagon';
+
+ WordCloud(element, options);
+});
+
+test('shape can be set to star', function() {
+ var options = getTestOptions();
+ options.shape = 'star';
+
+ WordCloud(element, options);
+});
+
+test('shape can be set to a given polar equation', function() {
+ var options = getTestOptions();
+ options.shape = function (theta) {
+ return theta / (2 * Math.PI);
+ };
+
+ WordCloud(element, options);
+});
\ No newline at end of file
diff --git a/wordcloud/wordcloud.d.ts b/wordcloud/wordcloud.d.ts
new file mode 100644
index 0000000000..61c7003a45
--- /dev/null
+++ b/wordcloud/wordcloud.d.ts
@@ -0,0 +1,105 @@
+// Type definitions for wordcloud
+// Project: https://github.com/timdream/wordcloud2.js
+// Definitions by: Joe Skeen
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+declare function WordCloud(elements: HTMLElement | HTMLElement[], options: WordCloud.Options): void;
+
+declare namespace WordCloud {
+ var isSupported: boolean;
+ var miniumFontSize: number;
+
+ interface Options {
+ /**
+ * List of words/text to paint on the canvas in a 2-d array, in the form of [word, size],
+ * e.g. [['foo', 12] , ['bar', 6]].
+ */
+ list?: Array | any[];
+ /** font to use. */
+ fontFamily?: string;
+ /** font weight to use, e.g. normal, bold or 600 */
+ fontWeight?: string | number;
+ /**
+ * color of the text, can be any CSS color, or a callback(word, weight, fontSize, distance, theta)
+ * specifies different color for each item in the list. You may also specify colors with built-in
+ * keywords: random-dark and random-light.
+ */
+ color?: string | ((word: string, weight: string | number, fontSize: number, distance: number, theta: number) => string);
+ /** minimum font size to draw on the canvas. */
+ minSize?: number;
+ /** function to call or number to multiply for size of each word in the list. */
+ weightFactor?: number | ((weight: number) => number);
+ /** paint the entire canvas with background color and consider it empty before start. */
+ clearCanvas?: boolean;
+ /** color of the background. */
+ backgroundColor?: string;
+
+ /**
+ * size of the grid in pixels for marking the availability of the canvas — the larger the grid size,
+ * the bigger the gap between words.
+ */
+ gridSize?: number;
+ /** origin of the “cloud” in [x, y]. */
+ origin?: [number, number];
+
+ /** visualize the grid by draw squares to mask the drawn areas. */
+ drawMask?: boolean;
+ /** color of the mask squares. */
+ maskColor?: string;
+ /** width of the gaps between mask squares. */
+ maskGapWidth?: number;
+
+ /** Wait for x milliseconds before start drawn the next item using setTimeout. */
+ wait?: number;
+ /** If the call with in the loop takes more than x milliseconds (and blocks the browser), abort immediately. */
+ abortThreshold?: number;
+ /** callback function to call when abort. */
+ abort?: Function;
+
+ /** If the word should rotate, the minimum rotation (in rad) the text should rotate. */
+ minRotation?: number;
+ /**
+ * If the word should rotate, the maximum rotation (in rad) the text should rotate. Set the two value equal
+ * to keep all text in one angle.
+ */
+ maxRotation?: number;
+
+ /** Shuffle the points to draw so the result will be different each time for the same list and settings. */
+ shuffle?: boolean;
+ /** Probability for the word to rotate. Set the number to 1 to always rotate. */
+ rotateRatio?: number;
+
+ /**
+ * The shape of the "cloud" to draw. Can be any polar equation represented as a callback function, or a
+ * keyword present. Available presents are circle (default), cardioid (apple or heart shape curve, the most
+ * known polar equation), diamond (alias of square), triangle-forward, triangle, (alias of triangle-upright,
+ * pentagon, and star.
+ */
+ shape?: string | ((theta: number) => number);
+ /** degree of "flatness" of the shape wordcloud2.js should draw. */
+ ellipticity?: number;
+
+ /**
+ * callback to call when the cursor enters or leaves a region occupied by a word. The callback will take
+ * arugments callback(item, dimension, event), where event is the original mousemove event. This only will work
+ * on HTML5 canvas word clouds.
+ */
+ hover?: EventCallback;
+ /**
+ * callback to call when the user clicks on a word. The callback will take arugments
+ * callback(item, dimension, event), where event is the original click event. This only will work on HTML5
+ * canvas word clouds.
+ */
+ click?: EventCallback;
+ }
+
+ interface Dimension {
+ x: number;
+ y: number;
+ w: number;
+ h: number;
+ }
+
+ type ListEntry = [string, number];
+ type EventCallback = (item: ListEntry, dimension: Dimension, event: MouseEvent) => void;
+}
\ No newline at end of file