Source: lib/genpptx.js

//
// officegen: All the code to generate PPTX/PPTS files.
//
// Please refer to README.md for this module's documentations.
//
// NOTE:
// - Before changing this code please refer to the hacking the code section on README.md.
//
// Copyright (c) 2013 Ziv Barber;
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// 'Software'), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

/**
 * Basicgen plugin to create pptx files (Microsoft PowerPoint).
 */

var baseobj = require("./basicgen.js");
var OfficeChart = require("./officechart.js");
var msdoc = require("./msofficegen.js");
var pptxShapes = require("./pptxshapes.js");
var pptxFields = require("./pptxfields.js");
var fs = require('fs');
var officeTable = require('./genofficetable');
var path = require('path');
var fast_image_size = require('fast-image-size');
var excelbuilder = require('./msexcel-builder.js');
var xmlBuilder = require('xmlbuilder');


if ( !String.prototype.encodeHTML ) {
	String.prototype.encodeHTML = function () {
		return this.replace(/&/g, '&')
			.replace(/</g, '&lt;')
			.replace(/>/g, '&gt;')
			.replace(/"/g, '&quot;');
	};
}

var GLOBAL_CHART_COUNT = 0;

/**
 * Extend officegen object with PPTX/PPSX support.
 *
 * This method extending the given officegen object to create PPTX/PPSX document.
 *
 * @param {object} genobj The object to extend.
 * @param {string} new_type The type of object to create.
 * @param {object} options The object's options.
 * @param {object} gen_private Access to the internals of this object.
 * @param {object} type_info Additional information about this type.
 * @constructor
 * @name makePptx
 */
function makePptx ( genobj, new_type, options, gen_private, type_info ) {
	/**
	 * Convert shape name to shape information.
	 *
	 * This method convert the shape information reseived from the user to the real shape information object.
	 *
	 * @param {object} shapeName Either the name of the shape or the shape information.
	 * @return Information about this shape.
	 */

	var pptWidth = 9144000;
	var pptType = 'screen4x3';

	function getShapeInfo ( shapeName ) {
		if ( !shapeName ) {
			return pptxShapes.RECTANGLE;
		} // Endif.

		if ( (typeof shapeName == 'object') && shapeName.name && shapeName.displayName && shapeName.avLst ) {
			return shapeName;
		} // Endif.

		if ( pptxShapes[shapeName] ) {
			return pptxShapes[shapeName];
		} // Endif.

		for ( var shapeIntName in pptxShapes ) {
			if ( pptxShapes[shapeIntName].name == shapeName ) {
				return pptxShapes[shapeIntName];
			} // Endif.

			if ( pptxShapes[shapeIntName].displayName == shapeName ) {
				return pptxShapes[shapeIntName];
			} // Endif.
		} // End of for loop.

		return pptxShapes.RECTANGLE;
	}

	genobj.shapes = pptxShapes;
	genobj.fields = pptxFields;
	genobj.options = (options && typeof options == 'object') ? options : {};

	// Temporary, I'll create a new code without the need to create a temp file (Ziv Barber, 2016-06-23):
	if ( !genobj.options.tempDir ) {
		genobj.options.tempDir = './';
	} // Endif.

	/**
	 * Prepare everything to generate PPTX files.
	 *
	 * This method checking for extra resources needed to add by the generator engine.
	 */
	function cbPreparePptxToGenerate () {
		genobj.generate_data = {};

		// BMK_TODO:
	}

	/**
	 * Create the 'presProps.xml' resource.
	 *
	 * @param {object} data Ignored by this callback function.
	 * @return Text string.
	 */
	function cbMakePptxPresProps ( data ) {
		return gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml ( data ) + 
		
'<p:presentationPr xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">\
	<p:extLst>\
		<p:ext uri="{E76CE94A-603C-4142-B9EB-6D1370010A27}">\
			<p14:discardImageEditData xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" val="0"/>\
		</p:ext>\
		<p:ext uri="{D31A062A-798A-4329-ABDD-BBA856620510}">\
			<p14:defaultImageDpi xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" val="220"/>\
		</p:ext>\
		<p:ext uri="{FD5EFAAD-0ECE-453E-9831-46B23BE46B34}">\
			<p15:chartTrackingRefBased xmlns:p15="http://schemas.microsoft.com/office/powerpoint/2012/main" val="1"/>\
		</p:ext>\
	</p:extLst>\
</p:presentationPr>';
	}

	/**
	 * Create the 'tableStyles.xml' resource.
	 *
	 * @param {object} data Ignored by this callback function.
	 * @return Text string.
	 */
	function cbMakePptxStyles ( data ) {
		return gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml ( data ) + '<a:tblStyleLst xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" def="{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}"/>';
	}

	/**
	 * Create the 'viewProps.xml' resource.
	 *
	 * @param {object} data Ignored by this callback function.
	 * @return Text string.
	 */
	function cbMakePptxViewProps ( data ) {
		return gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml ( data ) + '<p:viewPr xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"><p:normalViewPr><p:restoredLeft sz="15620"/><p:restoredTop sz="94660"/></p:normalViewPr><p:slideViewPr><p:cSldViewPr><p:cViewPr varScale="1"><p:scale><a:sx n="64" d="100"/><a:sy n="64" d="100"/></p:scale><p:origin x="-1392" y="-96"/></p:cViewPr><p:guideLst><p:guide orient="horz" pos="2160"/><p:guide pos="2880"/></p:guideLst></p:cSldViewPr></p:slideViewPr><p:notesTextViewPr><p:cViewPr><p:scale><a:sx n="100" d="100"/><a:sy n="100" d="100"/></p:scale><p:origin x="0" y="0"/></p:cViewPr></p:notesTextViewPr><p:gridSpacing cx="78028800" cy="78028800"/></p:viewPr>';
	}

	/**
	 * Create the 'slideLayout1.xml' resource.
	 *
	 * @param {object} data Ignored by this callback function.
	 * @return Text string.
	 */
	function cbMakePptxLayout ( data ) {
		return gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml ( data ) + '<p:sldLayout xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" type="title" preserve="1"><p:cSld name="Title Slide"><p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/><a:chOff x="0" y="0"/><a:chExt cx="0" cy="0"/></a:xfrm></p:grpSpPr><p:sp><p:nvSpPr><p:cNvPr id="2" name="Title 1"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="ctrTitle"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="685800" y="2130425"/><a:ext cx="7772400" cy="1470025"/></a:xfrm></p:spPr><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:rPr lang="en-US" smtClean="0"/><a:t>Click to edit Master title style</a:t></a:r><a:endParaRPr lang="en-US"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="3" name="Subtitle 2"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="subTitle" idx="1"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="1371600" y="3886200"/><a:ext cx="6400800" cy="1752600"/></a:xfrm></p:spPr><p:txBody><a:bodyPr/><a:lstStyle><a:lvl1pPr marL="0" indent="0" algn="ctr"><a:buNone/><a:defRPr><a:solidFill><a:schemeClr val="tx1"><a:tint val="75000"/></a:schemeClr></a:solidFill></a:defRPr></a:lvl1pPr><a:lvl2pPr marL="457200" indent="0" algn="ctr"><a:buNone/><a:defRPr><a:solidFill><a:schemeClr val="tx1"><a:tint val="75000"/></a:schemeClr></a:solidFill></a:defRPr></a:lvl2pPr><a:lvl3pPr marL="914400" indent="0" algn="ctr"><a:buNone/><a:defRPr><a:solidFill><a:schemeClr val="tx1"><a:tint val="75000"/></a:schemeClr></a:solidFill></a:defRPr></a:lvl3pPr><a:lvl4pPr marL="1371600" indent="0" algn="ctr"><a:buNone/><a:defRPr><a:solidFill><a:schemeClr val="tx1"><a:tint val="75000"/></a:schemeClr></a:solidFill></a:defRPr></a:lvl4pPr><a:lvl5pPr marL="1828800" indent="0" algn="ctr"><a:buNone/><a:defRPr><a:solidFill><a:schemeClr val="tx1"><a:tint val="75000"/></a:schemeClr></a:solidFill></a:defRPr></a:lvl5pPr><a:lvl6pPr marL="2286000" indent="0" algn="ctr"><a:buNone/><a:defRPr><a:solidFill><a:schemeClr val="tx1"><a:tint val="75000"/></a:schemeClr></a:solidFill></a:defRPr></a:lvl6pPr><a:lvl7pPr marL="2743200" indent="0" algn="ctr"><a:buNone/><a:defRPr><a:solidFill><a:schemeClr val="tx1"><a:tint val="75000"/></a:schemeClr></a:solidFill></a:defRPr></a:lvl7pPr><a:lvl8pPr marL="3200400" indent="0" algn="ctr"><a:buNone/><a:defRPr><a:solidFill><a:schemeClr val="tx1"><a:tint val="75000"/></a:schemeClr></a:solidFill></a:defRPr></a:lvl8pPr><a:lvl9pPr marL="3657600" indent="0" algn="ctr"><a:buNone/><a:defRPr><a:solidFill><a:schemeClr val="tx1"><a:tint val="75000"/></a:schemeClr></a:solidFill></a:defRPr></a:lvl9pPr></a:lstStyle><a:p><a:r><a:rPr lang="en-US" smtClean="0"/><a:t>Click to edit Master subtitle style</a:t></a:r><a:endParaRPr lang="en-US"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="4" name="Date Placeholder 3"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="dt" sz="half" idx="10"/></p:nvPr></p:nvSpPr><p:spPr/><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:fld id="{F8166F1F-CE9B-4651-A6AA-CD717754106B}" type="datetimeFigureOut"><a:rPr lang="en-US" smtClean="0"/><a:t>6/13/2013</a:t></a:fld><a:endParaRPr lang="en-US"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="5" name="Footer Placeholder 4"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="ftr" sz="quarter" idx="11"/></p:nvPr></p:nvSpPr><p:spPr/><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:endParaRPr lang="en-US"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="6" name="Slide Number Placeholder 5"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="sldNum" sz="quarter" idx="12"/></p:nvPr></p:nvSpPr><p:spPr/><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:fld id="{F7021451-1387-4CA6-816F-3879F97B5CBC}" type="slidenum"><a:rPr lang="en-US" smtClean="0"/><a:t>�#�</a:t></a:fld><a:endParaRPr lang="en-US"/></a:p></p:txBody></p:sp></p:spTree></p:cSld><p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr></p:sldLayout>';
	}

	/**
	 * Create the main presentation resource.
	 *
	 * This resource is the main resource of any PowerPoint document.
	 *
	 * @param {object} data Ignored by this callback function.
	 * @return Text string.
	 */
	function cbMakePptxPresentation ( data ) {

		var outString = gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml ( data ) + '<p:presentation xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" saveSubsetFonts="1"><p:sldMasterIdLst><p:sldMasterId id="2147483648" r:id="rId1"/></p:sldMasterIdLst><p:sldIdLst>';

		for ( var i = 0, total_size = gen_private.pages.length; i < total_size; i++ ) {
			outString += '<p:sldId id="' + (i + 256) + '" r:id="rId' + (i + 2) + '"/>';
		} // End of for loop.

		outString += '</p:sldIdLst><p:sldSz cx="' + pptWidth + '" cy="6858000" type="' + pptType + '"/><p:notesSz cx="6858000" cy="9144000"/><p:defaultTextStyle><a:defPPr><a:defRPr lang="en-US"/></a:defPPr>';

		var curPos = 0;
		for ( var i = 1; i < 10; i++ )
		{
			outString += '<a:lvl' + i + 'pPr marL="' + curPos + '" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl' + i + 'pPr>';
			curPos += 457200;
		} // End of for loop.

		outString += '</p:defaultTextStyle>';
		
		outString += '<p:extLst>\
		<p:ext uri="{EFAFB233-063F-42B5-8137-9DF3F51BA10A}">\
			<p15:sldGuideLst xmlns:p15="http://schemas.microsoft.com/office/powerpoint/2012/main"/>\
		</p:ext>\
	</p:extLst></p:presentation>';
		
		return outString;
	}

	/**
	 * Create the slides masters resource.
	 *
	 * @param {object} data Ignored by this callback function.
	 * @return Text string.
	 */
	function cbMakePptxSlideMasters ( data ) {
		return gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml ( data ) + '<p:sldMaster xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"><p:cSld><p:bg><p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef></p:bg><p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/><a:chOff x="0" y="0"/><a:chExt cx="0" cy="0"/></a:xfrm></p:grpSpPr><p:sp><p:nvSpPr><p:cNvPr id="2" name="Title Placeholder 1"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="title"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="457200" y="274638"/><a:ext cx="8229600" cy="1143000"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr><p:txBody><a:bodyPr vert="horz" lIns="91440" tIns="45720" rIns="91440" bIns="45720" rtlCol="0" anchor="ctr"><a:normAutofit/></a:bodyPr><a:lstStyle/><a:p><a:r><a:rPr lang="en-US" smtClean="0"/><a:t>Click to edit Master title style</a:t></a:r><a:endParaRPr lang="en-US"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="3" name="Text Placeholder 2"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="body" idx="1"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="457200" y="1600200"/><a:ext cx="8229600" cy="4525963"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr><p:txBody><a:bodyPr vert="horz" lIns="91440" tIns="45720" rIns="91440" bIns="45720" rtlCol="0"><a:normAutofit/></a:bodyPr><a:lstStyle/><a:p><a:pPr lvl="0"/><a:r><a:rPr lang="en-US" smtClean="0"/><a:t>Click to edit Master text styles</a:t></a:r></a:p><a:p><a:pPr lvl="1"/><a:r><a:rPr lang="en-US" smtClean="0"/><a:t>Second level</a:t></a:r></a:p><a:p><a:pPr lvl="2"/><a:r><a:rPr lang="en-US" smtClean="0"/><a:t>Third level</a:t></a:r></a:p><a:p><a:pPr lvl="3"/><a:r><a:rPr lang="en-US" smtClean="0"/><a:t>Fourth level</a:t></a:r></a:p><a:p><a:pPr lvl="4"/><a:r><a:rPr lang="en-US" smtClean="0"/><a:t>Fifth level</a:t></a:r><a:endParaRPr lang="en-US"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="4" name="Date Placeholder 3"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="dt" sz="half" idx="2"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="457200" y="6356350"/><a:ext cx="2133600" cy="365125"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr><p:txBody><a:bodyPr vert="horz" lIns="91440" tIns="45720" rIns="91440" bIns="45720" rtlCol="0" anchor="ctr"/><a:lstStyle><a:lvl1pPr algn="l"><a:defRPr sz="1200"><a:solidFill><a:schemeClr val="tx1"><a:tint val="75000"/></a:schemeClr></a:solidFill></a:defRPr></a:lvl1pPr></a:lstStyle><a:p><a:fld id="{F8166F1F-CE9B-4651-A6AA-CD717754106B}" type="datetimeFigureOut"><a:rPr lang="en-US" smtClean="0"/><a:t>6/13/2013</a:t></a:fld><a:endParaRPr lang="en-US"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="5" name="Footer Placeholder 4"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="ftr" sz="quarter" idx="3"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="3124200" y="6356350"/><a:ext cx="2895600" cy="365125"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr><p:txBody><a:bodyPr vert="horz" lIns="91440" tIns="45720" rIns="91440" bIns="45720" rtlCol="0" anchor="ctr"/><a:lstStyle><a:lvl1pPr algn="ctr"><a:defRPr sz="1200"><a:solidFill><a:schemeClr val="tx1"><a:tint val="75000"/></a:schemeClr></a:solidFill></a:defRPr></a:lvl1pPr></a:lstStyle><a:p><a:endParaRPr lang="en-US"/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id="6" name="Slide Number Placeholder 5"/><p:cNvSpPr><a:spLocks noGrp="1"/></p:cNvSpPr><p:nvPr><p:ph type="sldNum" sz="quarter" idx="4"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="6553200" y="6356350"/><a:ext cx="2133600" cy="365125"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr><p:txBody><a:bodyPr vert="horz" lIns="91440" tIns="45720" rIns="91440" bIns="45720" rtlCol="0" anchor="ctr"/><a:lstStyle><a:lvl1pPr algn="r"><a:defRPr sz="1200"><a:solidFill><a:schemeClr val="tx1"><a:tint val="75000"/></a:schemeClr></a:solidFill></a:defRPr></a:lvl1pPr></a:lstStyle><a:p><a:fld id="{F7021451-1387-4CA6-816F-3879F97B5CBC}" type="slidenum"><a:rPr lang="en-US" smtClean="0"/><a:t>�#�</a:t></a:fld><a:endParaRPr lang="en-US"/></a:p></p:txBody></p:sp></p:spTree></p:cSld><p:clrMap bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/><p:sldLayoutIdLst><p:sldLayoutId id="2147483649" r:id="rId1"/></p:sldLayoutIdLst><p:txStyles><p:titleStyle><a:lvl1pPr algn="ctr" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:spcBef><a:spcPct val="0"/></a:spcBef><a:buNone/><a:defRPr sz="4400" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mj-lt"/><a:ea typeface="+mj-ea"/><a:cs typeface="+mj-cs"/></a:defRPr></a:lvl1pPr></p:titleStyle><p:bodyStyle><a:lvl1pPr marL="342900" indent="-342900" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:spcBef><a:spcPct val="20000"/></a:spcBef><a:buFont typeface="Arial" pitchFamily="34" charset="0"/><a:buChar char="�"/><a:defRPr sz="3200" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl1pPr><a:lvl2pPr marL="742950" indent="-285750" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:spcBef><a:spcPct val="20000"/></a:spcBef><a:buFont typeface="Arial" pitchFamily="34" charset="0"/><a:buChar char="�"/><a:defRPr sz="2800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl2pPr><a:lvl3pPr marL="1143000" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:spcBef><a:spcPct val="20000"/></a:spcBef><a:buFont typeface="Arial" pitchFamily="34" charset="0"/><a:buChar char="�"/><a:defRPr sz="2400" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl3pPr><a:lvl4pPr marL="1600200" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:spcBef><a:spcPct val="20000"/></a:spcBef><a:buFont typeface="Arial" pitchFamily="34" charset="0"/><a:buChar char="�"/><a:defRPr sz="2000" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl4pPr><a:lvl5pPr marL="2057400" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:spcBef><a:spcPct val="20000"/></a:spcBef><a:buFont typeface="Arial" pitchFamily="34" charset="0"/><a:buChar char="�"/><a:defRPr sz="2000" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl5pPr><a:lvl6pPr marL="2514600" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:spcBef><a:spcPct val="20000"/></a:spcBef><a:buFont typeface="Arial" pitchFamily="34" charset="0"/><a:buChar char="�"/><a:defRPr sz="2000" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl6pPr><a:lvl7pPr marL="2971800" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:spcBef><a:spcPct val="20000"/></a:spcBef><a:buFont typeface="Arial" pitchFamily="34" charset="0"/><a:buChar char="�"/><a:defRPr sz="2000" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl7pPr><a:lvl8pPr marL="3429000" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:spcBef><a:spcPct val="20000"/></a:spcBef><a:buFont typeface="Arial" pitchFamily="34" charset="0"/><a:buChar char="�"/><a:defRPr sz="2000" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl8pPr><a:lvl9pPr marL="3886200" indent="-228600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:spcBef><a:spcPct val="20000"/></a:spcBef><a:buFont typeface="Arial" pitchFamily="34" charset="0"/><a:buChar char="�"/><a:defRPr sz="2000" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl9pPr></p:bodyStyle><p:otherStyle><a:defPPr><a:defRPr lang="en-US"/></a:defPPr><a:lvl1pPr marL="0" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl1pPr><a:lvl2pPr marL="457200" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl2pPr><a:lvl3pPr marL="914400" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl3pPr><a:lvl4pPr marL="1371600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl4pPr><a:lvl5pPr marL="1828800" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl5pPr><a:lvl6pPr marL="2286000" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl6pPr><a:lvl7pPr marL="2743200" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl7pPr><a:lvl8pPr marL="3200400" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl8pPr><a:lvl9pPr marL="3657600" algn="l" defTabSz="914400" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl9pPr></p:otherStyle></p:txStyles></p:sldMaster>';
	}

	/**
	 * Generate the XML code to describe colors.
	 *
	 * @param {object} color_info Foreground color information.
	 * @param {object} back_info Background color information.
	 */
	function cMakePptxColorSelection ( color_info, back_info )
	{
		var outText = '';
		var colorVal;
		var fillType = 'solid';
		var internalElements = '';

		if ( back_info ) {
			outText += '<p:bg><p:bgPr>';

			outText += cMakePptxColorSelection ( back_info, false );

			outText += '<a:effectLst/>';
			// BMK_TODO: (add support for effects)
			
			outText += '</p:bgPr></p:bg>';
		} // Endif.

		if ( color_info ) {
			if ( typeof color_info == 'string' ) {
				colorVal = color_info;

			} else {
				if ( color_info.type ) {
					fillType = color_info.type;
				} // Endif.

				if ( color_info.color ) {
					colorVal = color_info.color;
				} // Endif.

				if ( color_info.alpha ) {
					internalElements += '<a:alpha val="' + (100 - color_info.alpha) + '000"/>';
				} // Endif.
			} // Endif.

			switch ( fillType )
			{
				case 'solid':
					outText += '<a:solidFill><a:srgbClr val="' + colorVal + '">' + internalElements + '</a:srgbClr></a:solidFill>';
					break;
			} // End of switch.
		} // Endif.

		return outText;
	}

	/**
	 * Translate field_name into the text real value.
	 *
	 * This method creating the text to display for the given field.
	 *
	 * @param {string} field_name the name of the field.
	 * @param {number} slide_num current slide number.
	 * @return The text string data.
	 */
	function CreateFieldText ( field_name, slide_num ) {
		var curDateTime = new Date ();
		var dayInWeek = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ];
		var monthsList = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
		var monthsShortList = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
		var outValue = '';

		// curDateTime.getDate () 	Returns the day of the month (from 1-31)
		// curDateTime.getDay () 	Returns the day of the week (from 0-6)
		// curDateTime.getFullYear () 	Returns the year (four digits)
		// curDateTime.getHours () 	Returns the hour (from 0-23)
		// curDateTime.getMinutes () 	Returns the minutes (from 0-59)
		// curDateTime.getMonth () 	Returns the month (from 0-11)
		// curDateTime.getSeconds () 	Returns the seconds (from 0-59)

		switch ( field_name ) {
			// presentation slide number:
			case 'SLIDE_NUM':
			case 'slidenum':
				outValue += slide_num;
				break;

			// default date time format for the rendering application:
			case 'DATE_TIME':
			case 'datetime':
				outValue += curDateTime.getMonth () + '/' + curDateTime.getDate () + '/' + curDateTime.getFullYear ();
				break;

			// MM/DD/YYYY date time format (Example: 10/12/2007):
			case 'DATE_MM_DD_YYYY':
			case 'datetime1':
				outValue += curDateTime.getMonth () + '/' + curDateTime.getDate () + '/' + curDateTime.getFullYear ();
				break;

			// Day, Month DD, YYYY date time format (Example: Friday, October 12, 2007):
			case 'DATE_WD_MN_DD_YYYY':
			case 'datetime2':
				outValue += dayInWeek[curDateTime.getDay ()] + ', ' + monthsList[curDateTime.getMonth ()] + ' ' + curDateTime.getDate () + ', ' + curDateTime.getFullYear ();
				break;

			// DD Month YYYY date time format (Example: 12 October 2007):
			case 'DATE_DD_MN_YYYY':
			case 'datetime3':
				outValue += curDateTime.getDate () + ' ' + monthsList[curDateTime.getMonth ()] + ' ' + curDateTime.getFullYear ();
				break;

			// Month DD, YYYY date time format (Example: October 12, 2007):
			case 'DATE_MN_DD_YYYY':
			case 'datetime4':
				outValue += monthsList[curDateTime.getMonth ()] + ' ' + curDateTime.getDate () + ', ' + curDateTime.getFullYear ();
				break;

			// DD-Mon-YY date time format (Example: 12-Oct-07):
			case 'DATE_DD_SMN_YY':
			case 'datetime5':
				outValue += curDateTime.getDate () + '-' + monthsShortList[curDateTime.getMonth ()] + '-' + (curDateTime.getFullYear () % 100);
				break;

			// Month YY date time format (Example: October 07):
			case 'DATE_MM_YY':
			case 'datetime6':
				outValue += monthsList[curDateTime.getMonth ()] + ' ' + (curDateTime.getFullYear () % 100);
				break;

			// Mon-YY date time format (Example: Oct-07):
			case 'DATE_SMN_YY':
			case 'datetime7':
				outValue += monthsShortList[curDateTime.getMonth ()] + '-' + (curDateTime.getFullYear () % 100);
				break;

			// MM/DD/YYYY hh:mm AM/PM date time format (Example: 10/12/2007 4:28 PM):
			case 'DATE_TIME_DD_MM_YYYY_HH_MM_PM':
			case 'datetime8':
				outValue += curDateTime.getMonth () + '/' + curDateTime.getDate () + '/' + curDateTime.getFullYear ();
				outValue += (curDateTime.getHours () % 12) + ':' + curDateTime.getMinutes ();
				outValue += (curDateTime.getHours () > 11) ? ' PM' : ' AM';
				break;

			// MM/DD/YYYY hh:mm:ss AM/PM date time format (Example: 10/12/2007 4:28:34 PM):
			case 'DATE_TIME_DD_MM_YYYY_HH_MM_SC_PM':
			case 'datetime9':
				outValue += curDateTime.getMonth () + '/' + curDateTime.getDate () + '/' + curDateTime.getFullYear ();
				outValue += (curDateTime.getHours () % 12) + ':' + curDateTime.getMinutes () + ':' + curDateTime.getSeconds ();
				outValue += (curDateTime.getHours () > 11) ? ' PM' : ' AM';
				break;

			// hh:mm date time format (Example: 16:28):
			case 'TIME_HH_MM':
			case 'datetime10':
				outValue += curDateTime.getHours () + ':' + curDateTime.getMinutes ();
				break;

			// hh:mm:ss date time format (Example: 16:28:34):
			case 'TIME_HH_MM_SC':
			case 'datetime11':
				outValue += curDateTime.getHours () + ':' + curDateTime.getMinutes () + ':' + curDateTime.getSeconds ();
				break;

			// hh:mm AM/PM date time format (Example: 4:28 PM):
			case 'TIME_HH_MM_PM':
			case 'datetime12':
				outValue += (curDateTime.getHours () % 12) + ':' + curDateTime.getMinutes ();
				outValue += (curDateTime.getHours () > 11) ? ' PM' : ' AM';
				break;

			// hh:mm:ss: AM/PM date time format (Example: 4:28:34 PM):
			case 'TIME_HH_MM_SC_PM':
			case 'datetime13':
				outValue += (curDateTime.getHours () % 12) + ':' + curDateTime.getMinutes () + ':' + curDateTime.getSeconds ();
				outValue += (curDateTime.getHours () > 11) ? ' PM' : ' AM';
				break;

			default:
				return null;
		} // End of switch.

		return outValue;
	}

	/**
	 * ???.
	 *
	 * @param {object} text_info Information how to display the text.
	 * @param {object} slide_obj The object of this slider.
	 * @return Text string.
	 */
	function cMakePptxOutTextData ( text_info, slide_obj ) {
		var out_obj = {};

		out_obj.font_size = '';
		out_obj.bold = '';
		out_obj.italic = '';
		out_obj.strike = '';
		out_obj.underline = '';
		out_obj.rpr_info = '';
        out_obj.char_spacing = '';

		if ( typeof text_info == 'object' )
		{
			if ( text_info.bold ) {
				out_obj.bold = ' b="1"';
			} // Endif.

			if ( text_info.italic ) {
				out_obj.italic = ' i="1"';
			} // Endif.

			if ( text_info.strike ) {
				out_obj.strike = ' strike="sngStrike"';
			} // Endif.

			if ( text_info.underline ) {
				out_obj.underline = ' u="sng"';
			} // Endif.

			if ( text_info.font_size ) {
				out_obj.font_size = ' sz="' + text_info.font_size + '00"';
			} // Endif.

      //psv 2015-01-21 Manually copied in from https://github.com/Ziv-Barber/officegen/pull/41/files
      if ( text_info.char_spacing ) {
        out_obj.char_spacing = ' spc="' + (text_info.char_spacing * 100) + '"';
        // must also disable kerning; otherwise text won't actually expand
            out_obj.char_spacing += ' kern="0"';
      } // Endif.


			if ( text_info.color ) {
				out_obj.rpr_info += cMakePptxColorSelection ( text_info.color );

			} else if ( slide_obj && slide_obj.color )
			{
				out_obj.rpr_info += cMakePptxColorSelection ( slide_obj.color );
			} // Endif.

			if ( text_info.font_face ) {
				out_obj.rpr_info += '<a:latin typeface="' + text_info.font_face + '" pitchFamily="34" charset="0"/><a:cs typeface="' + text_info.font_face + '" pitchFamily="34" charset="0"/>';
			} // Endif.

		} else {
			if ( slide_obj && slide_obj.color )
			{
				out_obj.rpr_info += cMakePptxColorSelection ( slide_obj.color );
			} // Endif.
		} // Endif.

		if ( out_obj.rpr_info != '' )
			out_obj.rpr_info += '</a:rPr>';

		return out_obj;
	}

	/**
	 * Create a text object for adding into a slide.
	 *
	 * @param {object} text_info Information how to display the text.
	 * @param {object} text_string The text string or requested field.
	 * @param {object} slide_obj The object of this slider.
	 * @param {object} slide_num Current slide number.
	 * @return The PPTX code.
	 */
	function cMakePptxOutTextCommand ( text_info, text_string, slide_obj, slide_num ) {
		var area_opt_data = cMakePptxOutTextData ( text_info, slide_obj );
		var textStyles = ['font_size', 'strike', 'italic', 'bold', 'underline', 'char_spacing'].reduce(function(acc, attr) {
			return acc + area_opt_data[attr]
		}, '');
		var parsedText;
		var startInfo = '<a:rPr lang="en-US"' + textStyles + ' dirty="0" smtClean="0"' +
			(area_opt_data.rpr_info != '' ? ('>' + area_opt_data.rpr_info) : '/>') + '<a:t>';
		var endTag = '</a:r>';
		var outData = '<a:r>' + startInfo;

		if ( text_string.field ) {
			endTag = '</a:fld>';
			var outTextField = pptxFields[text_string.field];
			if ( outTextField === null ) {
				for ( var fieldIntName in pptxFields ) {
					if ( pptxFields[fieldIntName] === text_string.field ) {
						outTextField = text_string.field;
						break;
					} // Endif.
				} // End of for loop.

				if ( outTextField === null ) {
					outTextField = 'datetime';
				} // Endif.
			} // Endif.

			outData = '<a:fld id="{' + gen_private.plugs.type.msoffice.makeUniqueID ( '5C7A2A3D' ) + '}" type="' + outTextField + '">' + startInfo;
			outData += CreateFieldText ( outTextField, slide_num );

		} else {
		// Automatic support for newline - split it into multi-p:
			parsedText = text_string.split ( "\n" );
		if ( parsedText.length > 1 ) {
			var outTextData = '';
			for ( var i = 0, total_size_i = parsedText.length; i < total_size_i; i++ ) {
				outTextData += outData + parsedText[i].encodeHTML ();

				if ( (i + 1) < total_size_i ) {
					outTextData += '</a:t></a:r></a:p><a:p>';
				} // Endif.
			} // End of for loop.

			outData = outTextData;

		} else {
			outData += text_string.encodeHTML ();
		} // Endif.
		} // Endif.

		var outBreakP = '';
		if ( text_info.breakLine ) {
			outBreakP += '</a:p><a:p>';
		} // Endif.
		
		return outData + '</a:t>' + endTag + outBreakP;
	}

	/**
	 * ???.
	 *
	 * @param {object} in_data_val Input value as passed by the user.
	 * @param {number} max_value Maximum value allowed.
	 * @param {number} def_value Default value.
	 * @param {number} auto_val ???.
	 * @param {number} mul_val ???.
	 * @return ???.
	 */
	function parseSmartNumber ( in_data_val, max_value, def_value, auto_val, mul_val ) {	
		if ( typeof in_data_val == 'undefined' ) {
			return (typeof def_value == 'number') ? def_value : 0;
		} // Endif.

		if ( in_data_val == '' ) {
			in_data_val = 0;
		} // Endif.
		
		if ( typeof in_data_val == 'string' && !isNaN ( in_data_val ) ) {
			in_data_val = parseInt ( in_data_val, 10 );
		} // Endif.
	
		var realNum = Math.round ( mul_val ? in_data_val * mul_val : in_data_val );

		if ( typeof in_data_val == 'string' ) {
			if ( in_data_val.indexOf ( '%' ) != -1 ) {
				var realMax = (typeof max_value == 'number') ? max_value : 0;
				if ( realMax <= 0 ) return 0;

				var realVal = parseInt ( in_data_val, 10 );
				return Math.round ( (realMax / 100) * realVal );
			} // Endif.

			if ( in_data_val.indexOf ( '#' ) != -1 ) {
				var realVal = parseInt ( in_data_val, 10 );
				return realMax;
			} // Endif.

			var realAuto = (typeof auto_val == 'number') ? auto_val : 0;

			if ( in_data_val == '*' ) {
				return realAuto;
			} // Endif.

			if ( in_data_val == 'c' ) {
				return Math.round ( realAuto / 2 );
			} // Endif.

			return (typeof def_value == 'number') ? def_value : 0;
		} // Endif.
	
		if ( typeof in_data_val == 'number' ) {
			return realNum;
		} // Endif.

		return (typeof def_value == 'number') ? def_value : 0;
	}

	/**
	 * Create the XML code of a single effect.
	 *
	 * This method creating the effect XML code for a single object.
	 *
	 * @param {object} effectData Effect data.
	 * @param {string} effectName The name of the effect.
	 */
	function cbGenerateEffects ( effectData, effectName ) {
		var outData = '<a:' + effectName + ' ';
		var color = effectData.color || 'black';
		var alphaPer = 60;
		var algnData = '';
		var blurRad = 50800;
		var dist = 38100;
		var dir = 13500000;

		if ( typeof effectData.transparency == 'number' ) {
			alphaPer = effectData.transparency;
		} // Endif.

		if ( (alphaPer > 100) || (alphaPer < 0) )
			alphaPer = 60;

		alphaPer = (100 - alphaPer) * 1000;

		if ( effectData.align ) {
			if ( effectData.align.top )
				algnData += 't';

			if ( effectData.align.bottom )
				algnData += 'b';

			if ( effectData.align.left )
				algnData += 'l';

			if ( effectData.align.right )
				algnData += 'r';
		} // Endif.

		if ( algnData == '' )
			algnData = 'br';

		// Size
		// Blur
		// Angle
		// Distance
		// BMK_TODO:

		outData += ' blurRad="' + blurRad + '" dist="' + dist + '" dir="' + dir + '" algn="' + algnData + '" rotWithShape="0"';

		// sx="24000" sy="24000"
		// BMK_TODO:

		outData += '><a:prstClr val="' + color + '"><a:alpha val="' + alphaPer + '"/></a:prstClr>';
		return outData + '</a:' + effectName + '>';
	}

	/**
	 * Create the body properties code for text.
	 *
	 * This method creating the XML code of the body properties of a text.
	 *
	 * @return The body properties XML code.
	 */
	function createBodyProperties ( objOptions ) {
		var bodyProperties = '<a:bodyPr';

		if ( objOptions && objOptions.bodyProp ) {
			// Set anchorPoints bottom, center or top:
			if ( objOptions.bodyProp.anchor ) {
				bodyProperties += ' anchor="' + objOptions.bodyProp.anchor + '"';
			} // Endif.

			if ( objOptions.bodyProp.anchorCtr ) {
				bodyProperties += ' anchorCtr="' + objOptions.bodyProp.anchorCtr + '"';
			} // Endif.

			// Enable or disable textwrapping none or square:
			if ( objOptions.bodyProp.wrap ) {
				bodyProperties += ' wrap="' + objOptions.bodyProp.wrap + '"';

			} else {
				bodyProperties += ' wrap="square"';
			} // Endif.

			// Box margins(padding):
			// BMK_TODO: I should pass a better value as the auto_val parameter of parseSmartNumber().
			if ( objOptions.bodyProp.bIns ) {
				bodyProperties += ' bIns="' + parseSmartNumber ( objOptions.bodyProp.bIns, 6858000, 369332, 6858000, 10000 ) + '"';
			} // Endif.

			if ( objOptions.bodyProp.lIns ) {
				bodyProperties += ' lIns="' + parseSmartNumber ( objOptions.bodyProp.lIns, 9144000, 2819400, 9144000, 10000 ) + '"';
			} // Endif.

			if ( objOptions.bodyProp.rIns ) {
				bodyProperties += ' rIns="' + parseSmartNumber ( objOptions.bodyProp.rIns, 9144000, 2819400, 9144000, 10000 ) + '"';
			} // Endif.

			if ( objOptions.bodyProp.tIns ) {
				bodyProperties += ' tIns="' + parseSmartNumber ( objOptions.bodyProp.tIns, 6858000, 369332, 6858000, 10000 ) + '"';
			} // Endif.

			bodyProperties += ' rtlCol="0">';

			if ( objOptions.bodyProp.autoFit !== false ) {
				bodyProperties += '<a:spAutoFit/>';
			} // Endif.

			bodyProperties += '</a:bodyPr>';

		// Default:
		} else {
			bodyProperties += ' wrap="square" rtlCol="0"></a:bodyPr>';
		} // Endif.

		return bodyProperties;
	}

	/**
	 * Generate a slider resource.
	 *
	 * This function generating a slider XML resource.
	 *
	 * @param {object} data The main slide object.
	 * @return Text string.
	 */
	function cbMakePptxSlide ( data ) {
		var outString = gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml ( data ) + '<p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"';
		var objs_list = data.data;
		var timingData = '';

		if ( !data.slide.show ) {
			outString += ' show="0"';
		} // Endif.

		outString += '><p:cSld>';

		if ( data.slide.back ) {
			outString += cMakePptxColorSelection ( false, data.slide.back );
		} // Endif.

		outString += '<p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/><a:chOff x="0" y="0"/><a:chExt cx="0" cy="0"/></a:xfrm></p:grpSpPr>';

		// Loop on all the objects inside the slide to add it into the slide:
		for ( var i = 0, total_size = objs_list.length; i < total_size; i++ ) {
			var x = 0;
			var y = 0;
			var cx = 2819400;
			var cy = 369332;

			var moreStyles = '';
			var moreStylesAttr = '';
			var outStyles = '';
			var styleData = '';
			var shapeType = null;
			var locationAttr = '';

			if ( objs_list[i].options ) {
				if ( typeof objs_list[i].options.cx != 'undefined' ) {
					if ( objs_list[i].options.cx ) {
						cx = parseSmartNumber ( objs_list[i].options.cx, pptWidth, 2819400, pptWidth, 10000 );

					} else {
						cx = 1;
					} // Endif.
				} // Endif.

				if ( typeof objs_list[i].options.cy != 'undefined' ) {
					if ( objs_list[i].options.cy ) {
						cy = parseSmartNumber ( objs_list[i].options.cy, 6858000, 369332, 6858000, 10000 );

					} else {
						cy = 1;
					} // Endif.
				} // Endif.

				if ( objs_list[i].options.x ) {
					x = parseSmartNumber ( objs_list[i].options.x, pptWidth, 0, pptWidth - cx, 10000 );
				} // Endif.

				if ( objs_list[i].options.y ) {
					y = parseSmartNumber ( objs_list[i].options.y, 6858000, 0, 6858000 - cy, 10000 );
				} // Endif.

				if ( objs_list[i].options.shape ) {
					shapeType = getShapeInfo ( objs_list[i].options.shape );
				} // Endif.

				if ( objs_list[i].options.flip_vertical ) {
					locationAttr += ' flipV="1"';
				} // Endif.

				if ( objs_list[i].options.rotate ) {
					var rotateVal = objs_list[i].options.rotate > 360 ? (objs_list[i].options.rotate - 360) : objs_list[i].options.rotate;
					rotateVal *= 60000;
					locationAttr += ' rot="' + rotateVal + '"';
				} // Endif.
			} // Endif.

			switch ( objs_list[i].type ) {
				// TODO: remove hard code here
        case 'table':


          var table_obj = officeTable.getTable(objs_list[i].data, objs_list[i].options);
          var table_xml = xmlBuilder.create(table_obj,{version: '1.0', encoding: 'UTF-8', standalone: true}).toString({ pretty: true, indent: '  ', newline: '\n' });

          outString += table_xml;
          break;

				case 'chart':
					// loop through the charts
					//

					if( objs_list[i].renderType === 'pie' )
					{
						outString += '<p:graphicFrame>\
							<p:nvGraphicFramePr>\
								<p:cNvPr id="20" name="OfficeChart 19"/>\
								<p:cNvGraphicFramePr/>\
								<p:nvPr>\
									<p:extLst>\
										<p:ext uri="{D42A27DB-BD31-4B8C-83A1-F6EECF244321}">\
											<p14:modId xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" val="4198609065"/>\
										</p:ext>\
									</p:extLst>\
								</p:nvPr>\
							</p:nvGraphicFramePr>\
							<p:xfrm>\
								<a:off x="'+( objs_list[i].options.x || 1524000 )+'" y="'+( objs_list[i].options.y || 1397000 )+'"/>\
								<a:ext cx="'+( objs_list[i].options.cx || 6096000 )+'" cy="'+( objs_list[i].options.cy || 4064000 )+'"/>\
							</p:xfrm>\
							<a:graphic>\
								<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart">\
									<c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId2"/>\
								</a:graphicData>\
							</a:graphic>\
						</p:graphicFrame>'
					}
					else if( objs_list[i].renderType === 'column' )
					{
						outString += '\
						\
						<p:graphicFrame>\
							<p:nvGraphicFramePr>\
								<p:cNvPr id="4" name="OfficeChart 3"/>\
								<p:cNvGraphicFramePr/>\
								<p:nvPr>\
									<p:extLst>\
										<p:ext uri="{D42A27DB-BD31-4B8C-83A1-F6EECF244321}">\
											<p14:modId xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" val="1256887135"/>\
										</p:ext>\
									</p:extLst>\
								</p:nvPr>\
							</p:nvGraphicFramePr>\
							<p:xfrm>\
								<a:off x="'+( objs_list[i].options.x || 1524000 )+'" y="'+( objs_list[i].options.y || 1397000 )+'"/>\
								<a:ext cx="'+( objs_list[i].options.cx || 6096000 )+'" cy="'+( objs_list[i].options.cy || 4064000 )+'"/>\
							</p:xfrm>\
							<a:graphic>\
								<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart">\
									<c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId2"/>\
								</a:graphicData>\
							</a:graphic>\
						</p:graphicFrame>\
						'
					}
					break;
				case 'text':
				case 'cxn':
					var effectsList = '';

					if ( shapeType == null ) shapeType = getShapeInfo ( null );

					// if ( objs_list[i].type == 'text' ) {
					// 	if ( !objs_list[i].options || (!objs_list[i].options.cx && !objs_list[i].options.cx) ) {
					// 		objs_list[i].options = objs_list[i].options ? objs_list[i].options : {};
					// 		objs_list[i].options.bodyProp = objs_list[i].options.bodyProp ? objs_list[i].options.bodyProp : {};
					// 		objs_list[i].options.bodyProp.autoFit = true;
					// 		cx = 9144000 - x;
					// 		cy = 6858000 - y;
					// 	} // Endif.
					// } // Endif.

					if ( objs_list[i].type == 'cxn' ) {
						outString += '<p:cxnSp><p:nvCxnSpPr>';
						outString += '<p:cNvPr id="' + (i + 2) + '" name="Object ' + (i + 1) + '"/><p:nvPr/></p:nvCxnSpPr>';

					} else {
						outString += '<p:sp><p:nvSpPr>';
						outString += '<p:cNvPr id="' + (i + 2) + '" name="Object ' + (i + 1) + '"/><p:cNvSpPr txBox="1"/><p:nvPr/></p:nvSpPr>';
					} // Endif.

					outString += '<p:spPr>';

					outString += '<a:xfrm' + locationAttr + '>';

					outString += '<a:off x="' + x + '" y="' + y + '"/><a:ext cx="' + cx + '" cy="' + cy + '"/></a:xfrm><a:prstGeom prst="' + shapeType.name + '">';
					
					//string changed to take into account change of shape that you do by moving the little yellow dot
					
					if(shapeType.avLst != {}){
						outString += '<a:avLst>';
						for (var adj in shapeType.avLst){
							outString +='<a:gd name="' + adj + '" fmla="val ' + shapeType.avLst.adj + '"/>';
						}
					}
					
					outString +='</a:avLst></a:prstGeom>';

					if ( objs_list[i].options ) {
						if ( objs_list[i].options.fill ) {
							outString += cMakePptxColorSelection ( objs_list[i].options.fill );

						} else {
							outString += '<a:noFill/>';
						} // Endif.

						if ( objs_list[i].options.line ) {
							var lineAttr = '';

							if ( objs_list[i].options.line_size ) {
								lineAttr += ' w="' + (objs_list[i].options.line_size * 12700) + '"';
							} // Endif.

							// cmpd="dbl"

							outString += '<a:ln' + lineAttr + '>';
							outString += cMakePptxColorSelection ( objs_list[i].options.line );

							if ( objs_list[i].options.line_head ) {
								outString += '<a:headEnd type="' + objs_list[i].options.line_head + '"/>';
							} // Endif.

							if ( objs_list[i].options.line_tail ) {
								outString += '<a:tailEnd type="' + objs_list[i].options.line_tail + '"/>';
							} // Endif.

							outString += '</a:ln>';
						} // Endif.

					} else {
						outString += '<a:noFill/>';
					} // Endif.

					if ( objs_list[i].options.effects ) {
						for ( var ii = 0, total_size_ii = objs_list[i].options.effects.length; ii < total_size_ii; ii++ ) {
							switch ( objs_list[i].options.effects[ii].type ) {
								case 'outerShadow':
									effectsList += cbGenerateEffects ( objs_list[i].options.effects[ii], 'outerShdw' );
									break;

								case 'innerShadow':
									effectsList += cbGenerateEffects ( objs_list[i].options.effects[ii], 'innerShdw' );
									break;
							} // End of switch.
						} // End of for loop.
					} // Endif.

					if ( effectsList != '' ) {
						outString += '<a:effectLst>' + effectsList + '</a:effectLst>';
					} // Endif.

					outString += '</p:spPr>';

					if ( objs_list[i].options ) {
						if ( objs_list[i].options.align ) {
							switch ( objs_list[i].options.align )
							{
								case 'right':
									moreStylesAttr += ' algn="r"';
									break;

								case 'center':
									moreStylesAttr += ' algn="ctr"';
									break;

								case 'justify':
									moreStylesAttr += ' algn="just"';
									break;
							} // End of switch.
						} // Endif.

						if ( objs_list[i].options.indentLevel > 0 ) {
								moreStylesAttr += ' lvl="' + objs_list[i].options.indentLevel + '"';
						} // Endif.
					} // Endif.

					if ( moreStyles != '' ) {
						outStyles = '<a:pPr' + moreStylesAttr + '>' + moreStyles + '</a:pPr>';

					} else if ( moreStylesAttr != '' ) {
						outStyles = '<a:pPr' + moreStylesAttr + '/>';
					} // Endif.

					if ( styleData != '' ) {
						outString += '<p:style>' + styleData + '</p:style>';
					} // Endif.

					if ( typeof objs_list[i].text == 'string' ) {
						outString += '<p:txBody>' + createBodyProperties ( objs_list[i].options ) + '<a:lstStyle/><a:p>' + outStyles;
						outString += cMakePptxOutTextCommand ( objs_list[i].options, objs_list[i].text, data.slide, data.slide.getPageNumber () );

					} else if ( typeof objs_list[i].text == 'number' ) {
						outString += '<p:txBody>' + createBodyProperties ( objs_list[i].options ) + '<a:lstStyle/><a:p>' + outStyles;
						outString += cMakePptxOutTextCommand ( objs_list[i].options, objs_list[i].text + '', data.slide, data.slide.getPageNumber () );

					} else if ( objs_list[i].text && objs_list[i].text.length ) {
						var outBodyOpt = createBodyProperties ( objs_list[i].options );
						outString += '<p:txBody>' + outBodyOpt + '<a:lstStyle/><a:p>' + outStyles;

						for ( var j = 0, total_size_j = objs_list[i].text.length; j < total_size_j; j++ ) {
							if ( (typeof objs_list[i].text[j] == 'object') && objs_list[i].text[j].text ) {
								outString += cMakePptxOutTextCommand ( objs_list[i].text[j].options || objs_list[i].options, objs_list[i].text[j].text, data.slide, outBodyOpt, outStyles, data.slide.getPageNumber () );

							} else if ( typeof objs_list[i].text[j] == 'string' ) {
								outString += cMakePptxOutTextCommand ( objs_list[i].options, objs_list[i].text[j], data.slide, outBodyOpt, outStyles, data.slide.getPageNumber () );

							} else if ( typeof objs_list[i].text[j] == 'number' ) {
								outString += cMakePptxOutTextCommand ( objs_list[i].options, objs_list[i].text[j] + '', data.slide, outBodyOpt, outStyles, data.slide.getPageNumber () );

							} else if ( (typeof objs_list[i].text[j] == 'object') && objs_list[i].text[j].field ) {
								outString += cMakePptxOutTextCommand ( objs_list[i].options, objs_list[i].text[j], data.slide, outBodyOpt, outStyles, data.slide.getPageNumber () );
							} // Endif.
						} // Endif.

					} else if ( (typeof objs_list[i].text == 'object') && objs_list[i].text.field ) {
						outString += '<p:txBody>' + createBodyProperties ( objs_list[i].options ) + '<a:lstStyle/><a:p>' + outStyles;
						outString += cMakePptxOutTextCommand ( objs_list[i].options, objs_list[i].text, data.slide, data.slide.getPageNumber () );
					} // Endif.

					// We must add that at the end of every paragraph with text:
					if ( typeof objs_list[i].text != 'undefined' ) {
						var font_size = '';
						if ( objs_list[i].options && objs_list[i].options.font_size ) {
							font_size = ' sz="' + objs_list[i].options.font_size + '00"';
						} // Endif.

						outString += '<a:endParaRPr lang="en-US"' + font_size + ' dirty="0"/></a:p></p:txBody>';
					} // Endif.

					outString += objs_list[i].type == 'cxn' ? '</p:cxnSp>' : '</p:sp>';
					break;

				// Table:
				case 'table':
					outString += '<p:graphicFrame><p:nvGraphicFramePr><p:cNvPr id="' + (i + 2) + '" name="Object ' + (i + 1) + '"/><p:cNvGraphicFramePr><a:graphicFrameLocks noGrp="1"/></p:cNvGraphicFramePr><p:nvPr/></p:nvGraphicFramePr>';
					outString += '<p:xfrm><a:off x="' + x + '" y="' + y + '"/><a:ext cx="' + cx + '" cy="' + cy + '"/></p:xfrm>';
					outString += '<a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/table"><a:tbl><a:tblPr firstRow="1" bandRow="1"><a:tableStyleId>{073A0DAA-6AF3-43AB-8588-CEC1D06C72B9}</a:tableStyleId></a:tblPr><a:tblGrid>';
					// <a:gridCol w="3276600"/>
					outString += '</a:tblGrid>';
					// objs_list[i].options
					// objs_list[i].rows[][].text
					// BMK_TODO:
					break;

				// Image:
				case 'image':
          //psv 2015-01-21 Manually copied this section from https://github.com/Ziv-Barber/officegen/pull/39/files?w=1
					//outString += '<p:pic><p:nvPicPr><p:cNvPr id="' + (i + 2) + '" name="Object ' + (i + 1) + '"/><p:cNvPicPr><a:picLocks noChangeAspect="1"/></p:cNvPicPr><p:nvPr/></p:nvPicPr><p:blipFill><a:blip r:embed="rId' + objs_list[i].rel_id + '" cstate="print"/><a:stretch><a:fillRect/></a:stretch></p:blipFill><p:spPr><a:xfrm' + locationAttr + '><a:off x="' + x + '" y="' + y + '"/><a:ext cx="' + cx + '" cy="' + cy + '"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr></p:pic>';
          var parts = [];
          parts.push('<p:pic><p:nvPicPr><p:cNvPr id="' + (i + 2) + '" name="Object ' + (i + 1) + '"');
          if (objs_list[i].link_rel_id) {
            parts.push('><a:hlinkClick r:id="rId' + objs_list[i].link_rel_id + '"/></p:cNvPr>');
          } else {
            parts.push('/>');
          }
          parts.push('<p:cNvPicPr><a:picLocks noChangeAspect="1"/></p:cNvPicPr><p:nvPr/></p:nvPicPr><p:blipFill><a:blip r:embed="rId' + objs_list[i].rel_id + '" cstate="print"/><a:stretch><a:fillRect/></a:stretch></p:blipFill><p:spPr><a:xfrm' + locationAttr + '><a:off x="' + x + '" y="' + y + '"/><a:ext cx="' + cx + '" cy="' + cy + '"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr></p:pic>');
          outString += parts.join('');
          //-- psv 2015-01-21 end merge
					break;

				// Paragraph:
				case 'p':
					if ( shapeType == null ) shapeType = getShapeInfo ( null );

					outString += '<p:sp><p:nvSpPr>';
					outString += '<p:cNvPr id="' + (i + 2) + '" name="Object ' + (i + 1) + '"/><p:cNvSpPr txBox="1"/><p:nvPr/></p:nvSpPr>';
					outString += '<p:spPr>';

					outString += '<a:xfrm' + locationAttr + '>';

					outString += '<a:off x="' + x + '" y="' + y + '"/><a:ext cx="' + cx + '" cy="' + cy + '"/></a:xfrm><a:prstGeom prst="' + shapeType.name + '"><a:avLst/></a:prstGeom>';

					if ( objs_list[i].options ) {
						if ( objs_list[i].options.fill ) {
							outString += cMakePptxColorSelection ( objs_list[i].options.fill );

						} else {
							outString += '<a:noFill/>';
						} // Endif.

						if ( objs_list[i].options.line ) {
							outString += '<a:ln>';
							outString += cMakePptxColorSelection ( objs_list[i].options.line );

							if ( objs_list[i].options.line_head ) {
								outString += '<a:headEnd type="' + objs_list[i].options.line_head + '"/>';
							} // Endif.

							if ( objs_list[i].options.line_tail ) {
								outString += '<a:tailEnd type="' + objs_list[i].options.line_tail + '"/>';
							} // Endif.

							outString += '</a:ln>';
						} // Endif.

					} else {
						outString += '<a:noFill/>';
					} // Endif.

					outString += '</p:spPr>';

					if ( styleData != '' ) {
						outString += '<p:style>' + styleData + '</p:style>';
					} // Endif.

					outString += '<p:txBody><a:bodyPr wrap="square" rtlCol="0"><a:spAutoFit/></a:bodyPr><a:lstStyle/>';

					for ( var j = 0, total_size_j = objs_list[i].data.length; j < total_size_j; j++ ) {
						if ( objs_list[i].data[j] ) {
							moreStylesAttr = '';
							moreStyles = '';
							
							if ( objs_list[i].data[j].options ) {
								if ( objs_list[i].data[j].options.align ) {
									switch ( objs_list[i].data[j].options.align )
									{
										case 'right':
											moreStylesAttr += ' algn="r"';
											break;

										case 'center':
											moreStylesAttr += ' algn="ctr"';
											break;

										case 'justify':
											moreStylesAttr += ' algn="just"';
											break;
									} // End of switch.
								} // Endif.

								if ( objs_list[i].data[j].options.indentLevel > 0 ) {
									moreStylesAttr += ' lvl="' + objs_list[i].data[j].options.indentLevel + '"';
								} // Endif.

								if ( objs_list[i].data[j].options.listType == 'number' ) {
									moreStyles += '<a:buFont typeface="+mj-lt"/><a:buAutoNum type="arabicPeriod"/>';
								} // Endif.
							} // Endif.

							if ( moreStyles != '' ) {
								outStyles = '<a:pPr' + moreStylesAttr + '>' + moreStyles + '</a:pPr>';

							} else if ( moreStylesAttr != '' ) {
								outStyles = '<a:pPr' + moreStylesAttr + '/>';
							} // Endif.

							outString += '<a:p>' + outStyles;

							// if ( typeof objs_list[i].data[j].text == 'string' ) {
							outString += cMakePptxOutTextCommand ( objs_list[i].data[j].options, objs_list[i].data[j].text, data.slide, data.slide.getPageNumber () );
							// BMK_TODO:
						} // Endif.
					} // Endif.

					var font_size = '';
					if ( objs_list[i].options && objs_list[i].options.font_size ) {
						font_size = ' sz="' + objs_list[i].options.font_size + '00"';
					} // Endif.

					outString += '<a:endParaRPr lang="en-US"' + font_size + ' dirty="0"/></a:p>';
					outString += '</p:txBody>';

					outString += '</p:sp>';
					break;
			} // End of switch.
		} // End of for loop.

		outString += '</p:spTree></p:cSld><p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>';

		if ( timingData != '' ) {
			outString += '<p:timing>' + timingData + '</p:timing>';
		} // Endif.

		outString += '</p:sld>';
		return outString;
	}

	/**
	 * Generate the extended attributes file (app) for PPTX/PPSX documents.
	 *
	 * @param {object} data Ignored by this callback function.
	 * @return Text string.
	 */
	function cbMakePptxApp ( data ) {
		var slidesCount = gen_private.pages.length;
		var userName = genobj.options.creator || 'officegen';
		var outString = gen_private.plugs.type.msoffice.cbMakeMsOfficeBasicXml ( data ) + '<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><TotalTime>0</TotalTime><Words>0</Words><Application>Microsoft Office PowerPoint</Application><PresentationFormat>On-screen Show (4:3)</PresentationFormat><Paragraphs>0</Paragraphs><Slides>' + slidesCount + '</Slides><Notes>0</Notes><HiddenSlides>0</HiddenSlides><MMClips>0</MMClips><ScaleCrop>false</ScaleCrop><HeadingPairs><vt:vector size="4" baseType="variant"><vt:variant><vt:lpstr>Theme</vt:lpstr></vt:variant><vt:variant><vt:i4>1</vt:i4></vt:variant><vt:variant><vt:lpstr>Slide Titles</vt:lpstr></vt:variant><vt:variant><vt:i4>' + slidesCount + '</vt:i4></vt:variant></vt:vector></HeadingPairs><TitlesOfParts><vt:vector size="' + (slidesCount + 1) + '" baseType="lpstr"><vt:lpstr>Office Theme</vt:lpstr>';

		for ( var i = 0, total_size = gen_private.pages.length; i < total_size; i++ ) {
			outString += '<vt:lpstr>' + gen_private.pages[i].slide.name.encodeHTML () + '</vt:lpstr>';
		} // End of for loop.

		outString += '</vt:vector></TitlesOfParts><Company>' + userName + '</Company><LinksUpToDate>false</LinksUpToDate><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>12.0000</AppVersion></Properties>';
		return outString;
	}

	/**
	 * Create XML string for a chart description
	 *
	 * @param {object} chartInfo
	 * @return Text Xml string.
	 */
	function cbMakeCharts ( chartInfo ) {
		var chart = new OfficeChart(chartInfo);
		return chart.toXML();
	}
	
	function cbMakeChartDataExcel ( data ) {
		// PSV not sure why this method is here.  Presumably vestigial from earlier code.
	}	
	
	// Prepare genobj for MS-Office:
	msdoc.makemsdoc ( genobj, new_type, options, gen_private, type_info );
	gen_private.plugs.type.msoffice.makeOfficeGenerator ( 'ppt', 'presentation', {} );

	gen_private.features.page_name = 'slides'; // This document type must have pages.

	gen_private.plugs.type.msoffice.addInfoType ( 'dc:title', '', 'title', 'setDocTitle' );

	genobj.on ( 'beforeGen', cbPreparePptxToGenerate );

	var type_of_main_doc = 'slideshow';
	if ( new_type != 'ppsx' )
	{
		type_of_main_doc = 'presentation';
	} // Endif.

	gen_private.type.msoffice.files_list.push (
		{
			name: '/ppt/slideMasters/slideMaster1.xml',
			type: 'application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml',
			clear: 'type'
		},
		{
			name: '/ppt/presProps.xml',
			type: 'application/vnd.openxmlformats-officedocument.presentationml.presProps+xml',
			clear: 'type'
		},
		{
			name: '/ppt/presentation.xml',
			type: 'application/vnd.openxmlformats-officedocument.presentationml.' + type_of_main_doc + '.main+xml',
			clear: 'type'
		},
		{
			name: '/ppt/slideLayouts/slideLayout1.xml',
			type: 'application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml',
			clear: 'type'
		},
		{
			name: '/ppt/tableStyles.xml',
			type: 'application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml',
			clear: 'type'
		},
		{
			name: '/ppt/viewProps.xml',
			type: 'application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml',
			clear: 'type'
		}
	);

	gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\presProps.xml', 'buffer', null, cbMakePptxPresProps, true );
	gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\tableStyles.xml', 'buffer', null, cbMakePptxStyles, true );
	gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\viewProps.xml', 'buffer', null, cbMakePptxViewProps, true );
	gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\presentation.xml', 'buffer', null, cbMakePptxPresentation, true );
	
	gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\slideLayouts\\slideLayout1.xml', 'buffer', null, cbMakePptxLayout, true );
	gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\slideLayouts\\_rels\\slideLayout1.xml.rels', 'buffer', [
		{
			type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster',
			target: '../slideMasters/slideMaster1.xml'
		}
	], gen_private.plugs.type.msoffice.cbMakeRels, true );

	gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\slideMasters\\slideMaster1.xml', 'buffer', null, cbMakePptxSlideMasters, true );
	gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\slideMasters\\_rels\\slideMaster1.xml.rels', 'buffer', [
		{
			type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout',
			target: '../slideLayouts/slideLayout1.xml'
		},
		{
			type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme',
			target: '../theme/theme1.xml'
		}
	], gen_private.plugs.type.msoffice.cbMakeRels, true );

	gen_private.plugs.intAddAnyResourceToParse ( 'docProps\\app.xml', 'buffer', null, cbMakePptxApp, true );

	gen_private.type.msoffice.rels_app.push (
		{
			type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster',
			target: 'slideMasters/slideMaster1.xml',
			clear: 'type'
		}
	);

	// Apple Keynote requires these added *after* all slides.
	genobj.on('beforeGen', function() {
		gen_private.type.msoffice.rels_app.push (
			{
				type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/presProps',
				target: 'presProps.xml',
				clear: 'type'
			},
			{
				type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/viewProps',
				target: 'viewProps.xml',
				clear: 'type'
			},
			{
				type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme',
				target: 'theme/theme1.xml',
				clear: 'type'
			},
			{
				type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles',
				target: 'tableStyles.xml',
				clear: 'type'
			}
		);
	});

	gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\_rels\\presentation.xml.rels', 'buffer', gen_private.type.msoffice.rels_app, gen_private.plugs.type.msoffice.cbMakeRels, true );

	// ----- API for PowerPoint documents: -----

	/**
	 * Create a new slide.
	 *
	 * This method creating a new slide inside the presentation.
	 *
	 * @return The new slide object.
	 */
	genobj.makeNewSlide = function () {
		var pageNumber = gen_private.pages.length;
		var slideObj = { show: true }; // The slide object that the user will use.

		gen_private.pages[pageNumber] = {};
		gen_private.pages[pageNumber].slide = slideObj;
		gen_private.pages[pageNumber].data = [];
		gen_private.pages[pageNumber].rels = [
			{
				type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout',
				target: '../slideLayouts/slideLayout1.xml',
				clear: 'data'
			}
		];

		gen_private.type.msoffice.files_list.push (
			{
				name: '/ppt/slides/slide' + (pageNumber + 1) + '.xml',
				type: 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml',
				clear: 'data'
			}
		);

		gen_private.type.msoffice.rels_app.push (
			{
				type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide',
				target: 'slides/slide' + (pageNumber + 1) + '.xml',
				clear: 'data'
			}
		);

		slideObj.getPageNumber = function () { return pageNumber; };

		slideObj.name = 'Slide ' + (pageNumber + 1);

		/**
		 * ???.
		 *
		 * @param {object} prgObj Paragraph object.
		 */
		function addParagraphApiForBasicOpt ( prgObj ) {
			if ( !prgObj.api ) {
				prgObj.api = {};
			} // Endif.

			prgObj.api.options = prgObj.options;
		}

		/**
		 * ???.
		 *
		 * @param {object} prgObj Paragraph object.
		 */
		function addParagraphApiForEffects ( prgObj ) {
			if ( !prgObj.api ) {
				prgObj.api = {};
			} // Endif.

			/**
			 * ???.
			 *
			 * @param {object} inType ???.
			 * @param {object} inAlign ???.
			 * @param {object} inColor ???.
			 * @param {object} inTransparency ???.
			 * @param {object} inSize ???.
			 * @param {object} inBlur ???.
			 * @param {object} inAngle ???.
			 * @param {object} inDistance ???.
			 */
			prgObj.api.setShadowEffect = function ( inType, inAlign, inColor, inTransparency, inSize, inBlur, inAngle, inDistance ) {
				if ( !prgObj.options.effects )
					prgObj.options.effects = [];

				var newEffect = {
					'type': inType,
					'align': inAlign,
					'color': inColor,
					'transparency': inTransparency,
					'size': inSize,
					'blur': inBlur,
					'angle': inAngle,
					'distance': inDistance
				};

				prgObj.options.effects.push ( newEffect );
			};
		}


    // added 2015-01-02 PSV as a way for user to modify chart properties before generating the XML string
    slideObj.createChart = function(chartInfo) {
      return new OfficeChart(chartInfo);
    };

    // added 2015-01-08 PSV following model of addChart
    slideObj.addTable = function(data, options) {
      var objNumber = gen_private.pages[pageNumber].data.length;

      gen_private.pages[pageNumber].data[objNumber] = {
        type: 'table',
        data: data,
        options: options || {} // right now this isn't yet used
      };

      addParagraphApiForBasicOpt ( gen_private.pages[pageNumber].data[objNumber] );
      addParagraphApiForEffects ( gen_private.pages[pageNumber].data[objNumber] );
      return gen_private.pages[pageNumber].data[objNumber].api;
    };

		/**
		 * Generate the chart based on input data.
		 *
		 * @param {object} renderType should belong to: 'column', 'pie'
		 * @param {object} data a JSON object with follow the following format
		 *     { 	
		 *			title: 'eSurvey chart',
		 *			data:  [
		 *				{
		 *					name: 'Income',
		 *					labels: ['2005', '2006', '2007', '2008', '2009'],
		 *					values: [23.5, 26.2, 30.1, 29.5, 24.6]
		 *				},
		 *				{
		 *					name: 'Expense',
		 *					labels: ['2005', '2006', '2007', '2008', '2009'],
		 *					values: [18.1, 22.8, 23.9, 25.1, 25]
		 *				}
		 *			]
		 * 	}
		 * @author vtloc
		 * @date 2014Jan09
		 */
		slideObj.addChart = function ( data, callback, errorCallback ) {

			var objNumber = gen_private.pages[pageNumber].data.length;
			GLOBAL_CHART_COUNT += 1;

			gen_private.pages[pageNumber].data[objNumber] = {};
			gen_private.pages[pageNumber].data[objNumber].type = 'chart';
			gen_private.pages[pageNumber].data[objNumber].renderType = 'column';
			gen_private.pages[pageNumber].data[objNumber].title = data['title'];
			gen_private.pages[pageNumber].data[objNumber].data = data['data'];
			gen_private.pages[pageNumber].data[objNumber].options = data;   // include generic options like x,y,cx,cy, etc.
			//data['renderType'] = renderType;

			// First, generate a temporatory excel file for storing the chart's data
			var workbook = excelbuilder.createWorkbook( genobj.options.tempDir, 'sample' + GLOBAL_CHART_COUNT + '.xlsx');

			// Create a new worksheet with 10 columns and 12 rows
			// number of columns: data['data'].length+1 -> equaly number of series
			// number of rows: data['data'][0].values.length+1
			var sheet1 = workbook.createSheet('Sheet1', data['data'].length+1, data['data'][0].values.length+1);
			var headerrow = 1;

			// write header using serie name
			for( var j=0; j < data['data'].length; j++ )
			{
				sheet1.set(j+2, headerrow, data['data'][j].name);
			}
			
			// write category column in the first column
			for( var j=0; j < data['data'][0].labels.length; j++ )
			{
				sheet1.set(1, j+2, data['data'][0].labels[j]);
			}
			
			// for each serie, write out values in its row
			for (var i = 0; i < data['data'].length; i++)
			{
				for( var j=0; j < data['data'][i].values.length; j++ )
				{
					// col i+2
					// row j+1
					sheet1.set(i+2, j+2, data['data'][i].values[j]);
				}
			}
			
			// Fill some data
			// Save it
			var localEmbeddingExcelFile = 'ppt\\embeddings\\Microsoft_Excel_Worksheet' + GLOBAL_CHART_COUNT + '.xlsx';
			var tmpExcelFile = genobj.options.tempDir + 'sample'+GLOBAL_CHART_COUNT+'.xlsx';
			// will copy the tmpExcelFile into localEmbeddingExcelFile
			gen_private.plugs.intAddAnyResourceToParse ( localEmbeddingExcelFile, 'file', tmpExcelFile, cbMakeChartDataExcel, false, true );
			gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\charts\\chart'+GLOBAL_CHART_COUNT+'.xml', 'buffer', data, cbMakeCharts, true );
			gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\charts\\_rels\\chart'+GLOBAL_CHART_COUNT+'.xml.rels', 'buffer', [
					{
						type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/package',
						target: '../embeddings/Microsoft_Excel_Worksheet'+GLOBAL_CHART_COUNT+'.xlsx'
					}
				], gen_private.plugs.type.msoffice.cbMakeRels, true );
			gen_private.type.msoffice.files_list.push (
				{
					name: '/ppt/charts/chart'+GLOBAL_CHART_COUNT+'.xml',
					type: 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml',
					clear: 'type'
				},
				{
					name: '/ppt/embeddings/Microsoft_Excel_Worksheet'+GLOBAL_CHART_COUNT+'.xlsx',
					type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
					ext: 'xlsx',
					clear: 'type'
				}
			);
			
			gen_private.pages[pageNumber].rels.push (
			{
				type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
				target: '../charts/chart'+GLOBAL_CHART_COUNT+'.xml',
				clear: 'data'
			});
			
			workbook.save(function(err){
				if (err) 
				{
				  workbook.cancel();
				}
				else
				{
					callback();
				}
			});
		}
		
		/**
		 * ???.
		 *
		 * @param {object} text ???.
		 * @param {object} opt ???.
		 * @param {object} y_pos ???.
		 * @param {object} x_size ???.
		 * @param {object} y_size ???.
		 * @param {object} opt_b ???.
		 */
		slideObj.addText = function ( text, opt, y_pos, x_size, y_size, opt_b ) {
			var objNumber = gen_private.pages[pageNumber].data.length;

			gen_private.pages[pageNumber].data[objNumber] = {};
			gen_private.pages[pageNumber].data[objNumber].type = 'text';
			gen_private.pages[pageNumber].data[objNumber].text = text;
			gen_private.pages[pageNumber].data[objNumber].options = typeof opt == 'object' ? opt : {};

			if ( typeof opt == 'string' ) {
				gen_private.pages[pageNumber].data[objNumber].options.color = opt;

			} else if ( (typeof opt != 'object') && (typeof y_pos != 'undefined') ) {
				gen_private.pages[pageNumber].data[objNumber].options.x = opt;
				gen_private.pages[pageNumber].data[objNumber].options.y = y_pos;

				if ( (typeof x_size != 'undefined') && (typeof y_size != 'undefined') ) {
					gen_private.pages[pageNumber].data[objNumber].options.cx = x_size;
					gen_private.pages[pageNumber].data[objNumber].options.cy = y_size;
				} // Endif.
			} // Endif.

			if ( typeof opt_b == 'object' ) {
				for ( var attrname in opt_b ) { gen_private.pages[pageNumber].data[objNumber].options[attrname] = opt_b[attrname]; }

			} else if ( (typeof x_size == 'object') && (typeof y_size == 'undefined') ) {
				for ( var attrname in x_size ) { gen_private.pages[pageNumber].data[objNumber].options[attrname] = x_size[attrname]; }
			} // Endif.

			addParagraphApiForBasicOpt ( gen_private.pages[pageNumber].data[objNumber] );
			addParagraphApiForEffects ( gen_private.pages[pageNumber].data[objNumber] );
			return gen_private.pages[pageNumber].data[objNumber].api;
		};

		/**
		 * ???
		 *
		 * @param {string} shape ???.
		 * @param {object} opt ???.
		 * @param {number} y_pos ???.
		 * @param {number} x_size ???.
		 * @param {number} y_size ???.
		 * @param {object} opt_b ???.
		 */
		slideObj.addShape = function ( shape, opt, y_pos, x_size, y_size, opt_b ) {
			var objNumber = gen_private.pages[pageNumber].data.length;

			gen_private.pages[pageNumber].data[objNumber] = {};
			gen_private.pages[pageNumber].data[objNumber].type = 'text';
			gen_private.pages[pageNumber].data[objNumber].options = typeof opt == 'object' ? opt : {};
			gen_private.pages[pageNumber].data[objNumber].options.shape = shape;

			if ( typeof opt == 'string' ) {
				gen_private.pages[pageNumber].data[objNumber].options.color = opt;

			} else if ( (typeof opt != 'object') && (typeof y_pos != 'undefined') ) {
				gen_private.pages[pageNumber].data[objNumber].options.x = opt;
				gen_private.pages[pageNumber].data[objNumber].options.y = y_pos;

				if ( (typeof x_size != 'undefined') && (typeof y_size != 'undefined') ) {
					gen_private.pages[pageNumber].data[objNumber].options.cx = x_size;
					gen_private.pages[pageNumber].data[objNumber].options.cy = y_size;
				} // Endif.
			} // Endif.

			if ( typeof opt_b == 'object' ) {
				for ( var attrname in opt_b ) { gen_private.pages[pageNumber].data[objNumber].options[attrname] = opt_b[attrname]; }

			} else if ( (typeof x_size == 'object') && (typeof y_size == 'undefined') ) {
				for ( var attrname in x_size ) { gen_private.pages[pageNumber].data[objNumber].options[attrname] = x_size[attrname]; }
			} // Endif.

			addParagraphApiForBasicOpt ( gen_private.pages[pageNumber].data[objNumber] );
			addParagraphApiForEffects ( gen_private.pages[pageNumber].data[objNumber] );
			return gen_private.pages[pageNumber].data[objNumber].api;
		};

		/**
		 * ???.
		 *
		 * @param {object} image_path ???.
		 * @param {object} opt ???.
		 * @param {object} y_pos ???.
		 * @param {object} x_size ???.
		 * @param {object} y_size ???.
		 * @param {object} image_format_type ???.
		 */
		slideObj.addImage = function ( image_path, opt, y_pos, x_size, y_size, image_format_type ) {
			var objNumber = gen_private.pages[pageNumber].data.length;
			var image_type = (typeof image_format_type == 'string') ? image_format_type : 'png';
			var defWidth, defHeight = 0;

			if ( typeof image_path == 'string' ) {
				var ret_data = fast_image_size ( image_path );
				if ( ret_data.type == 'unknown' ) {
					var image_ext = path.extname ( image_path );

					switch ( image_ext ) {
						case '.bmp':
							image_type = 'bmp';
							break;

						case '.gif':
							image_type = 'gif';
							break;

						case '.jpg':
						case '.jpeg':
							image_type = 'jpeg';
							break;

						case '.emf':
							image_type = 'emf';
							break;

						case '.tiff':
							image_type = 'tiff';
							break;
					} // End of switch.

				} else {
					if ( ret_data.width ) {
						defWidth = ret_data.width;
					} // Endif.

					if ( ret_data.height ) {
						defHeight = ret_data.height;
					} // Endif.

					image_type = ret_data.type;
					if ( image_type == 'jpg' ) {
						image_type = 'jpeg';
					} // Endif.
				} // Endif.
			} // Endif.

			gen_private.pages[pageNumber].data[objNumber] = {};
			gen_private.pages[pageNumber].data[objNumber].type = 'image';
			gen_private.pages[pageNumber].data[objNumber].image = image_path;
			gen_private.pages[pageNumber].data[objNumber].options = typeof opt == 'object' ? opt : {};

			if ( !gen_private.pages[pageNumber].data[objNumber].options.cx && defWidth ) {
				gen_private.pages[pageNumber].data[objNumber].options.cx = defWidth;
			} // Endif.

			if ( !gen_private.pages[pageNumber].data[objNumber].options.cy && defHeight ) {
				gen_private.pages[pageNumber].data[objNumber].options.cy = defHeight;
			} // Endif.

			var image_id = gen_private.type.msoffice.src_files_list.indexOf ( image_path );
			var image_rel_id = -1;

			if ( image_id >= 0 ) {
				for ( var j = 0, total_size_j = gen_private.pages[pageNumber].rels.length; j < total_size_j; j++ ) {
					if ( gen_private.pages[pageNumber].rels[j].target == ('../media/image' + (image_id + 1) + '.' + image_type) ) {
						image_rel_id = j + 1;
					} // Endif.
				} // Endif.
			
			} else
			{
				image_id = gen_private.type.msoffice.src_files_list.length;
				gen_private.type.msoffice.src_files_list[image_id] = image_path;
				gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\media\\image' + (image_id + 1) + '.' + image_type, (typeof image_path == 'string') ? 'file' : 'stream', image_path, null, false );
			} // Endif.

			if ( image_rel_id == -1 ) {
				image_rel_id = gen_private.pages[pageNumber].rels.length + 1;

				gen_private.pages[pageNumber].rels.push (
					{
						type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
						target: '../media/image' + (image_id + 1) + '.' + image_type,
						clear: 'data'
					}
				);
			} // Endif.

      //-- psv 2015-01-21 Manually copied change below from https://github.com/Ziv-Barber/officegen/pull/39/files?w=1
			if ((opt || {}).link) {
  				var link_rel_id = gen_private.pages[pageNumber].rels.length + 1;

      				gen_private.pages[pageNumber].rels.push (
          					{
              						type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
      						target: opt.link,
      						targetMode: 'External'
  					}
				);

    				gen_private.pages[pageNumber].data[objNumber].link_rel_id = link_rel_id;
			} // Endif.
      //-- psv 2015-01-21 end edits






			gen_private.pages[pageNumber].data[objNumber].image_id = image_id;
			gen_private.pages[pageNumber].data[objNumber].rel_id = image_rel_id;

			if ( typeof opt == 'string' ) {
				gen_private.pages[pageNumber].data[objNumber].options.color = opt;

			} else if ( (typeof opt != 'object') && (typeof y_pos != 'undefined') ) {
				gen_private.pages[pageNumber].data[objNumber].options.x = opt;
				gen_private.pages[pageNumber].data[objNumber].options.y = y_pos;

				if ( (typeof x_size != 'undefined') && (typeof y_size != 'undefined') ) {
					gen_private.pages[pageNumber].data[objNumber].options.cx = x_size;
					gen_private.pages[pageNumber].data[objNumber].options.cy = y_size;
				} // Endif.
			} // Endif.

			addParagraphApiForBasicOpt ( gen_private.pages[pageNumber].data[objNumber] );
			addParagraphApiForEffects ( gen_private.pages[pageNumber].data[objNumber] );
			return gen_private.pages[pageNumber].data[objNumber].api;
		};

		/**
		 * ???.
		 *
		 * @param {object} text ???.
		 * @param {object} opt ???.
		 * @param {object} y_pos ???.
		 * @param {object} x_size ???.
		 * @param {object} y_size ???.
		 * @param {object} opt_b ???.
		 */
		slideObj.addP = function ( text, opt, y_pos, x_size, y_size, opt_b ) {
			var objNumber = gen_private.pages[pageNumber].data.length;

			gen_private.pages[pageNumber].data[objNumber] = {};
			gen_private.pages[pageNumber].data[objNumber].type = 'p';
			gen_private.pages[pageNumber].data[objNumber].data = [];
			gen_private.pages[pageNumber].data[objNumber].options = typeof opt == 'object' ? opt : {};

			if ( typeof opt == 'string' ) {
				gen_private.pages[pageNumber].data[objNumber].options.color = opt;

			} else if ( (typeof opt != 'object') && (typeof y_pos != 'undefined') ) {
				gen_private.pages[pageNumber].data[objNumber].options.x = opt;
				gen_private.pages[pageNumber].data[objNumber].options.y = y_pos;

				if ( (typeof x_size != 'undefined') && (typeof y_size != 'undefined') ) {
					gen_private.pages[pageNumber].data[objNumber].options.cx = x_size;
					gen_private.pages[pageNumber].data[objNumber].options.cy = y_size;
				} // Endif.
			} // Endif.

			if ( typeof opt_b == 'object' ) {
				for ( var attrname in opt_b ) { gen_private.pages[pageNumber].data[objNumber].options[attrname] = opt_b[attrname]; }

			} else if ( (typeof x_size == 'object') && (typeof y_size == 'undefined') ) {
				for ( var attrname in x_size ) { gen_private.pages[pageNumber].data[objNumber].options[attrname] = x_size[attrname]; }
			} // Endif.

			// BMK_TODO:

			return gen_private.pages[pageNumber].data[objNumber].data;
		};

		slideObj.addDateToHeader = function () {
			if ( !gen_private.pages[pageNumber].header ) {
				gen_private.pages[pageNumber].header = {};
			} // Endif.

			// gen_private.pages[pageNumber]
			// <a:fld id="{5C7A2A3D-B97F-4EB0-B937-FE8C3AFCAC1A}" type="datetime1">
			// BMK_TODO:
		};

		gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\slides\\slide' + (pageNumber + 1) + '.xml', 'buffer', gen_private.pages[pageNumber], cbMakePptxSlide, false );
		gen_private.plugs.intAddAnyResourceToParse ( 'ppt\\slides\\_rels\\slide' + (pageNumber + 1) + '.xml.rels', 'buffer', gen_private.pages[pageNumber].rels, gen_private.plugs.type.msoffice.cbMakeRels, false );		
		return slideObj;
	};

	genobj.setWidescreen = function(wide){
		pptWidth 	= wide ? 12191996 		: 9144000;
		pptType 	= wide ? 'screen16x9' 	: 'screen4x3';
	}

	return this;
}

baseobj.plugins.registerDocType ( 'pptx', makePptx, {}, baseobj.docType.PRESENTATION, "Microsoft PowerPoint Document" );
baseobj.plugins.registerDocType ( 'ppsx', makePptx, {}, baseobj.docType.PRESENTATION, "Microsoft PowerPoint Slideshow Document" );