UNPKG

offices-viewer

Version:

## Current Renderable File Types

1,305 lines (1,278 loc) 60.2 kB
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } // @ts-nocheck import * as colz from 'colz/dist/colz.cjs'; // MIT https://github.com/g21589/PPTX2HTML var _order = 1; var themeContent = null; var styleTable = {}; var chartID = 0; var MsgQueue = new Array(); var titleFontSize = 42; var bodyFontSize = 20; var otherFontSize = 16; export function setThemeContent(data) { themeContent = data; } function tXml(S) { 'use strict'; var openBracket = '<'; var openBracketCC = '<'.charCodeAt(0); var closeBracket = '>'; var closeBracketCC = '>'.charCodeAt(0); var minus = '-'; var minusCC = '-'.charCodeAt(0); var slash = '/'; var slashCC = '/'.charCodeAt(0); var exclamation = '!'; var exclamationCC = '!'.charCodeAt(0); var singleQuote = "'"; var singleQuoteCC = "'".charCodeAt(0); var doubleQuote = '"'; var doubleQuoteCC = '"'.charCodeAt(0); var questionMark = '?'; var questionMarkCC = '?'.charCodeAt(0); /** * returns text until the first nonAlphebetic letter */ var nameSpacer = '\r\n\t>/= '; var pos = 0; /** * Parsing a list of entries */ function parseChildren() { var children = []; while (S[pos]) { if (S.charCodeAt(pos) == openBracketCC) { if (S.charCodeAt(pos + 1) === slashCC) { // </ //while (S[pos]!=='>') { pos++; } pos = S.indexOf(closeBracket, pos); return children; } else if (S.charCodeAt(pos + 1) === exclamationCC) { // <! or <!-- if (S.charCodeAt(pos + 2) == minusCC) { // comment support while (!(S.charCodeAt(pos) === closeBracketCC && S.charCodeAt(pos - 1) == minusCC && S.charCodeAt(pos - 2) == minusCC && pos != -1)) { pos = S.indexOf(closeBracket, pos + 1); } if (pos === -1) { pos = S.length; } } else { // doctype support pos += 2; for (; S.charCodeAt(pos) !== closeBracketCC; pos++) {} } pos++; continue; } else if (S.charCodeAt(pos + 1) === questionMarkCC) { // <? // XML header support pos = S.indexOf(closeBracket, pos); pos++; continue; } pos++; var startNamePos = pos; for (; nameSpacer.indexOf(S[pos]) === -1; pos++) {} var node_tagName = S.slice(startNamePos, pos); // Parsing attributes var attrFound = false; var node_attributes = {}; for (; S.charCodeAt(pos) !== closeBracketCC; pos++) { var c = S.charCodeAt(pos); if (c > 64 && c < 91 || c > 96 && c < 123) { startNamePos = pos; for (; nameSpacer.indexOf(S[pos]) === -1; pos++) {} var name = S.slice(startNamePos, pos); // search beginning of the string var code = S.charCodeAt(pos); while (code !== singleQuoteCC && code !== doubleQuoteCC) { pos++; code = S.charCodeAt(pos); } var startChar = S[pos]; var startStringPos = ++pos; pos = S.indexOf(startChar, startStringPos); var value = S.slice(startStringPos, pos); if (!attrFound) { node_attributes = {}; attrFound = true; } node_attributes[name] = value; } } // Optional parsing of children if (S.charCodeAt(pos - 1) !== slashCC) { pos++; var node_children = parseChildren(); } children.push({ children: node_children, tagName: node_tagName, attrs: node_attributes }); } else { var startTextPos = pos; pos = S.indexOf(openBracket, pos) - 1; // Skip characters until '<' if (pos === -2) { pos = S.length; } var text = S.slice(startTextPos, pos + 1); if (text.trim().length > 0) { children.push(text); } } pos++; } return children; } _order = 1; return simplefy(parseChildren()); } function simplefy(children) { var node = {}; if (children === undefined) { return {}; } // Text node (e.g. <t>This is text.</t>) if (children.length === 1 && typeof children[0] == 'string') { return children[0]; } // map each object children.forEach(function (child) { if (!node[child.tagName]) { node[child.tagName] = []; } if (_typeof(child) === 'object') { var kids = simplefy(child.children); if (_typeof(kids) === 'object') { if (child.attrs) { kids.attrs = child.attrs; } if (kids['attrs'] === undefined) { kids['attrs'] = { order: _order }; } else { kids['attrs']['order'] = _order; } } _order++; node[child.tagName].push(kids); } }); for (var i in node) { if (node[i].length == 1) { node[i] = node[i][0]; } } return node; } function indexNodes(content) { var keys = Object.keys(content); var spTreeNode = content[keys[0]]["p:cSld"]["p:spTree"]; var idTable = {}; var idxTable = {}; var typeTable = {}; for (var key in spTreeNode) { if (key == "p:nvGrpSpPr" || key == "p:grpSpPr") { continue; } var targetNode = spTreeNode[key]; if (targetNode.constructor === Array) { for (var i = 0; i < targetNode.length; i++) { var nvSpPrNode = targetNode[i]["p:nvSpPr"]; var id = getTextByPathList(nvSpPrNode, ["p:cNvPr", "attrs", "id"]); var idx = getTextByPathList(nvSpPrNode, ["p:nvPr", "p:ph", "attrs", "idx"]); var type = getTextByPathList(nvSpPrNode, ["p:nvPr", "p:ph", "attrs", "type"]); if (id !== undefined) { idTable[id] = targetNode[i]; } if (idx !== undefined) { idxTable[idx] = targetNode[i]; } if (type !== undefined) { typeTable[type] = targetNode[i]; } } } else { var nvSpPrNode = targetNode["p:nvSpPr"]; var id = getTextByPathList(nvSpPrNode, ["p:cNvPr", "attrs", "id"]); var idx = getTextByPathList(nvSpPrNode, ["p:nvPr", "p:ph", "attrs", "idx"]); var type = getTextByPathList(nvSpPrNode, ["p:nvPr", "p:ph", "attrs", "type"]); if (id !== undefined) { idTable[id] = targetNode; } if (idx !== undefined) { idxTable[idx] = targetNode; } if (type !== undefined) { typeTable[type] = targetNode; } } } return { "idTable": idTable, "idxTable": idxTable, "typeTable": typeTable }; } export function base64ArrayBuffer(arrayBuffer) { var base64 = ''; var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; var bytes = new Uint8Array(arrayBuffer); var byteLength = bytes.byteLength; var byteRemainder = byteLength % 3; var mainLength = byteLength - byteRemainder; var a, b, c, d; var chunk; for (var i = 0; i < mainLength; i = i + 3) { chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2]; a = (chunk & 16515072) >> 18; b = (chunk & 258048) >> 12; c = (chunk & 4032) >> 6; d = chunk & 63; base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]; } if (byteRemainder == 1) { chunk = bytes[mainLength]; a = (chunk & 252) >> 2; b = (chunk & 3) << 4; base64 += encodings[a] + encodings[b] + '=='; } else if (byteRemainder == 2) { chunk = bytes[mainLength] << 8 | bytes[mainLength + 1]; a = (chunk & 64512) >> 10; b = (chunk & 1008) >> 4; c = (chunk & 15) << 2; base64 += encodings[a] + encodings[b] + encodings[c] + '='; } return base64; } function readXmlFile(zip, filename) { return tXml(zip.file(filename).asText()); } export function getContentTypes(zip) { var ContentTypesJson = readXmlFile(zip, '[Content_Types].xml'); var subObj = ContentTypesJson['Types']['Override']; var slidesLocArray = []; var slideLayoutsLocArray = []; for (var i = 0; i < subObj.length; i++) { switch (subObj[i]['attrs']['ContentType']) { case 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml': slidesLocArray.push(subObj[i]['attrs']['PartName'].substr(1)); break; case 'application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml': slideLayoutsLocArray.push(subObj[i]['attrs']['PartName'].substr(1)); break; default: } } return { slides: slidesLocArray, slideLayouts: slideLayoutsLocArray }; } export function getSlideSize(zip) { if (!zip.files['ppt/presentation.xml']) { return { width: 960, height: 720 }; } // Pixel = EMUs * Resolution / 914400; (Resolution = 96) var content = readXmlFile(zip, 'ppt/presentation.xml'); var sldSzAttrs = content['p:presentation']['p:sldSz']['attrs']; return { width: parseInt(sldSzAttrs['cx']) * 96 / 914400, height: parseInt(sldSzAttrs['cy']) * 96 / 914400 }; } export function loadTheme(zip) { var preResContent = readXmlFile(zip, "ppt/_rels/presentation.xml.rels"); var relationshipArray = preResContent["Relationships"]["Relationship"]; var themeURI = undefined; if (relationshipArray.constructor === Array) { for (var i = 0; i < relationshipArray.length; i++) { if (relationshipArray[i]["attrs"]["Type"] === "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme") { themeURI = relationshipArray[i]["attrs"]["Target"]; break; } } } else if (relationshipArray["attrs"]["Type"] === "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme") { themeURI = relationshipArray["attrs"]["Target"]; } if (themeURI === undefined) { throw Error("Can't open theme file."); } return readXmlFile(zip, "ppt/" + themeURI); } export function processSingleSlide(zip, sldFileName, index, slideSize) { // self.postMessage({ // "type": "INFO", // "data": "Processing slide" + (index + 1) // }); // =====< Step 1 >===== // Read relationship filename of the slide (Get slideLayoutXX.xml) // @sldFileName: ppt/slides/slide1.xml // @resName: ppt/slides/_rels/slide1.xml.rels var resName = sldFileName.replace("slides/slide", "slides/_rels/slide") + ".rels"; var resContent = readXmlFile(zip, resName); var RelationshipArray = resContent["Relationships"]["Relationship"]; var layoutFilename = ""; var slideResObj = {}; if (RelationshipArray.constructor === Array) { for (var i = 0; i < RelationshipArray.length; i++) { switch (RelationshipArray[i]["attrs"]["Type"]) { case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout": layoutFilename = RelationshipArray[i]["attrs"]["Target"].replace("../", "ppt/"); break; case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide": case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image": case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart": case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink": default: slideResObj[RelationshipArray[i]["attrs"]["Id"]] = { "type": RelationshipArray[i]["attrs"]["Type"].replace("http://schemas.openxmlformats.org/officeDocument/2006/relationships/", ""), "target": RelationshipArray[i]["attrs"]["Target"].replace("../", "ppt/") }; } } } else { layoutFilename = RelationshipArray["attrs"]["Target"].replace("../", "ppt/"); } // Open slideLayoutXX.xml var slideLayoutContent = readXmlFile(zip, layoutFilename); var slideLayoutTables = indexNodes(slideLayoutContent); // =====< Step 2 >===== // Read slide master filename of the slidelayout (Get slideMasterXX.xml) // @resName: ppt/slideLayouts/slideLayout1.xml // @masterName: ppt/slideLayouts/_rels/slideLayout1.xml.rels var slideLayoutResFilename = layoutFilename.replace("slideLayouts/slideLayout", "slideLayouts/_rels/slideLayout") + ".rels"; var slideLayoutResContent = readXmlFile(zip, slideLayoutResFilename); RelationshipArray = slideLayoutResContent["Relationships"]["Relationship"]; var masterFilename = ""; if (RelationshipArray.constructor === Array) { for (var i = 0; i < RelationshipArray.length; i++) { switch (RelationshipArray[i]["attrs"]["Type"]) { case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster": masterFilename = RelationshipArray[i]["attrs"]["Target"].replace("../", "ppt/"); break; default: } } } else { masterFilename = RelationshipArray["attrs"]["Target"].replace("../", "ppt/"); } // Open slideMasterXX.xml var slideMasterContent = readXmlFile(zip, masterFilename); var slideMasterTextStyles = getTextByPathList(slideMasterContent, ["p:sldMaster", "p:txStyles"]); var slideMasterTables = indexNodes(slideMasterContent); // =====< Step 3 >===== var slideContent = readXmlFile(zip, sldFileName); var nodes = slideContent["p:sld"]["p:cSld"]["p:spTree"]; var warpObj = { "zip": zip, "slideLayoutTables": slideLayoutTables, "slideMasterTables": slideMasterTables, "slideResObj": slideResObj, "slideMasterTextStyles": slideMasterTextStyles }; var bgColor = getSlideBackgroundFill(slideContent, slideLayoutContent, slideMasterContent); var result = "<section style='width:" + slideSize.width + "px; height:" + slideSize.height + "px; background-color: #" + bgColor + "'>"; for (var nodeKey in nodes) { if (nodes[nodeKey].constructor === Array) { for (var i = 0; i < nodes[nodeKey].length; i++) { result += processNodesInSlide(nodeKey, nodes[nodeKey][i], warpObj); } } else { result += processNodesInSlide(nodeKey, nodes[nodeKey], warpObj); } } return result + "</section>"; } function getTextByPathList(node, path) { if (path.constructor !== Array) { throw Error("Error of path type! path is not array."); } if (node === undefined) { return undefined; } var l = path.length; for (var i = 0; i < l; i++) { node = node[path[i]]; if (node === undefined) { return undefined; } } return node; } function getSolidFill(solidFill) { if (solidFill === undefined) { return undefined; } var color = "FFF"; if (solidFill["a:srgbClr"] !== undefined) { color = getTextByPathList(solidFill["a:srgbClr"], ["attrs", "val"]); } else if (solidFill["a:schemeClr"] !== undefined) { var schemeClr = "a:" + getTextByPathList(solidFill["a:schemeClr"], ["attrs", "val"]); color = getSchemeColorFromTheme(schemeClr); } return color; } function processNodesInSlide(nodeKey, nodeValue, warpObj) { var result = ""; switch (nodeKey) { case "p:sp": // Shape, Text result = processSpNode(nodeValue, warpObj); break; case "p:cxnSp": // Shape, Text (with connection) result = processCxnSpNode(nodeValue, warpObj); break; case "p:pic": // Picture result = processPicNode(nodeValue, warpObj); break; case "p:graphicFrame": // Chart, Diagram, Table result = processGraphicFrameNode(nodeValue, warpObj); break; case "p:grpSp": // 群組 result = processGroupSpNode(nodeValue, warpObj); break; default: } return result; } function processSpNode(node, warpObj) { /* * 958 <xsd:complexType name="CT_GvmlShape"> * 959 <xsd:sequence> * 960 <xsd:element name="nvSpPr" type="CT_GvmlShapeNonVisual" minOccurs="1" maxOccurs="1"/> * 961 <xsd:element name="spPr" type="CT_ShapeProperties" minOccurs="1" maxOccurs="1"/> * 962 <xsd:element name="txSp" type="CT_GvmlTextShape" minOccurs="0" maxOccurs="1"/> * 963 <xsd:element name="style" type="CT_ShapeStyle" minOccurs="0" maxOccurs="1"/> * 964 <xsd:element name="extLst" type="CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/> * 965 </xsd:sequence> * 966 </xsd:complexType> */ var id = node["p:nvSpPr"]["p:cNvPr"]["attrs"]["id"]; var name = node["p:nvSpPr"]["p:cNvPr"]["attrs"]["name"]; var idx = node["p:nvSpPr"]["p:nvPr"]["p:ph"] === undefined ? undefined : node["p:nvSpPr"]["p:nvPr"]["p:ph"]["attrs"]["idx"]; var type = node["p:nvSpPr"]["p:nvPr"]["p:ph"] === undefined ? undefined : node["p:nvSpPr"]["p:nvPr"]["p:ph"]["attrs"]["type"]; var order = node["attrs"]["order"]; var slideLayoutSpNode = undefined; var slideMasterSpNode = undefined; if (type !== undefined) { if (idx !== undefined) { slideLayoutSpNode = warpObj["slideLayoutTables"]["typeTable"][type]; slideMasterSpNode = warpObj["slideMasterTables"]["typeTable"][type]; } else { slideLayoutSpNode = warpObj["slideLayoutTables"]["typeTable"][type]; slideMasterSpNode = warpObj["slideMasterTables"]["typeTable"][type]; } } else { if (idx !== undefined) { slideLayoutSpNode = warpObj["slideLayoutTables"]["idxTable"][idx]; slideMasterSpNode = warpObj["slideMasterTables"]["idxTable"][idx]; } else { // Nothing } } if (type === undefined) { type = getTextByPathList(slideLayoutSpNode, ["p:nvSpPr", "p:nvPr", "p:ph", "attrs", "type"]); if (type === undefined) { type = getTextByPathList(slideMasterSpNode, ["p:nvSpPr", "p:nvPr", "p:ph", "attrs", "type"]); } } return genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, type, order, warpObj); } function processCxnSpNode(node, warpObj) { var id = node["p:nvCxnSpPr"]["p:cNvPr"]["attrs"]["id"]; var name = node["p:nvCxnSpPr"]["p:cNvPr"]["attrs"]["name"]; //var idx = (node["p:nvCxnSpPr"]["p:nvPr"]["p:ph"] === undefined) ? undefined : node["p:nvSpPr"]["p:nvPr"]["p:ph"]["attrs"]["idx"]; //var type = (node["p:nvCxnSpPr"]["p:nvPr"]["p:ph"] === undefined) ? undefined : node["p:nvSpPr"]["p:nvPr"]["p:ph"]["attrs"]["type"]; //<p:cNvCxnSpPr>(<p:cNvCxnSpPr>, <a:endCxn>) var order = node["attrs"]["order"]; return genShape(node, undefined, undefined, id, name, undefined, undefined, order, warpObj); } function genShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, type, order, warpObj) { var xfrmList = ["p:spPr", "a:xfrm"]; var slideXfrmNode = getTextByPathList(node, xfrmList); var slideLayoutXfrmNode = getTextByPathList(slideLayoutSpNode, xfrmList); var slideMasterXfrmNode = getTextByPathList(slideMasterSpNode, xfrmList); var result = ""; var shapType = getTextByPathList(node, ["p:spPr", "a:prstGeom", "attrs", "prst"]); var isFlipV = false; if (getTextByPathList(slideXfrmNode, ["attrs", "flipV"]) === "1" || getTextByPathList(slideXfrmNode, ["attrs", "flipH"]) === "1") { isFlipV = true; } if (shapType !== undefined) { var off = getTextByPathList(slideXfrmNode, ["a:off", "attrs"]); var x = parseInt(off["x"]) * 96 / 914400; var y = parseInt(off["y"]) * 96 / 914400; var ext = getTextByPathList(slideXfrmNode, ["a:ext", "attrs"]); var w = parseInt(ext["cx"]) * 96 / 914400; var h = parseInt(ext["cy"]) * 96 / 914400; result += "<svg class='drawing' _id='" + id + "' _idx='" + idx + "' _type='" + type + "' _name='" + name + "' style='" + getPosition(slideXfrmNode, undefined, undefined) + getSize(slideXfrmNode, undefined, undefined) + " z-index: " + order + ";" + "'>"; // Fill Color var fillColor = getShapeFill(node, true); // Border Color var border = getBorder(node, true); var headEndNodeAttrs = getTextByPathList(node, ["p:spPr", "a:ln", "a:headEnd", "attrs"]); var tailEndNodeAttrs = getTextByPathList(node, ["p:spPr", "a:ln", "a:tailEnd", "attrs"]); // type: none, triangle, stealth, diamond, oval, arrow if (headEndNodeAttrs !== undefined && (headEndNodeAttrs["type"] === "triangle" || headEndNodeAttrs["type"] === "arrow") || tailEndNodeAttrs !== undefined && (tailEndNodeAttrs["type"] === "triangle" || tailEndNodeAttrs["type"] === "arrow")) { var triangleMarker = "<defs><marker id=\"markerTriangle\" viewBox=\"0 0 10 10\" refX=\"1\" refY=\"5\" markerWidth=\"5\" markerHeight=\"5\" orient=\"auto-start-reverse\" markerUnits=\"strokeWidth\"><path d=\"M 0 0 L 10 5 L 0 10 z\" /></marker></defs>"; result += triangleMarker; } switch (shapType) { case "accentBorderCallout1": case "accentBorderCallout2": case "accentBorderCallout3": case "accentCallout1": case "accentCallout2": case "accentCallout3": case "actionButtonBackPrevious": case "actionButtonBeginning": case "actionButtonBlank": case "actionButtonDocument": case "actionButtonEnd": case "actionButtonForwardNext": case "actionButtonHelp": case "actionButtonHome": case "actionButtonInformation": case "actionButtonMovie": case "actionButtonReturn": case "actionButtonSound": case "arc": case "bevel": case "blockArc": case "borderCallout1": case "borderCallout2": case "borderCallout3": case "bracePair": case "bracketPair": case "callout1": case "callout2": case "callout3": case "can": case "chartPlus": case "chartStar": case "chartX": case "chevron": case "chord": case "cloud": case "cloudCallout": case "corner": case "cornerTabs": case "cube": case "decagon": case "diagStripe": case "diamond": case "dodecagon": case "donut": case "doubleWave": case "downArrowCallout": case "ellipseRibbon": case "ellipseRibbon2": case "flowChartAlternateProcess": case "flowChartCollate": case "flowChartConnector": case "flowChartDecision": case "flowChartDelay": case "flowChartDisplay": case "flowChartDocument": case "flowChartExtract": case "flowChartInputOutput": case "flowChartInternalStorage": case "flowChartMagneticDisk": case "flowChartMagneticDrum": case "flowChartMagneticTape": case "flowChartManualInput": case "flowChartManualOperation": case "flowChartMerge": case "flowChartMultidocument": case "flowChartOfflineStorage": case "flowChartOffpageConnector": case "flowChartOnlineStorage": case "flowChartOr": case "flowChartPredefinedProcess": case "flowChartPreparation": case "flowChartProcess": case "flowChartPunchedCard": case "flowChartPunchedTape": case "flowChartSort": case "flowChartSummingJunction": case "flowChartTerminator": case "folderCorner": case "frame": case "funnel": case "gear6": case "gear9": case "halfFrame": case "heart": case "heptagon": case "hexagon": case "homePlate": case "horizontalScroll": case "irregularSeal1": case "irregularSeal2": case "leftArrow": case "leftArrowCallout": case "leftBrace": case "leftBracket": case "leftRightArrowCallout": case "leftRightRibbon": case "irregularSeal1": case "lightningBolt": case "lineInv": case "mathDivide": case "mathEqual": case "mathMinus": case "mathMultiply": case "mathNotEqual": case "mathPlus": case "moon": case "nonIsoscelesTrapezoid": case "noSmoking": case "octagon": case "parallelogram": case "pentagon": case "pie": case "pieWedge": case "plaque": case "plaqueTabs": case "plus": case "quadArrowCallout": case "rect": case "ribbon": case "ribbon2": case "rightArrowCallout": case "rightBrace": case "rightBracket": case "round1Rect": case "round2DiagRect": case "round2SameRect": case "rtTriangle": case "smileyFace": case "snip1Rect": case "snip2DiagRect": case "snip2SameRect": case "snipRoundRect": case "squareTabs": case "star10": case "star12": case "star16": case "star24": case "star32": case "star4": case "star5": case "star6": case "star7": case "star8": case "sun": case "teardrop": case "trapezoid": case "upArrowCallout": case "upDownArrowCallout": case "verticalScroll": case "wave": case "wedgeEllipseCallout": case "wedgeRectCallout": case "wedgeRoundRectCallout": case "rect": result += "<rect x='0' y='0' width='" + w + "' height='" + h + "' fill='" + fillColor + "' stroke='" + border.color + "' stroke-width='" + border.width + "' stroke-dasharray='" + border.strokeDasharray + "' />"; break; case "ellipse": result += "<ellipse cx='" + w / 2 + "' cy='" + h / 2 + "' rx='" + w / 2 + "' ry='" + h / 2 + "' fill='" + fillColor + "' stroke='" + border.color + "' stroke-width='" + border.width + "' stroke-dasharray='" + border.strokeDasharray + "' />"; break; case "roundRect": result += "<rect x='0' y='0' width='" + w + "' height='" + h + "' rx='7' ry='7' fill='" + fillColor + "' stroke='" + border.color + "' stroke-width='" + border.width + "' stroke-dasharray='" + border.strokeDasharray + "' />"; break; case "bentConnector2": // 直角 (path) var d = ""; if (isFlipV) { d = "M 0 " + w + " L " + h + " " + w + " L " + h + " 0"; } else { d = "M " + w + " 0 L " + w + " " + h + " L 0 " + h; } result += "<path d='" + d + "' stroke='" + border.color + "' stroke-width='" + border.width + "' stroke-dasharray='" + border.strokeDasharray + "' fill='none' "; if (headEndNodeAttrs !== undefined && (headEndNodeAttrs["type"] === "triangle" || headEndNodeAttrs["type"] === "arrow")) { result += "marker-start='url(#markerTriangle)' "; } if (tailEndNodeAttrs !== undefined && (tailEndNodeAttrs["type"] === "triangle" || tailEndNodeAttrs["type"] === "arrow")) { result += "marker-end='url(#markerTriangle)' "; } result += "/>"; break; case "line": case "straightConnector1": case "bentConnector3": case "bentConnector4": case "bentConnector5": case "curvedConnector2": case "curvedConnector3": case "curvedConnector4": case "curvedConnector5": if (isFlipV) { result += "<line x1='" + w + "' y1='0' x2='0' y2='" + h + "' stroke='" + border.color + "' stroke-width='" + border.width + "' stroke-dasharray='" + border.strokeDasharray + "' "; } else { result += "<line x1='0' y1='0' x2='" + w + "' y2='" + h + "' stroke='" + border.color + "' stroke-width='" + border.width + "' stroke-dasharray='" + border.strokeDasharray + "' "; } if (headEndNodeAttrs !== undefined && (headEndNodeAttrs["type"] === "triangle" || headEndNodeAttrs["type"] === "arrow")) { result += "marker-start='url(#markerTriangle)' "; } if (tailEndNodeAttrs !== undefined && (tailEndNodeAttrs["type"] === "triangle" || tailEndNodeAttrs["type"] === "arrow")) { result += "marker-end='url(#markerTriangle)' "; } result += "/>"; break; case "rightArrow": result += "<defs><marker id=\"markerTriangle\" viewBox=\"0 0 10 10\" refX=\"1\" refY=\"5\" markerWidth=\"2.5\" markerHeight=\"2.5\" orient=\"auto-start-reverse\" markerUnits=\"strokeWidth\"><path d=\"M 0 0 L 10 5 L 0 10 z\" /></marker></defs>"; result += "<line x1='0' y1='" + h / 2 + "' x2='" + (w - 15) + "' y2='" + h / 2 + "' stroke='" + border.color + "' stroke-width='" + h / 2 + "' stroke-dasharray='" + border.strokeDasharray + "' "; result += "marker-end='url(#markerTriangle)' />"; break; case "downArrow": result += "<defs><marker id=\"markerTriangle\" viewBox=\"0 0 10 10\" refX=\"1\" refY=\"5\" markerWidth=\"2.5\" markerHeight=\"2.5\" orient=\"auto-start-reverse\" markerUnits=\"strokeWidth\"><path d=\"M 0 0 L 10 5 L 0 10 z\" /></marker></defs>"; result += "<line x1='" + w / 2 + "' y1='0' x2='" + w / 2 + "' y2='" + (h - 15) + "' stroke='" + border.color + "' stroke-width='" + w / 2 + "' stroke-dasharray='" + border.strokeDasharray + "' "; result += "marker-end='url(#markerTriangle)' />"; break; case "bentArrow": case "bentUpArrow": case "stripedRightArrow": case "quadArrow": case "circularArrow": case "swooshArrow": case "leftRightArrow": case "leftRightUpArrow": case "leftUpArrow": case "leftCircularArrow": case "notchedRightArrow": case "curvedDownArrow": case "curvedLeftArrow": case "curvedRightArrow": case "curvedUpArrow": case "upDownArrow": case "upArrow": case "uturnArrow": case "leftRightCircularArrow": break; case "triangle": break; case undefined: default: console.warn("Undefine shape type."); } result += "</svg>"; result += "<div class='block content " + getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode, type) + "' _id='" + id + "' _idx='" + idx + "' _type='" + type + "' _name='" + name + "' style='" + getPosition(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode) + getSize(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode) + " z-index: " + order + ";" + "'>"; // TextBody if (node["p:txBody"] !== undefined) { result += genTextBody(node["p:txBody"], slideLayoutSpNode, slideMasterSpNode, type, warpObj); } result += "</div>"; } else { result += "<div class='block content " + getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode, type) + "' _id='" + id + "' _idx='" + idx + "' _type='" + type + "' _name='" + name + "' style='" + getPosition(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode) + getSize(slideXfrmNode, slideLayoutXfrmNode, slideMasterXfrmNode) + getBorder(node, false) + getShapeFill(node, false) + " z-index: " + order + ";" + "'>"; // TextBody if (node["p:txBody"] !== undefined) { result += genTextBody(node["p:txBody"], slideLayoutSpNode, slideMasterSpNode, type, warpObj); } result += "</div>"; } return result; } function getPosition(slideSpNode, slideLayoutSpNode, slideMasterSpNode) { var off = undefined; var x = -1, y = -1; if (slideSpNode !== undefined) { off = slideSpNode["a:off"]["attrs"]; } else if (slideLayoutSpNode !== undefined) { off = slideLayoutSpNode["a:off"]["attrs"]; } else if (slideMasterSpNode !== undefined) { off = slideMasterSpNode["a:off"]["attrs"]; } if (off === undefined) { return ""; } else { x = parseInt(off["x"]) * 96 / 914400; y = parseInt(off["y"]) * 96 / 914400; return isNaN(x) || isNaN(y) ? "" : "top:" + y + "px; left:" + x + "px;"; } } function getSize(slideSpNode, slideLayoutSpNode, slideMasterSpNode) { var ext = undefined; var w = -1, h = -1; if (slideSpNode !== undefined) { ext = slideSpNode["a:ext"]["attrs"]; } else if (slideLayoutSpNode !== undefined) { ext = slideLayoutSpNode["a:ext"]["attrs"]; } else if (slideMasterSpNode !== undefined) { ext = slideMasterSpNode["a:ext"]["attrs"]; } if (ext === undefined) { return ""; } else { w = parseInt(ext["cx"]) * 96 / 914400; h = parseInt(ext["cy"]) * 96 / 914400; return isNaN(w) || isNaN(h) ? "" : "width:" + w + "px; height:" + h + "px;"; } } function getHorizontalAlign(node, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles) { var algn = getTextByPathList(node, ["a:pPr", "attrs", "algn"]); if (algn === undefined) { algn = getTextByPathList(slideLayoutSpNode, ["p:txBody", "a:p", "a:pPr", "attrs", "algn"]); if (algn === undefined) { algn = getTextByPathList(slideMasterSpNode, ["p:txBody", "a:p", "a:pPr", "attrs", "algn"]); if (algn === undefined) { switch (type) { case "title": case "subTitle": case "ctrTitle": algn = getTextByPathList(slideMasterTextStyles, ["p:titleStyle", "a:lvl1pPr", "attrs", "alng"]); break; default: algn = getTextByPathList(slideMasterTextStyles, ["p:otherStyle", "a:lvl1pPr", "attrs", "alng"]); } } } } // TODO: if (algn === undefined) { if (type == "title" || type == "subTitle" || type == "ctrTitle") { return "h-mid"; } else if (type == "sldNum") { return "h-right"; } } return algn === "ctr" ? "h-mid" : algn === "r" ? "h-right" : "h-left"; } function getVerticalAlign(node, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles) { // 上中下對齊: X, <a:bodyPr anchor="ctr">, <a:bodyPr anchor="b"> var anchor = getTextByPathList(node, ["p:txBody", "a:bodyPr", "attrs", "anchor"]); if (anchor === undefined) { anchor = getTextByPathList(slideLayoutSpNode, ["p:txBody", "a:bodyPr", "attrs", "anchor"]); if (anchor === undefined) { anchor = getTextByPathList(slideMasterSpNode, ["p:txBody", "a:bodyPr", "attrs", "anchor"]); } } return anchor === "ctr" ? "v-mid" : anchor === "b" ? "v-down" : "v-up"; } function getFontType(node, type, slideMasterTextStyles) { var typeface = getTextByPathList(node, ["a:rPr", "a:latin", "attrs", "typeface"]); if (typeface === undefined) { var fontSchemeNode = getTextByPathList(themeContent, ["a:theme", "a:themeElements", "a:fontScheme"]); if (type == "title" || type == "subTitle" || type == "ctrTitle") { typeface = getTextByPathList(fontSchemeNode, ["a:majorFont", "a:latin", "attrs", "typeface"]); } else if (type == "body") { typeface = getTextByPathList(fontSchemeNode, ["a:minorFont", "a:latin", "attrs", "typeface"]); } else { typeface = getTextByPathList(fontSchemeNode, ["a:minorFont", "a:latin", "attrs", "typeface"]); } } return typeface === undefined ? "inherit" : typeface; } function getFontColor(node, type, slideMasterTextStyles) { var color = getTextByPathStr(node, "a:rPr a:solidFill a:srgbClr attrs val"); return color === undefined ? "#000" : "#" + color; } function getFontSize(node, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles) { var fontSize = undefined; if (node["a:rPr"] !== undefined) { fontSize = parseInt(node["a:rPr"]["attrs"]["sz"]) / 100; } if (isNaN(fontSize) || fontSize === undefined) { var sz = getTextByPathList(slideLayoutSpNode, ["p:txBody", "a:lstStyle", "a:lvl1pPr", "a:defRPr", "attrs", "sz"]); fontSize = parseInt(sz) / 100; } if (isNaN(fontSize) || fontSize === undefined) { if (type == "title" || type == "subTitle" || type == "ctrTitle") { var sz = getTextByPathList(slideMasterTextStyles, ["p:titleStyle", "a:lvl1pPr", "a:defRPr", "attrs", "sz"]); } else if (type == "body") { var sz = getTextByPathList(slideMasterTextStyles, ["p:bodyStyle", "a:lvl1pPr", "a:defRPr", "attrs", "sz"]); } else if (type == "dt" || type == "sldNum") { var sz = "1200"; } else if (type === undefined) { var sz = getTextByPathList(slideMasterTextStyles, ["p:otherStyle", "a:lvl1pPr", "a:defRPr", "attrs", "sz"]); } fontSize = parseInt(sz) / 100; } var baseline = getTextByPathList(node, ["a:rPr", "attrs", "baseline"]); if (baseline !== undefined && !isNaN(fontSize)) { fontSize -= 10; } return isNaN(fontSize) ? "inherit" : fontSize + "pt"; } function getFontBold(node, type, slideMasterTextStyles) { return node["a:rPr"] !== undefined && node["a:rPr"]["attrs"]["b"] === "1" ? "bold" : "initial"; } function getFontItalic(node, type, slideMasterTextStyles) { return node["a:rPr"] !== undefined && node["a:rPr"]["attrs"]["i"] === "1" ? "italic" : "normal"; } function getFontDecoration(node, type, slideMasterTextStyles) { return node["a:rPr"] !== undefined && node["a:rPr"]["attrs"]["u"] === "sng" ? "underline" : "initial"; } function getTextVerticalAlign(node, type, slideMasterTextStyles) { var baseline = getTextByPathList(node, ["a:rPr", "attrs", "baseline"]); return baseline === undefined ? "baseline" : parseInt(baseline) / 1000 + "%"; } function getBorder(node, isSvgMode) { var cssText = "border: "; // 1. presentationML var lineNode = node["p:spPr"]["a:ln"]; // Border width: 1pt = 12700, default = 0.75pt var borderWidth = parseInt(getTextByPathList(lineNode, ["attrs", "w"])) / 12700; if (isNaN(borderWidth) || borderWidth < 1) { cssText += "1pt "; } else { cssText += borderWidth + "pt "; } // Border color var borderColor = getTextByPathList(lineNode, ["a:solidFill", "a:srgbClr", "attrs", "val"]); if (borderColor === undefined) { var schemeClrNode = getTextByPathList(lineNode, ["a:solidFill", "a:schemeClr"]); var schemeClr = "a:" + getTextByPathList(schemeClrNode, ["attrs", "val"]); var borderColor = getSchemeColorFromTheme(schemeClr); } // 2. drawingML namespace if (borderColor === undefined) { var schemeClrNode = getTextByPathList(node, ["p:style", "a:lnRef", "a:schemeClr"]); var schemeClr = "a:" + getTextByPathList(schemeClrNode, ["attrs", "val"]); var borderColor = getSchemeColorFromTheme(schemeClr); if (borderColor !== undefined) { var shade = getTextByPathList(schemeClrNode, ["a:shade", "attrs", "val"]); if (shade !== undefined) { shade = parseInt(shade) / 100000; var color = new colz.Color("#" + borderColor); color.setLum(color.hsl.l * shade); borderColor = color.hex.replace("#", ""); } } } if (borderColor === undefined) { if (isSvgMode) { borderColor = "none"; } else { borderColor = "#000"; } } else { borderColor = "#" + borderColor; } cssText += " " + borderColor + " "; // Border type var borderType = getTextByPathList(lineNode, ["a:prstDash", "attrs", "val"]); var strokeDasharray = "0"; switch (borderType) { case "solid": cssText += "solid"; strokeDasharray = "0"; break; case "dash": cssText += "dashed"; strokeDasharray = "5"; break; case "dashDot": cssText += "dashed"; strokeDasharray = "5, 5, 1, 5"; break; case "dot": cssText += "dotted"; strokeDasharray = "1, 5"; break; case "lgDash": cssText += "dashed"; strokeDasharray = "10, 5"; break; case "lgDashDotDot": cssText += "dashed"; strokeDasharray = "10, 5, 1, 5, 1, 5"; break; case "sysDash": cssText += "dashed"; strokeDasharray = "5, 2"; break; case "sysDashDot": cssText += "dashed"; strokeDasharray = "5, 2, 1, 5"; break; case "sysDashDotDot": cssText += "dashed"; strokeDasharray = "5, 2, 1, 5, 1, 5"; break; case "sysDot": cssText += "dotted"; strokeDasharray = "2, 5"; break; case undefined: //console.log(borderType); default: //console.warn(borderType); //cssText += "#000 solid"; } if (isSvgMode) { return { "color": borderColor, "width": borderWidth, "type": borderType, "strokeDasharray": strokeDasharray }; } else { return cssText + ";"; } } function getSlideBackgroundFill(slideContent, slideLayoutContent, slideMasterContent) { var bgColor = getSolidFill(getTextByPathList(slideContent, ["p:sld", "p:cSld", "p:bg", "p:bgPr", "a:solidFill"])); if (bgColor === undefined) { bgColor = getSolidFill(getTextByPathList(slideLayoutContent, ["p:sldLayout", "p:cSld", "p:bg", "p:bgPr", "a:solidFill"])); if (bgColor === undefined) { bgColor = getSolidFill(getTextByPathList(slideMasterContent, ["p:sldMaster", "p:cSld", "p:bg", "p:bgPr", "a:solidFill"])); if (bgColor === undefined) { bgColor = "FFF"; } } } return bgColor; } function getSchemeColorFromTheme(schemeClr) { // TODO: <p:clrMap ...> in slide master // e.g. tx2="dk2" bg2="lt2" tx1="dk1" bg1="lt1" switch (schemeClr) { case "a:tx1": schemeClr = "a:dk1"; break; case "a:tx2": schemeClr = "a:dk2"; break; case "a:bg1": schemeClr = "a:lt1"; break; case "a:bg2": schemeClr = "a:lt2"; break; } var refNode = getTextByPathList(themeContent, ["a:theme", "a:themeElements", "a:clrScheme", schemeClr]); var color = getTextByPathList(refNode, ["a:srgbClr", "attrs", "val"]); if (color === undefined) { color = getTextByPathList(refNode, ["a:sysClr", "attrs", "lastClr"]); } return color; } function getShapeFill(node, isSvgMode) { // 1. presentationML // p:spPr [a:noFill, solidFill, gradFill, blipFill, pattFill, grpFill] // From slide if (getTextByPathList(node, ["p:spPr", "a:noFill"]) !== undefined) { return isSvgMode ? "none" : "background-color: initial;"; } var fillColor = undefined; if (fillColor === undefined) { fillColor = getTextByPathList(node, ["p:spPr", "a:solidFill", "a:srgbClr", "attrs", "val"]); } // From theme if (fillColor === undefined) { var schemeClr = "a:" + getTextByPathList(node, ["p:spPr", "a:solidFill", "a:schemeClr", "attrs", "val"]); fillColor = getSchemeColorFromTheme(schemeClr); } // 2. drawingML namespace if (fillColor === undefined) { var schemeClr = "a:" + getTextByPathList(node, ["p:style", "a:fillRef", "a:schemeClr", "attrs", "val"]); fillColor = getSchemeColorFromTheme(schemeClr); } if (fillColor !== undefined) { fillColor = "#" + fillColor; // Apply shade or tint // TODO: 較淺, 較深 80% var lumMod = parseInt(getTextByPathList(node, ["p:spPr", "a:solidFill", "a:schemeClr", "a:lumMod", "attrs", "val"])) / 100000; var lumOff = parseInt(getTextByPathList(node, ["p:spPr", "a:solidFill", "a:schemeClr", "a:lumOff", "attrs", "val"])) / 100000; if (isNaN(lumMod)) { lumMod = 1.0; } if (isNaN(lumOff)) { lumOff = 0; } //console.log([lumMod, lumOff]); fillColor = applyLumModify(fillColor, lumMod, lumOff); if (isSvgMode) { return fillColor; } else { return "background-color: " + fillColor + ";"; } } else { if (isSvgMode) { return "none"; } else { return "background-color: " + fillColor + ";"; } } } function genTextBody(textBodyNode, slideLayoutSpNode, slideMasterSpNode, type, warpObj) { var text = ""; var slideMasterTextStyles = warpObj["slideMasterTextStyles"]; if (textBodyNode === undefined) { return text; } if (textBodyNode["a:p"].constructor === Array) { // multi p for (var i = 0; i < textBodyNode["a:p"].length; i++) { var pNode = textBodyNode["a:p"][i]; var rNode = pNode["a:r"]; text += "<div class='" + getHorizontalAlign(pNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles) + "'>"; text += genBuChar(pNode); if (rNode === undefined) { // without r text += genSpanElement(pNode, slideLayoutSpNode, slideMasterSpNode, type, warpObj); } else if (rNode.constructor === Array) { // with multi r for (var j = 0; j < rNode.length; j++) { text += genSpanElement(rNode[j], slideLayoutSpNode, slideMasterSpNode, type, warpObj); } } else { // with one r text += genSpanElement(rNode, slideLayoutSpNode, slideMasterSpNode, type, warpObj); } text += "</div>"; } } else { // one p var pNode = textBodyNode["a:p"]; var rNode = pNode["a:r"]; text += "<div class='" + getHorizontalAlign(pNode, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles) + "'>"; text += genBuChar(pNode); if (rNode === undefined) { // without r text += genSpanElement(pNode, slideLayoutSpNode, slideMasterSpNode, type, warpObj); } else if (rNode.constructor === Array) { // with multi r for (var j = 0; j < rNode.length; j++) { text += genSpanElement(rNode[j], slideLayoutSpNode, slideMasterSpNode, type, warpObj); } } else { // with one r text += genSpanElement(rNode, slideLayoutSpNode, slideMasterSpNode, type, warpObj); } text += "</div>"; } return text; } function genBuChar(node) { var pPrNode = node["a:pPr"]; var lvl = parseInt(getTextByPathList(pPrNode, ["attrs", "lvl"])); if (isNaN(lvl)) { lvl = 0; } var buChar = getTextByPathList(pPrNode, ["a:buChar", "attrs", "char"]); if (buChar !== undefined) { var buFontAttrs = getTextByPathList(pPrNode, ["a:buFont", "attrs"]); if (buFontAttrs !== undefined) { var marginLeft = parseInt(getTextByPathList(pPrNode, ["attrs", "marL"])) * 96 / 914400; var marginRight = parseInt(buFontAttrs["pitchFamily"]); if (isNaN(marginLeft)) { marginLeft = 328600 * 96 / 914400; } if (isNaN(marginRight)) { marginRight = 0; } var typeface = buFontAttrs["typeface"]; return "<span style='font-family: " + typeface + "; margin-left: " + marginLeft * lvl + "px" + "; margin-right: " + marginRight + "px" + "; font-size: 20pt" + "'>" + buChar + "</span>"; } else { marginLeft = 328600 * 96 / 914400 * lvl; return "<span style='margin-left: " + marginLeft + "px;'>" + buChar + "</span>"; } } else { //buChar = '•'; return "<span style='margin-left: " + 328600 * 96 / 914400 * lvl + "px" + "; margin-right: " + 0 + "px;'></span>"; } return ""; } function genSpanElement(node, slideLayoutSpNode, slideMasterSpNode, type, warpObj) { var slideMasterTextStyles = warpObj["slideMasterTextStyles"]; var text = node["a:t"]; if (typeof text !== 'string') { text = getTextByPathList(node, ["a:fld", "a:t"]); if (typeof text !== 'string') { text = "&nbsp;"; } } var styleText = "color:" + getFontColor(node, type, slideMasterTextStyles) + ";font-size:" + getFontSize(node, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles) + ";font-family:" + getFontType(node, type, slideMasterTextStyles) + ";font-weight:" + getFontBold(node, type, slideMasterTextStyles) + ";font-style:" + getFontItalic(node, type, slideMasterTextStyles) + ";text-decoration:" + getFontDecoration(node, type, slideMasterTextStyles) + ";vertical-align:" + getTextVerticalAlign(node, type, slideMasterTextStyles) + ";"; var cssName = ""; if (styleText in styleTable) { cssName = styleTable[styleText]["name"]; } else { cssName = "_css_" + (Object.keys(styleTable).length + 1); styleTable[styleText] = { "name": cssName, "text": styleText }; } var linkID = getTextByPathList(node, ["a:rPr", "a:hlinkClick", "attrs", "r:id"]); if (linkID !== undefined) { var linkURL = warpObj["slideResObj"][linkID]["target"]; return "<span class='text-block " + cssName + "'><a href='" + linkURL + "' target='_blank'>" + text.replace(/\s/i, "&nbsp;") + "</a></span>"; } else { return "<span class='text-block " + cssName + "'>" + text.replace(/\s/i, "&nbsp;") + "</span>"; } } function getTextByPathStr(node, pathStr) { return getTextByPathList(node, pathStr.trim().split(/\s+/)); } function processPicNode(node, warpObj) { //debug( JSON.stringify( node ) ); var order = node["attrs"]["order"]; var rid = node["p:blipFill"]["a:blip"]["attrs"]["r:embed"]; var imgName = warpObj["slideResObj"][rid]["target"]; var imgFileExt = extractFileExtension(imgName).toLowerCase(); var zip = warpObj["zip"]; var imgArrayBuffer = zip.file(imgName).asArrayBuffer(); var mimeType = ""; var xfrmNode = node["p:spPr"]["a:xfrm"]; switch (imgFileExt) { case "jpg": case "jpeg": mimeType = "image/jpeg"; break; case "png": mimeType = "image/png"; break; case "gif": mimeType = "image/gif"; break; case "emf": // Not native support mimeType = "image/x-emf"; break; case "wmf": // Not native support mimeType = "image/x-wmf"; break; default: mimeType = "image/*"; } return "<div class='block content' style='" + getPosition(xfrmNode, undefined, undefined) + getSize(xfrmNode, undefined, undefined) + " z-index: " + order + ";" + "'><img src=\"data:" + mimeType + ";base64," + base64ArrayBuffer(imgArrayBuffer) + "\" style='width: 100%; height: 100%'/></div>"; } function extractFileExtension(filename) { return filename.substr((~-filename.lastIndexOf(".") >>> 0) + 2); } function applyLumModify(rgbStr, factor, offset) { var color = new colz.Color(rgbStr); //color.setLum(color.hsl.l * factor); color.setLum(color.hsl.l * (1 + offset)); return color.rgb.toString(); } function processGroupSpNode(node, warpObj) { var factor = 96 / 914400; var xfrmNode = node["p:grpSpPr"]["a:xfrm"]; var x = parseInt(xfrmNode["a:off"]["attrs"]["x"]) * factor; var y = parseInt(xfrmNode["a:off"]["attrs"]["y"]) * factor; var chx = parseInt(xfrmNode["a:chOff"]["attrs"]["x"]) * factor; var chy = parseInt(xfrmNode["a:chOff"]["attrs"]["y"]) * factor; var cx = parseInt(xfrmNode["a:ext"]["attrs"]["cx"]) * factor; var cy = parseInt(xfrmNode["a:ext"]["attrs"]["cy"]) * factor; var chcx = parseInt(xfrmNode["a:chExt"]["attrs"]["cx"]) * factor; var chcy = parseInt(xfrmNode["a:chExt"]["attrs"]["cy"]) * factor; var order = node["attrs"]["order"]; var result = "<div class='block group' style='z-index: " + order + "; top: " + (y - chy) + "px; left: " +