// Version 1.4.0

Function TOfficeObj(n);
Begin
	case lowercase(n) of
	"nodeinfo":
		return new NodeInfo("");
	"trange":
		return new TRange("");
	"tfont":
		return new TFont();
	"tcomment":
		return new TComment();
	"tcomments":
		return new TComments();
	"trichtext":
		return new TRichText();
	"txdrfromto":
		return new TxdrFromTo();
	"toff":
		return new TOff();
	"text":
		return new TExt();
	"txfrm":
		return new TXfrm();
	"tclientdata":
		return new TClientData();
	"tgraphicframepr":
		return new TGraphicFramePr();
	"tgraphicframe":
		return new TGraphicFrame();
	"ttwocellanchor":
		return new TtwoCellAnchor();
	"tcnvpicpr":
		return new TcNvPicPr();
	"tpictureformat":
		return new TPictureFormat();
	"tshapeformat":
		return new TShapeFormat();
	"tchart":
		return new TChart();
	"tlegend":
		return new TLegend();
	"tchartaxis":
		return new TChartAxis();
	"tnumfont":
		return new TNumFont();
	"tnamelayout":
		return new TNameLayout();
	"tpt":
		return new Tpt();
	"tstrcache":
		return new TStrCache();
	"tstrref":
		return new TStrRef();
	"tccat":
		return new TcCat();
	"tnumcache":
		return new TNumCache();
	"tnumref":
		return new TNumRef();
	"tcval":
		return new TcVal();
	"ttx":
		return new TTx();
	"tsolidfill":
		return new TSolidFill();
	"tschemeclr":
		return new TSchemeClr();
	"tln":
		return new TLn();
	"tcontourclr":
		return new TContourClr();
	"tsp3d":
		return new TSp3D();
	"tsppr":
		return new TspPr();
	"tdpt":
		return new TDpt();
	"tmarker":
		return new TMarker();
	"tser":
		return new TSer();
	"tdlbls":
		return new TdLbls();
	"tccharts":
		return new TcCharts();
	"tcscaling":
		return new TcScaling();
	"tcchartlines":
		return new TcChartLines();
	"tcnumfmt":
		return new TcNumFmt();
	"tar":
		return new TaR();
	"taendpararpr":
		return new TaEndParaRPr();
	"tap":
		return new TaP();
	"tappr":
		return new TaPPr();
	"talatin":
		return new TaLatin();
	"taea":
		return new TaEa();
	"tacs":
		return new TaCs();
	"tarpr":
		return new TaRPr();
	"tabodypr":
		return new TaBodyPr();
	"ttxpr":
		return new TTxPr();
	"tcaxs":
		return new TcAxs();
	"tplotarea":
		return new TplotArea();
	"tview3d":
		return new TView3D();
	"tborder":
		return new TBorder();
	"tborders":
		return new TBorders();
	"tnumfmts":
		return new TNumFmts();
	"tgradient":
		return new TGradient();
	"tfills":
		return new TFills();
	"tpattern":
		return new TPattern();
	"tstop":
		return new TStop();
	"talignment":
		return new TAlignment();
	"tprotection":
		return new TProtection();
	"tstyle":
		return new TStyle();
	"txf":
		return new TXf();
	"theaderfooter":
		return new THeaderFooter();
	"tmargins":
		return new TMargins();
	"thyperlink":
		return new THyperLink();
	"tsheetview":
		return new TSheetView();
	"tpane":
		return new TPane();
	"tselection":
		return new TSelection();
	"tpagelayout":
		return new TPageLayout();
	"tappproperty":
		return new TAppProperty();
	"tcoreproperty":
		return new TCoreProperty();
	"tbr":
		return new TBr();
	"twfont":
		return new TwFont();
	"twrpr":
		return new TwrPr();
	"tnumpr":
		return new TNumPr();
	"ttextbox":
		return new TTextBox();
	"twhyperlinkimpl":
		return new TWHyperLinkImpl();
	"twppr":
		return new TwpPr();
	"tcnvgraphicframepr":
		return new TcNvGraphicFramePr();
	"tnvpicpr":
		return new TnvPicPr();
	"tcnvpr":
		return new TCNvPr();
	"textlst":
		return new TExtLst();
	"taext":
		return new TAext();
	"tprstgeom":
		return new TprstGeom();
	"tblipfill":
		return new TblipFill();
	"twline":
		return new TwLine();
	"tpicsppr":
		return new TpicsPpr();
	"tblip":
		return new TBlip();
	"tstretch":
		return new TStretch();
	"tref":
		return new TRef();
	"tscheme":
		return new TScheme();
	"txdrstyle":
		return new TXdrStyle();
	"tpic":
		return new TPic();
	"tgraphicdata":
		return new TGraphicData();
	"tgraphic":
		return new TGraphic();
	"twinline":
		return new TwInline();
	"twdrawing":
		return new TwDrawing();
	"ttext":
		return new TText();
	"trun":
		return new TRun();
	"tbookmark":
		return new TBookMark();
	"tfldsimple":
		return new TFldSimple();
	"tparagraph":
		return new TParagraph();
	"twbody":
		return new TwBody();
	"toptinfo":
		return new TOptInfo();
	"trevision":
		return new TRevision();
	"tdoccomment":
		return new TDocComment();
	"tcol":
		return new TCol();
	"tcols":
		return new TCols();
	"tpagemargin":
		return new TPageMargin();
	"tdocgrid":
		return new TDocGrid();
	"treference":
		return new TReference();
	"tpageborders":
		return new TPageBorders();
	"tpage":
		return new TPage();
	"tdocsection":
		return new TDocSection();
	"tcellmerge":
		return new TcellMerge();
	"twtcpr":
		return new TwTcPr();
	"twtc":
		return new TwTc();
	"twtrpr":
		return new TwTrPr();
	"twshading":
		return new TwShading();
	"ttblcellmar":
		return new TTblCellMar();
	"ttblprex":
		return new TTblPrEx();
	"twtr":
		return new TwTr();
	"twborder":
		return new TwBorder();
	"twtblborders":
		return new TwTblBorders();
	"twtblppr":
		return new TwTblpPr();
	"twtblpr":
		return new TwTblPr();
	"twgridcol":
		return new TwGridCol();
	"twtblgrid":
		return new TwTblGrid();
	"ttable":
		return new TTable();
	"tcoreproperties":
		return new TCoreProperties();
	"tpicture":
		return new TPicture();
	"tpbdr":
		return new TpBdr();
	"tlatentstyle":
		return new TLatentStyle();
	"ttblstylepr":
		return new TtblStylePr();
	"tdocxstyle":
		return new TDocxStyle();
	"tdocpartobj":
		return new TDocPartObj();
	"tsdtpr":
		return new TSdtPr();
	"tsdtendpr":
		return new TSdtEndPr();
	"tsdtcontent":
		return new TSdtContent();
	"ttablecontentimpl":
		return new TTableContentImpl();
	"ttabstops":
		return new TTabStops();
	"ttabstop":
		return new TTabStop();
	"tnumber":
		return new TNumber();
	"tlevel":
		return new TLevel();
	"tnumstyle":
		return new TNumStyle();
	"texceltable":
		return new TExcelTable();
	"ttablestyle":
		return new TTableStyle();
	"tbreak":
		return new TBreak();
	"tprotect":
		return new TProtect();
	"tcalcpr":
		return new TCalcPr();
	End;
End;

///////////////////////////////////////////////////////////////
/// TFont
///////////////////////////////////////////////////////////////
type TFont=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'font');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property Name read readXMLName write writeXMLName;
	Function readXMLName();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Name'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLName);
	End;

	Function writeXMLName(str);
	Begin
		XMLName := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Size read readXMLSize write writeXMLSize;
	Function readXMLSize();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Size'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLSize);
	End;

	Function writeXMLSize(str);
	Begin
		XMLSize := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Bold read readXMLBold write writeXMLBold;
	Function readXMLBold();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Bold'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLBold);
	End;

	Function writeXMLBold(str);
	Begin
		XMLBold := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Italic read readXMLItalic write writeXMLItalic;
	Function readXMLItalic();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Italic'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLItalic);
	End;

	Function writeXMLItalic(str);
	Begin
		XMLItalic := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Color read readXMLColor write writeXMLColor;
	Function readXMLColor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Color'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLColor);
	End;

	Function writeXMLColor(str);
	Begin
		XMLColor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ThemeColor read readXMLThemeColor write writeXMLThemeColor;
	Function readXMLThemeColor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ThemeColor'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLThemeColor);
	End;

	Function writeXMLThemeColor(str);
	Begin
		XMLThemeColor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Strikethrough read readXMLStrikethrough write writeXMLStrikethrough;
	Function readXMLStrikethrough();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Strikethrough'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLStrikethrough);
	End;

	Function writeXMLStrikethrough(str);
	Begin
		XMLStrikethrough := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Script read readXMLScript write writeXMLScript;
	Function readXMLScript();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Script'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLScript);
	End;

	Function writeXMLScript(str);
	Begin
		XMLScript := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Charset read readXMLCharset write writeXMLCharset;
	Function readXMLCharset();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Charset'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLCharset);
	End;

	Function writeXMLCharset(str);
	Begin
		XMLCharset := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Underline read readXMLUnderline write writeXMLUnderline;
	Function readXMLUnderline();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Underline'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLUnderline);
	End;

	Function writeXMLUnderline(str);
	Begin
		XMLUnderline := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Name","name":"name","obj":XMLName,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Size","name":"sz","obj":XMLSize,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Bold","name":"b","obj":XMLBold,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			,("field":"Italic","name":"i","obj":XMLItalic,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			,("field":"Color","name":"color","obj":XMLColor,"attrEx":"","nodeType":"","attrName":"rgb", "desc":"", "class":"")
			,("field":"ThemeColor","name":"color","obj":XMLThemeColor,"attrEx":"theme","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Strikethrough","name":"strike","obj":XMLStrikethrough,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			,("field":"Script","name":"vertAlign","obj":XMLScript,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Charset","name":"charset","obj":XMLCharset,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Underline","name":"u","obj":XMLUnderline,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"FontStyle","name":"fontstyle","obj":FontStyle,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"OutlineFont","name":"outlinefont","obj":OutlineFont,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Shadow","name":"shadow","obj":Shadow,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"TintAndShade","name":"tintandshade","obj":TintAndShade,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Background","name":"background","obj":Background,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"rFont","name":"rFont","obj":rFont,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ThemeFont","name":"scheme","obj":ThemeFont,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ColorIndex","name":"color","obj":ColorIndex,"attrEx":"index","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Subscript","name":"subscript","obj":Subscript,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Superscript","name":"superscript","obj":Superscript,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	XMLName;
	XMLSize;
	XMLBold;
	XMLItalic;
	XMLColor;
	XMLThemeColor;
	XMLStrikethrough;
	XMLScript;
	XMLCharset;
	XMLUnderline;
	FontStyle;
	OutlineFont;
	Shadow;
	TintAndShade;
	Background;
	rFont;
	ThemeFont;
	ColorIndex;
	Subscript;
	Superscript;
End;

///////////////////////////////////////////////////////////////
/// TComment
///////////////////////////////////////////////////////////////
type TComment=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'r');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Font := new TFont(self, 'rPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Font.InitRootNode(node);
	End;

	Property Text read readXMLText write writeXMLText;
	Function readXMLText();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Text'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLText);
	End;

	Function writeXMLText(str);
	Begin
		XMLText := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Font","name":Font.NodeName,"obj":Font,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TFont")
			,("field":"Text","name":"t","obj":XMLText,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Space","name":"t","obj":Space,"attrEx":"xml:space","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Font;
	XMLText;
	Space;
End;

///////////////////////////////////////////////////////////////
/// TComments
///////////////////////////////////////////////////////////////
type TComments=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'comment/text');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("AuthorId", "authorId", AuthorId, ""),("Ref", "ref", Ref, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	Function AddComment(text);
	Begin
		o := new TComment(self, "r");
		ExtNodes[ length(ExtNodes) ] := array("field":"", "name":"r", "obj":o, "attrEx":"", "nodeType":"");
		o.Text := text;
		o.Font.Bold := "";
		o.Font.Size := 9;
		o.Font.rFont := "宋体";
		o.Font.Charset := 134;
		return o;
	End;	

	Function Comment(index);
	Begin
		return GetNode(index);
	End;

	//Attributes
	AuthorId;
	Ref;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TRichText
///////////////////////////////////////////////////////////////
type TRichText=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'si');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	Function AddText(text);
	Begin
		o := new TComment(self, "r");
		ExtNodes[ length(ExtNodes) ] := array("field":"", "name":"r", "obj":o, "attrEx":"", "nodeType":"");
		o.Text := text;
		return o;
	End;

	Function RichText(index);
	Begin
		return GetNode(index);
	End;

	//Attributes

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TxdrFromTo
///////////////////////////////////////////////////////////////
type TxdrFromTo=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'xdr:from');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Col","name":"xdr:col","obj":Col,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"ColOff","name":"xdr:colOff","obj":ColOff,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Row","name":"xdr:row","obj":Row,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"RowOff","name":"xdr:rowOff","obj":RowOff,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Col;
	ColOff;
	Row;
	RowOff;
End;

///////////////////////////////////////////////////////////////
/// TOff
///////////////////////////////////////////////////////////////
type TOff=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:off');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("X", "x", X, ""),("Y", "y", Y, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	X;
	Y;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TExt
///////////////////////////////////////////////////////////////
type TExt=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:ext');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Cx", "cx", Cx, ""),("Cy", "cy", Cy, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Cx;
	Cy;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TXfrm
///////////////////////////////////////////////////////////////
type TXfrm=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:xfrm');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Off := new TOff(self, 'a:off');
		Ext := new TExt(self, 'a:ext');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Off.InitRootNode(node);
		Ext.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Off","name":Off.NodeName,"obj":Off,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TOff")
			,("field":"Ext","name":Ext.NodeName,"obj":Ext,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TExt")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Off;
	Ext;
End;

///////////////////////////////////////////////////////////////
/// TClientData
///////////////////////////////////////////////////////////////
type TClientData=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'x:ClientData');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		ObjectType := "Note";
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("ObjectType", "ObjectType", ObjectType, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"MoveWithCells","name":"x:MoveWithCells","obj":MoveWithCells,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			,("field":"SizeWithCells","name":"x:SizeWithCells","obj":SizeWithCells,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			,("field":"Anchor","name":"x:Anchor","obj":Anchor,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"AutoFill","name":"x:AutoFill","obj":AutoFill,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Row","name":"x:Row","obj":Row,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Column","name":"x:Column","obj":Column,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	ObjectType;

	//Nodes
	MoveWithCells;
	SizeWithCells;
	Anchor;
	AutoFill;
	Row;
	Column;
End;

///////////////////////////////////////////////////////////////
/// TGraphicFramePr
///////////////////////////////////////////////////////////////
type TGraphicFramePr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'xdr:cNvGraphicFramePr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Id","name":"xdr:cNvPr","obj":Id,"attrEx":"id","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Name","name":"xdr:cNvPr","obj":Name,"attrEx":"name","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"cNvGraphicFramePr","name":"xdr:cNvGraphicFramePr","obj":cNvGraphicFramePr,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Id;
	Name;
	cNvGraphicFramePr;
End;

///////////////////////////////////////////////////////////////
/// TGraphicFrame
///////////////////////////////////////////////////////////////
type TGraphicFrame=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'xdr:graphicFrame');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		GraphicFramePr := new TGraphicFramePr(self, 'xdr:nvGraphicFramePr');
		Xfrm := new TXfrm(self, 'xdr:xfrm');
		Graphic := new TGraphic(self, 'a:graphic');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		GraphicFramePr.InitRootNode(node);
		Xfrm.InitRootNode(node);
		Graphic.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("macro", "macro", macro, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"GraphicFramePr","name":GraphicFramePr.NodeName,"obj":GraphicFramePr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TGraphicFramePr")
			,("field":"Xfrm","name":Xfrm.NodeName,"obj":Xfrm,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TXfrm")
			,("field":"Graphic","name":Graphic.NodeName,"obj":Graphic,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TGraphic")
			) union ExtNodes;
	End;

	//Attributes
	macro;

	//Nodes
	GraphicFramePr;
	Xfrm;
	Graphic;
End;

///////////////////////////////////////////////////////////////
/// TtwoCellAnchor
///////////////////////////////////////////////////////////////
type TtwoCellAnchor=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'xdr:twoCellAnchor');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		XFrom := new TxdrFromTo(self, 'xdr:from');
		XTo := new TxdrFromTo(self, 'xdr:to');
		GraphicFrame := new TGraphicFrame(self, 'xdr:graphicFrame');
		Pic := new TPic(self, 'xdr:pic');
		ClientData := new TClientData(self, 'xdr:clientData');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		XFrom.InitRootNode(node);
		XTo.InitRootNode(node);
		GraphicFrame.InitRootNode(node);
		Pic.InitRootNode(node);
		ClientData.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("EditAs", "editAs", EditAs, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"XFrom","name":XFrom.NodeName,"obj":XFrom,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TxdrFromTo")
			,("field":"XTo","name":XTo.NodeName,"obj":XTo,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TxdrFromTo")
			,("field":"GraphicFrame","name":GraphicFrame.NodeName,"obj":GraphicFrame,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TGraphicFrame")
			,("field":"Pic","name":Pic.NodeName,"obj":Pic,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TPic")
			,("field":"ClientData","name":ClientData.NodeName,"obj":ClientData,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"TClientData")
			) union ExtNodes;
	End;

	//Attributes
	EditAs;

	//Nodes
	XFrom;
	XTo;
	GraphicFrame;
	Pic;
	ClientData;
End;

///////////////////////////////////////////////////////////////
/// TcNvPicPr
///////////////////////////////////////////////////////////////
type TcNvPicPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'xdr:cNvPicPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"PicLocks","name":"a:picLocks","obj":PicLocks,"attrEx":"noChangeAspect","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	PicLocks;
End;

///////////////////////////////////////////////////////////////
/// TPictureFormat
///////////////////////////////////////////////////////////////
type TPictureFormat=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, '');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		BegColOff := 0;
		BegRowOff := 0;
		EndColOff := 0;
		EndRowOff := 0;
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"BegColOff","name":"BegColOff","obj":BegColOff,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"BegRowOff","name":"BegRowOff","obj":BegRowOff,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"EndColOff","name":"EndColOff","obj":EndColOff,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"EndRowOff","name":"EndRowOff","obj":EndRowOff,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	BegColOff;
	BegRowOff;
	EndColOff;
	EndRowOff;
End;

///////////////////////////////////////////////////////////////
/// TShapeFormat
///////////////////////////////////////////////////////////////
type TShapeFormat=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, '');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"BegColOff","name":"BegColOff","obj":BegColOff,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"BegRowOff","name":"BegRowOff","obj":BegRowOff,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"EndColOff","name":"EndColOff","obj":EndColOff,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"EndRowOff","name":"EndRowOff","obj":EndRowOff,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	Function AddText(text);
	Begin
		o := new TaP(self, "a:p");
		o.R.Rpr.Lang := "en-US";
		o.R.Rpr.AltLang := "zh-CN";
		o.R.Rpr.SZ := 2400;
		o.Ppr.Algn := "l";
		ExtNodes[ length(ExtNodes) ] := array("field":"", "name":"a:p", "obj":o, "attrEx":"", "nodeType":"");
		return o;
	End;

	//Attributes

	//Nodes
	BegColOff;
	BegRowOff;
	EndColOff;
	EndRowOff;
End;

///////////////////////////////////////////////////////////////
/// TChartImpl
///////////////////////////////////////////////////////////////
type TChartImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 't:chart');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Series := array();
		XAxis := new TChartAxis(self, 'XAxis');
		YAxis := new TChartAxis(self, 'YAxis');
		Legend := new TLegend(self, 'c:legend');
		Plotarea := new TplotArea(self, 'c:plotArea');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		XAxis.InitRootNode(node);
		YAxis.InitRootNode(node);
		Legend.InitRootNode(node);
		Plotarea.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Width","name":"Width","obj":Width,"attrEx":"","nodeType":"","attrName":"", "desc":"word图表宽度（cm）", "class":"")
			,("field":"Height","name":"Height","obj":Height,"attrEx":"","nodeType":"","attrName":"", "desc":"word图表高度（cm）", "class":"")
			,("field":"BegColOff","name":"BegColOff","obj":BegColOff,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"BegRowOff","name":"BegRowOff","obj":BegRowOff,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"EndColOff","name":"EndColOff","obj":EndColOff,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"EndRowOff","name":"EndRowOff","obj":EndRowOff,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"Name","name":"Name","obj":Name,"attrEx":"","nodeType":"","attrName":"", "desc":"图表名称", "class":"")
			,("field":"Title","name":"Title","obj":Title,"attrEx":"","nodeType":"","attrName":"", "desc":"图表标题", "class":"")
			,("field":"Type","name":"Type","obj":Type,"attrEx":"","nodeType":"","attrName":"", "desc":"图表类型", "class":"")
			,("field":"VaryColors","name":"VaryColors","obj":VaryColors,"attrEx":"","nodeType":"","attrName":"", "desc":"varyColors (按点) 改变颜色，此元素指定系列中的每个数据标记具有不同的颜色。", "class":"")
			,("field":"ShowLegendKey","name":"ShowLegendKey","obj":ShowLegendKey,"attrEx":"","nodeType":"","attrName":"", "desc":"如果数据标签的图例项标示可见，则该属性值为 True，读/写 Boolean。", "class":"")
			,("field":"ShowVal","name":"ShowVal","obj":ShowVal,"attrEx":"","nodeType":"","attrName":"", "desc":"允许用户在图表中显示数据标签的值，读/写 Boolean。", "class":"")
			,("field":"ShowCatName","name":"ShowCatName","obj":ShowCatName,"attrEx":"","nodeType":"","attrName":"", "desc":"允许用户在图表中显示数据标签的分类名称，读/写 Boolean。", "class":"")
			,("field":"ShowSerName","name":"ShowSerName","obj":ShowSerName,"attrEx":"","nodeType":"","attrName":"", "desc":"允许用户在图表中显示数据标签的系列名称，读/写 Boolean。", "class":"")
			,("field":"ShowBubbleSize","name":"ShowBubbleSize","obj":ShowBubbleSize,"attrEx":"","nodeType":"","attrName":"", "desc":"允许用户在图表中显示数据标签的气泡大小，读/写 Boolean", "class":"")
			,("field":"ShowPercent","name":"ShowPercent","obj":ShowPercent,"attrEx":"","nodeType":"","attrName":"", "desc":"允许用户在图表中显示数据标签的百分比数值，读/写 Boolean。", "class":"")
			,("field":"ShowLeaderLines","name":"ShowLeaderLines","obj":ShowLeaderLines,"attrEx":"","nodeType":"","attrName":"", "desc":"如果数据系列有引导线，则该属性值为 True，读/写 Boolean。", "class":"")
			,("field":"DataTable","name":"DataTable","obj":DataTable,"attrEx":"","nodeType":"","attrName":"", "desc":"显示数据表，读/写 Boolean。", "class":"")
			,("field":"Ord","name":"Ord","obj":Ord,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"Series","name":"w:ser","obj":Series,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"XAxis","name":XAxis.NodeName,"obj":XAxis,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TChartAxis")
			,("field":"YAxis","name":YAxis.NodeName,"obj":YAxis,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TChartAxis")
			,("field":"Legend","name":Legend.NodeName,"obj":Legend,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TLegend")
			,("field":"Plotarea","name":Plotarea.NodeName,"obj":Plotarea,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TplotArea")
			,("field":"ShowBlanksAs","name":"ShowBlanksAs","obj":ShowBlanksAs,"attrEx":"","nodeType":"","attrName":"", "desc":"此元素指定如何在图表上绘制空白单元格。", "class":"")
			,("field":"plotVisOnly","name":"plotVisOnly","obj":plotVisOnly,"attrEx":"","nodeType":"","attrName":"", "desc":"此元素指定如何在图表上绘制空白单元格。", "class":"")
			,("field":"ChartNode","name":"ChartNode","obj":ChartNode,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"plotAreaNode","name":"plotAreaNode","obj":plotAreaNode,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"C","name":"C","obj":C,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"xmlObj","name":"xmlObj","obj":xmlObj,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"Rid","name":"Rid","obj":Rid,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"pNode","name":"pNode","obj":pNode,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"DisableExcel","name":"DisableExcel","obj":DisableExcel,"attrEx":"","nodeType":"","attrName":"", "desc":"是否内嵌excel数据文件，默认嵌入。", "class":"")
			,("field":"Excel","name":"Excel","obj":Excel,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"chartFileName","name":"chartFileName","obj":chartFileName,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"excelFileName","name":"excelFileName","obj":excelFileName,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"drawingFileName","name":"drawingFileName","obj":drawingFileName,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Width;
	Height;
	BegColOff;
	BegRowOff;
	EndColOff;
	EndRowOff;
	Name;
	Title;
	Type;
	VaryColors;
	ShowLegendKey;
	ShowVal;
	ShowCatName;
	ShowSerName;
	ShowBubbleSize;
	ShowPercent;
	ShowLeaderLines;
	DataTable;
	Ord;
	Series;
	XAxis;
	YAxis;
	Legend;
	Plotarea;
	ShowBlanksAs;
	plotVisOnly;
	ChartNode;
	plotAreaNode;
	C;
	xmlObj;
	Rid;
	pNode;
	DisableExcel;
	Excel;
	chartFileName;
	excelFileName;
	drawingFileName;
End;

///////////////////////////////////////////////////////////////
/// TLegend
///////////////////////////////////////////////////////////////
type TLegend=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:legend');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"legendPos","name":"c:legendPos","obj":legendPos,"attrEx":"val","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Layout","name":"c:layout","obj":Layout,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			,("field":"overlay","name":"c:overlay","obj":overlay,"attrEx":"val","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	Property Position write setPosition;
	Function setPosition(t);
	Begin
		m := array("bottom":    "b",
			"left":      "l",
			"right":     "r",
			"top":       "t",
			"top_right": "tr");
		legendPos := m[t];
	End;

	//Attributes

	//Nodes
	legendPos;
	Layout;
	overlay;
End;

///////////////////////////////////////////////////////////////
/// TChartAxis
///////////////////////////////////////////////////////////////
type TChartAxis=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'ChartAxis');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		NumFont := new TNumFont(self, 'NumFont');
		NameLayout := new TNameLayout(self, 'NameLayout');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		NumFont.InitRootNode(node);
		NameLayout.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"None","name":"None","obj":None,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Crossing","name":"Crossing","obj":Crossing,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"MajorGridlines","name":"MajorGridlines","obj":MajorGridlines,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"MinorGridlines","name":"MinorGridlines","obj":MinorGridlines,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"MajorTickMark","name":"MajorTickMark","obj":MajorTickMark,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"MinorTickMark","name":"MinorTickMark","obj":MinorTickMark,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"MinorUnitType","name":"MinorUnitType","obj":MinorUnitType,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"MajorUnit","name":"MajorUnit","obj":MajorUnit,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"MajorUnitType","name":"MajorUnitType","obj":MajorUnitType,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"TickLabelSkip","name":"TickLabelSkip","obj":TickLabelSkip,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"DisplayUnits","name":"DisplayUnits","obj":DisplayUnits,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"DisplayUnitsVisible","name":"DisplayUnitsVisible","obj":DisplayUnitsVisible,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"DateAxis","name":"DateAxis","obj":DateAxis,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ReverseOrder","name":"ReverseOrder","obj":ReverseOrder,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Max","name":"Max","obj":Max,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Min","name":"Min","obj":Min,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"NumFormat","name":"NumFormat","obj":NumFormat,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"NumFont","name":NumFont.NodeName,"obj":NumFont,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TNumFont")
			,("field":"LogBase","name":"LogBase","obj":LogBase,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"NameLayout","name":NameLayout.NodeName,"obj":NameLayout,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TNameLayout")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	None;
	Crossing;
	MajorGridlines;
	MinorGridlines;
	MajorTickMark;
	MinorTickMark;
	MinorUnitType;
	MajorUnit;
	MajorUnitType;
	TickLabelSkip;
	DisplayUnits;
	DisplayUnitsVisible;
	DateAxis;
	ReverseOrder;
	Max;
	Min;
	NumFormat;
	NumFont;
	LogBase;
	NameLayout;
End;

///////////////////////////////////////////////////////////////
/// TNumFont
///////////////////////////////////////////////////////////////
type TNumFont=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'NumFont');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Color","name":"Color","obj":Color,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Bold","name":"Bold","obj":Bold,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Italic","name":"Italic","obj":Italic,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Underline","name":"Underline","obj":Underline,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Color;
	Bold;
	Italic;
	Underline;
End;

///////////////////////////////////////////////////////////////
/// TNameLayout
///////////////////////////////////////////////////////////////
type TNameLayout=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'NameLayout');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"X","name":"X","obj":X,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Y","name":"Y","obj":Y,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Width","name":"Width","obj":Width,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Height","name":"Height","obj":Height,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	X;
	Y;
	Width;
	Height;
End;

///////////////////////////////////////////////////////////////
/// Tpt
///////////////////////////////////////////////////////////////
type Tpt=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:pt');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("IDx", "idx", IDx, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"V","name":"c:v","obj":V,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	IDx;

	//Nodes
	V;
End;

///////////////////////////////////////////////////////////////
/// TStrCache
///////////////////////////////////////////////////////////////
type TStrCache=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:strRef');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Pt := new Tpt(self, 'c:pt');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Pt.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"PtCount","name":"c:ptCount","obj":PtCount,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Pt","name":Pt.NodeName,"obj":Pt,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"Tpt")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	PtCount;
	Pt;
End;

///////////////////////////////////////////////////////////////
/// TStrRef
///////////////////////////////////////////////////////////////
type TStrRef=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:strRef');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		StrCache := new TStrCache(self, 'c:strCache');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		StrCache.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"F","name":"c:f","obj":F,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"StrCache","name":StrCache.NodeName,"obj":StrCache,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TStrCache")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	F;
	StrCache;
End;

///////////////////////////////////////////////////////////////
/// TcCat
///////////////////////////////////////////////////////////////
type TcCat=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:cat');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		StrRef := new TStrRef(self, 'c:strRef');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		StrRef.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"StrRef","name":StrRef.NodeName,"obj":StrRef,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TStrRef")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	StrRef;
End;

///////////////////////////////////////////////////////////////
/// TNumCache
///////////////////////////////////////////////////////////////
type TNumCache=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:numCache');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Pt := new Tpt(self, 'c:pt');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Pt.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"FormatCode","name":"c:formatCode","obj":FormatCode,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"PtCount","name":"c:ptCount","obj":PtCount,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Pt","name":Pt.NodeName,"obj":Pt,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"Tpt")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	FormatCode;
	PtCount;
	Pt;
End;

///////////////////////////////////////////////////////////////
/// TNumRef
///////////////////////////////////////////////////////////////
type TNumRef=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:numRef');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		NumCache := new TNumCache(self, 'c:numCache');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		NumCache.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"F","name":"c:f","obj":F,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"NumCache","name":NumCache.NodeName,"obj":NumCache,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TNumCache")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	F;
	NumCache;
End;

///////////////////////////////////////////////////////////////
/// TcVal
///////////////////////////////////////////////////////////////
type TcVal=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:val');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		NumRef := new TNumRef(self, 'c:numRef');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		NumRef.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"NumRef","name":NumRef.NodeName,"obj":NumRef,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TNumRef")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	NumRef;
End;

///////////////////////////////////////////////////////////////
/// TTx
///////////////////////////////////////////////////////////////
type TTx=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:tx');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		StrRef := new TStrRef(self, 'c:strRef');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		StrRef.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"StrRef","name":StrRef.NodeName,"obj":StrRef,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TStrRef")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	StrRef;
End;

///////////////////////////////////////////////////////////////
/// TSolidFill
///////////////////////////////////////////////////////////////
type TSolidFill=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:solidFill');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		SchemeClr := new TSchemeClr(self, 'a:schemeClr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		SchemeClr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"SchemeClr","name":SchemeClr.NodeName,"obj":SchemeClr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TSchemeClr")
			,("field":"SrgbClr","name":"a:srgbClr","obj":SrgbClr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	SchemeClr;
	SrgbClr;
End;

///////////////////////////////////////////////////////////////
/// TSchemeClr
///////////////////////////////////////////////////////////////
type TSchemeClr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:schemeClr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Val", "val", Val, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"LumMod","name":"a:lumMod","obj":LumMod,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"LumOff","name":"a:lumOff","obj":LumOff,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	Val;

	//Nodes
	LumMod;
	LumOff;
End;

///////////////////////////////////////////////////////////////
/// TLn
///////////////////////////////////////////////////////////////
type TLn=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 't:Ln');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		SolidFill := new TSolidFill(self, 'a:solidFill');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		SolidFill.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Algn", "algn", Algn, ""),("Cap", "cap", Cap, ""),("Cmpd", "cmpd", Cmpd, ""),("W", "w", W, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"NoFill","name":"a:noFill","obj":NoFill,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			,("field":"prstDash","name":"a:prstDash","obj":prstDash,"attrEx":"val","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Round","name":"a:round","obj":Round,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			,("field":"SolidFill","name":SolidFill.NodeName,"obj":SolidFill,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TSolidFill")
			) union ExtNodes;
	End;

	//Attributes
	Algn;
	Cap;
	Cmpd;
	W;

	//Nodes
	NoFill;
	prstDash;
	Round;
	SolidFill;
End;

///////////////////////////////////////////////////////////////
/// TContourClr
///////////////////////////////////////////////////////////////
type TContourClr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:contourClr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		SchemeClr := new TSchemeClr(self, 'a:schemeClr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		SchemeClr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"SchemeClr","name":SchemeClr.NodeName,"obj":SchemeClr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TSchemeClr")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	SchemeClr;
End;

///////////////////////////////////////////////////////////////
/// TSp3D
///////////////////////////////////////////////////////////////
type TSp3D=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:sp3d');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		ContourClr := new TContourClr(self, 'a:contourClr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		ContourClr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("ContourW", "contourW", ContourW, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"ContourClr","name":ContourClr.NodeName,"obj":ContourClr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TContourClr")
			) union ExtNodes;
	End;

	//Attributes
	ContourW;

	//Nodes
	ContourClr;
End;

///////////////////////////////////////////////////////////////
/// TspPr
///////////////////////////////////////////////////////////////
type TspPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:spPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		SolidFill := new TSolidFill(self, 'a:solidFill');
		Ln := new TLn(self, 'a:ln');
		Sp3D := new TSp3D(self, 'a:sp3d');
		XFrm := new TXfrm(self, 'a:xfrm');
		PrstGeom := new TprstGeom(self, 'a:prstGeom');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		SolidFill.InitRootNode(node);
		Ln.InitRootNode(node);
		Sp3D.InitRootNode(node);
		XFrm.InitRootNode(node);
		PrstGeom.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"NoFill","name":"a:noFill","obj":NoFill,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			,("field":"SolidFill","name":SolidFill.NodeName,"obj":SolidFill,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TSolidFill")
			,("field":"Ln","name":Ln.NodeName,"obj":Ln,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TLn")
			,("field":"Sp3D","name":Sp3D.NodeName,"obj":Sp3D,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TSp3D")
			,("field":"EffectLst","name":"a:effectLst","obj":EffectLst,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			,("field":"XFrm","name":XFrm.NodeName,"obj":XFrm,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TXfrm")
			,("field":"PrstGeom","name":PrstGeom.NodeName,"obj":PrstGeom,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TprstGeom")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	NoFill;
	SolidFill;
	Ln;
	Sp3D;
	EffectLst;
	XFrm;
	PrstGeom;
End;

///////////////////////////////////////////////////////////////
/// TDpt
///////////////////////////////////////////////////////////////
type TDpt=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:dPt');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		SpPr := new TspPr(self, 'c:spPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		SpPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"IDx","name":"c:idx","obj":IDx,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Bubble3D","name":"c:bubble3D","obj":Bubble3D,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"SpPr","name":SpPr.NodeName,"obj":SpPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TspPr")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	IDx;
	Bubble3D;
	SpPr;
End;

///////////////////////////////////////////////////////////////
/// TMarker
///////////////////////////////////////////////////////////////
type TMarker=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:marker');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		SpPr := new TspPr(self, 'c:spPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		SpPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Symbol","name":"c:symbol","obj":Symbol,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Size","name":"c:size","obj":Size,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"SpPr","name":SpPr.NodeName,"obj":SpPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TspPr")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Symbol;
	Size;
	SpPr;
End;

///////////////////////////////////////////////////////////////
/// TSer
///////////////////////////////////////////////////////////////
type TSer=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:ser');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Tx := new TTx(self, 'c:tx');
		SpPr := new TspPr(self, 'c:spPr');
		DPt := new TDpt(self, 'c:dPt');
		DPtEx := array();
		DLbls := new TdLbls(self, 'c:dLbls');
		Marker := new TMarker(self, 'c:marker');
		Cat := new TcCat(self, 'c:cat');
		Val := new TcVal(self, 'c:val');
		XVal := new TcCat(self, 'c:xVal');
		YVal := new TcVal(self, 'c:yVal');
		BubbleSize := new TcVal(self, 'c:bubbleSize');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Tx.InitRootNode(node);
		SpPr.InitRootNode(node);
		DPt.InitRootNode(node);
		DLbls.InitRootNode(node);
		Marker.InitRootNode(node);
		Cat.InitRootNode(node);
		Val.InitRootNode(node);
		XVal.InitRootNode(node);
		YVal.InitRootNode(node);
		BubbleSize.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"IDx","name":"c:idx","obj":IDx,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Ord","name":"c:order","obj":Ord,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Tx","name":Tx.NodeName,"obj":Tx,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TTx")
			,("field":"SpPr","name":SpPr.NodeName,"obj":SpPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TspPr")
			,("field":"DPt","name":DPt.NodeName,"obj":DPt,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TDpt")
			,("field":"DPtEx","name":"c:dPt","obj":DPtEx,"attrEx":"","nodeType":"","attrName":"","arrObj":"array", "desc":"", "class":"TDpt")
			,("field":"DLbls","name":DLbls.NodeName,"obj":DLbls,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TdLbls")
			,("field":"Marker","name":Marker.NodeName,"obj":Marker,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TMarker")
			,("field":"InvertIfNegative","name":"c:invertIfNegative","obj":InvertIfNegative,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Cat","name":Cat.NodeName,"obj":Cat,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcCat")
			,("field":"Val","name":Val.NodeName,"obj":Val,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcVal")
			,("field":"XVal","name":XVal.NodeName,"obj":XVal,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcCat")
			,("field":"YVal","name":YVal.NodeName,"obj":YVal,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcVal")
			,("field":"Smooth","name":"c:smooth","obj":Smooth,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"BubbleSize","name":BubbleSize.NodeName,"obj":BubbleSize,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcVal")
			,("field":"Bubble3D","name":"c:bubble3D","obj":Bubble3D,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	IDx;
	Ord;
	Tx;
	SpPr;
	DPt;
	DPtEx;
	DLbls;
	Marker;
	InvertIfNegative;
	Cat;
	Val;
	XVal;
	YVal;
	Smooth;
	BubbleSize;
	Bubble3D;
End;

///////////////////////////////////////////////////////////////
/// TdLbls
///////////////////////////////////////////////////////////////
type TdLbls=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:dLbls');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Del","name":"c:delete","obj":Del,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ShowLegendKey","name":"c:showLegendKey","obj":ShowLegendKey,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ShowVal","name":"c:showVal","obj":ShowVal,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ShowCatName","name":"c:showCatName","obj":ShowCatName,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ShowSerName","name":"c:showSerName","obj":ShowSerName,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ShowPercent","name":"c:showPercent","obj":ShowPercent,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ShowBubbleSize","name":"c:showBubbleSize","obj":ShowBubbleSize,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ShowLeaderLines","name":"c:showLeaderLines","obj":ShowLeaderLines,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Del;
	ShowLegendKey;
	ShowVal;
	ShowCatName;
	ShowSerName;
	ShowPercent;
	ShowBubbleSize;
	ShowLeaderLines;
End;

///////////////////////////////////////////////////////////////
/// TcCharts
///////////////////////////////////////////////////////////////
type TcCharts=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:chart');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Ser := array();
		DLbls := new TdLbls(self, 'c:dLbls');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		DLbls.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"BarDir","name":"c:barDir","obj":BarDir,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"BubbleScale","name":"c:bubbleScale","obj":BubbleScale,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Grouping","name":"c:grouping","obj":Grouping,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"RadarStyle","name":"c:radarStyle","obj":RadarStyle,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ScatterStyle","name":"c:scatterStyle","obj":ScatterStyle,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"OfPieType","name":"c:ofPieType","obj":OfPieType,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"VaryColors","name":"c:varyColors","obj":VaryColors,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Wireframe","name":"c:wireframe","obj":Wireframe,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Ser","name":"c:ser","obj":Ser,"attrEx":"","nodeType":"","attrName":"","arrObj":"array", "desc":"", "class":"TSer")
			,("field":"SerLines","name":"c:serLines","obj":SerLines,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"DLbls","name":DLbls.NodeName,"obj":DLbls,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TdLbls")
			,("field":"Shape","name":"c:shape","obj":Shape,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"HoleSize","name":"c:holeSize","obj":HoleSize,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Smooth","name":"c:smooth","obj":Smooth,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Overlap","name":"c:overlap","obj":Overlap,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"AxID","name":"c:axId","obj":AxID,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"AxID2","name":"c:axId","obj":AxID2,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"AxID3","name":"c:axId","obj":AxID3,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	BarDir;
	BubbleScale;
	Grouping;
	RadarStyle;
	ScatterStyle;
	OfPieType;
	VaryColors;
	Wireframe;
	Ser;
	SerLines;
	DLbls;
	Shape;
	HoleSize;
	Smooth;
	Overlap;
	AxID;
	AxID2;
	AxID3;
End;

///////////////////////////////////////////////////////////////
/// TcScaling
///////////////////////////////////////////////////////////////
type TcScaling=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:scaling');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"LogBase","name":"c:logBase","obj":LogBase,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Orientation","name":"c:orientation","obj":Orientation,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Max","name":"c:max","obj":Max,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Min","name":"c:min","obj":Min,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	LogBase;
	Orientation;
	Max;
	Min;
End;

///////////////////////////////////////////////////////////////
/// TcChartLines
///////////////////////////////////////////////////////////////
type TcChartLines=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:cChartLines');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		SpPr := new TspPr(self, 'c:spPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		SpPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"SpPr","name":SpPr.NodeName,"obj":SpPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TspPr")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	SpPr;
End;

///////////////////////////////////////////////////////////////
/// TcNumFmt
///////////////////////////////////////////////////////////////
type TcNumFmt=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:numFmt');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("FormatCode", "formatCode", FormatCode, ""),("SourceLinked", "sourceLinked", SourceLinked, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	FormatCode;
	SourceLinked;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TaR
///////////////////////////////////////////////////////////////
type TaR=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:r');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Rpr := new TaRpr(self, 'a:rPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Rpr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Rpr","name":Rpr.NodeName,"obj":Rpr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TaRpr")
			,("field":"T","name":"a:t","obj":T,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Rpr;
	T;
End;

///////////////////////////////////////////////////////////////
/// TaEndParaRPr
///////////////////////////////////////////////////////////////
type TaEndParaRPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:endParaRPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Lang", "lang", Lang, ""),("AltLang", "altLang", AltLang, ""),("Sz", "sz", Sz, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Lang;
	AltLang;
	Sz;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TaP
///////////////////////////////////////////////////////////////
type TaP=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:p');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Ppr := new TaPPr(self, 'a:pPr');
		R := new TaR(self, 'a:r');
		EndParaRPr := new TaEndParaRPr(self, 'a:endParaRPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Ppr.InitRootNode(node);
		R.InitRootNode(node);
		EndParaRPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Ppr","name":Ppr.NodeName,"obj":Ppr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TaPPr")
			,("field":"R","name":R.NodeName,"obj":R,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TaR")
			,("field":"EndParaRPr","name":EndParaRPr.NodeName,"obj":EndParaRPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TaEndParaRPr")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Ppr;
	R;
	EndParaRPr;
End;

///////////////////////////////////////////////////////////////
/// TaPPr
///////////////////////////////////////////////////////////////
type TaPPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:pPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		DefRPr := new TaRPr(self, 'a:defRPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		DefRPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Algn", "algn", Algn, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"DefRPr","name":DefRPr.NodeName,"obj":DefRPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TaRPr")
			) union ExtNodes;
	End;

	//Attributes
	Algn;

	//Nodes
	DefRPr;
End;

///////////////////////////////////////////////////////////////
/// TaLatin
///////////////////////////////////////////////////////////////
type TaLatin=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:latin');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Typeface", "typeface", Typeface, ""),("Panose", "panose", Panose, ""),("PitchFamily", "pitchFamily", PitchFamily, ""),("Charset", "charset", Charset, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Typeface;
	Panose;
	PitchFamily;
	Charset;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TaEa
///////////////////////////////////////////////////////////////
type TaEa=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:ea');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Typeface", "typeface", Typeface, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Typeface;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TaCs
///////////////////////////////////////////////////////////////
type TaCs=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:cs');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Typeface", "typeface", Typeface, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Typeface;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TaRPr
///////////////////////////////////////////////////////////////
type TaRPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:defRPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		SolidFill := new TSolidFill(self, 'a:solidFill');
		Latin := new TaLatin(self, 'a:latin');
		Ea := new TaEa(self, 'a:ea');
		Cs := new TaCs(self, 'a:cs');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		SolidFill.InitRootNode(node);
		Latin.InitRootNode(node);
		Ea.InitRootNode(node);
		Cs.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("AltLang", "altLang", AltLang, ""),("Bold", "b", Bold, ""),("Baseline", "baseline", Baseline, ""),("Bmk", "bmk", Bmk, ""),("Cap", "cap", Cap, ""),("Dirty", "dirty", Dirty, ""),("Err", "err", Err, ""),("Italic", "i", Italic, ""),("Kern", "kern", Kern, ""),("Kumimoji", "kumimoji", Kumimoji, ""),("Lang", "lang", Lang, ""),("NoProof", "noProof", NoProof, ""),("NormalizeH", "normalizeH", NormalizeH, ""),("SmtID", "smtId", SmtID, ""),("Spc", "spc", Spc, ""),("Strike", "strike", Strike, ""),("Sz", "sz", Sz, ""),("SmtClean", "smtClean", SmtClean, ""),("U", "u", U, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"SolidFill","name":SolidFill.NodeName,"obj":SolidFill,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TSolidFill")
			,("field":"Latin","name":Latin.NodeName,"obj":Latin,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TaLatin")
			,("field":"Ea","name":Ea.NodeName,"obj":Ea,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TaEa")
			,("field":"Cs","name":Cs.NodeName,"obj":Cs,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TaCs")
			) union ExtNodes;
	End;

	//Attributes
	AltLang;
	Bold;
	Baseline;
	Bmk;
	Cap;
	Dirty;
	Err;
	Italic;
	Kern;
	Kumimoji;
	Lang;
	NoProof;
	NormalizeH;
	SmtID;
	Spc;
	Strike;
	Sz;
	SmtClean;
	U;

	//Nodes
	SolidFill;
	Latin;
	Ea;
	Cs;
End;

///////////////////////////////////////////////////////////////
/// TaBodyPr
///////////////////////////////////////////////////////////////
type TaBodyPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:bodyPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Vert", "vert", Vert, ""),("VertOverflow", "vertOverflow", VertOverflow, ""),("HorzOverflow", "horzOverflow", HorzOverflow, ""),("RtlCol", "rtlCol", RtlCol, ""),("Anchor", "anchor", Anchor, ""),("AnchorCtr", "anchorCtr", AnchorCtr, ""),("Rot", "rot", Rot, ""),("BIns", "bIns", BIns, ""),("CompatLnSpc", "compatLnSpc", CompatLnSpc, ""),("ForceAA", "forceAA", ForceAA, ""),("FromWordArt", "fromWordArt", FromWordArt, ""),("LIns", "lIns", LIns, ""),("NumCol", "numCol", NumCol, ""),("RIns", "rIns", RIns, ""),("SpcCol", "spcCol", SpcCol, ""),("SpcFirstLastPara", "spcFirstLastPara", SpcFirstLastPara, ""),("TIns", "tIns", TIns, ""),("Upright", "upright", Upright, ""),("Wrap", "wrap", Wrap, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Vert;
	VertOverflow;
	HorzOverflow;
	RtlCol;
	Anchor;
	AnchorCtr;
	Rot;
	BIns;
	CompatLnSpc;
	ForceAA;
	FromWordArt;
	LIns;
	NumCol;
	RIns;
	SpcCol;
	SpcFirstLastPara;
	TIns;
	Upright;
	Wrap;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TTxPr
///////////////////////////////////////////////////////////////
type TTxPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'txPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		BodyPr := new TaBodyPr(self, 'a:bodyPr');
		P := new TaP(self, 'a:p');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		BodyPr.InitRootNode(node);
		P.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"BodyPr","name":BodyPr.NodeName,"obj":BodyPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TaBodyPr")
			,("field":"LstStyle","name":"a:lstStyle","obj":LstStyle,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"P","name":P.NodeName,"obj":P,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TaP")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	BodyPr;
	LstStyle;
	P;
End;

///////////////////////////////////////////////////////////////
/// TcAxs
///////////////////////////////////////////////////////////////
type TcAxs=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:catAx');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Scaling := new TcScaling(self, 'c:scaling');
		MajorGridlines := new TcChartLines(self, 'c:majorGridlines');
		MinorGridlines := new TcChartLines(self, 'c:minorGridlines');
		NumFmt := new TcNumFmt(self, 'c:numFmt');
		SpPr := new TspPr(self, 'c:spPr');
		TxPr := new TTxPr(self, 'c:txPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Scaling.InitRootNode(node);
		MajorGridlines.InitRootNode(node);
		MinorGridlines.InitRootNode(node);
		NumFmt.InitRootNode(node);
		SpPr.InitRootNode(node);
		TxPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"AxID","name":"c:axId","obj":AxID,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Scaling","name":Scaling.NodeName,"obj":Scaling,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcScaling")
			,("field":"Del","name":"c:delete","obj":Del,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"AxPos","name":"c:axPos","obj":AxPos,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"MajorGridlines","name":MajorGridlines.NodeName,"obj":MajorGridlines,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcChartLines")
			,("field":"MinorGridlines","name":MinorGridlines.NodeName,"obj":MinorGridlines,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcChartLines")
			,("field":"NumFmt","name":NumFmt.NodeName,"obj":NumFmt,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcNumFmt")
			,("field":"MajorTickMark","name":"c:majorTickMark","obj":MajorTickMark,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"MinorTickMark","name":"c:minorTickMark","obj":MinorTickMark,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"TickLblPos","name":"c:tickLblPos","obj":TickLblPos,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"SpPr","name":SpPr.NodeName,"obj":SpPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TspPr")
			,("field":"TxPr","name":TxPr.NodeName,"obj":TxPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TTxPr")
			,("field":"CrossAx","name":"c:crossAx","obj":CrossAx,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Crosses","name":"c:crosses","obj":Crosses,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"CrossBetween","name":"c:crossBetween","obj":CrossBetween,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"MajorUnit","name":"c:majorUnit","obj":MajorUnit,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"MinorUnit","name":"c:minorUnit","obj":MinorUnit,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Auto","name":"c:auto","obj":Auto,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"LblAlgn","name":"c:lblAlgn","obj":LblAlgn,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"LblOffset","name":"c:lblOffset","obj":LblOffset,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"TickLblSkip","name":"c:tickLblSkip","obj":TickLblSkip,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"TickMarkSkip","name":"c:tickMarkSkip","obj":TickMarkSkip,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"NoMultiLvlLbl","name":"c:noMultiLvlLbl","obj":NoMultiLvlLbl,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	AxID;
	Scaling;
	Del;
	AxPos;
	MajorGridlines;
	MinorGridlines;
	NumFmt;
	MajorTickMark;
	MinorTickMark;
	TickLblPos;
	SpPr;
	TxPr;
	CrossAx;
	Crosses;
	CrossBetween;
	MajorUnit;
	MinorUnit;
	Auto;
	LblAlgn;
	LblOffset;
	TickLblSkip;
	TickMarkSkip;
	NoMultiLvlLbl;
End;

///////////////////////////////////////////////////////////////
/// TplotArea
///////////////////////////////////////////////////////////////
type TplotArea=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:plotArea');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Chart := new TcCharts(self, 'c:chartname');
		CatAx := new TcAxs(self, 'c:catAx');
		ValAx := new TcAxs(self, 'c:valAx');
		SerAx := new TcAxs(self, 'c:serAx');
		SpPr := new TspPr(self, 'c:spPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Chart.InitRootNode(node);
		CatAx.InitRootNode(node);
		ValAx.InitRootNode(node);
		SerAx.InitRootNode(node);
		SpPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Layout","name":"c:layout","obj":Layout,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			,("field":"Chart","name":Chart.NodeName,"obj":Chart,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcCharts")
			,("field":"CatAx","name":CatAx.NodeName,"obj":CatAx,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcAxs")
			,("field":"ValAx","name":ValAx.NodeName,"obj":ValAx,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcAxs")
			,("field":"SerAx","name":SerAx.NodeName,"obj":SerAx,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcAxs")
			,("field":"SpPr","name":SpPr.NodeName,"obj":SpPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TspPr")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Layout;
	Chart;
	CatAx;
	ValAx;
	SerAx;
	SpPr;
End;

///////////////////////////////////////////////////////////////
/// TView3D
///////////////////////////////////////////////////////////////
type TView3D=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'c:view3D');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"RotX","name":"c:rotX","obj":RotX,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"RotY","name":"c:rotY","obj":RotY,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"RAngAx","name":"c:rAngAx","obj":RAngAx,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"DepthPercent","name":"c:depthPercent","obj":DepthPercent,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Perspective","name":"c:perspective","obj":Perspective,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	RotX;
	RotY;
	RAngAx;
	DepthPercent;
	Perspective;
End;

///////////////////////////////////////////////////////////////
/// TBorder
///////////////////////////////////////////////////////////////
type TBorder=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'border');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property Color read readXMLColor write writeXMLColor;
	Function readXMLColor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Color'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLColor);
	End;

	Function writeXMLColor(str);
	Begin
		XMLColor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ThemeColor read readXMLThemeColor write writeXMLThemeColor;
	Function readXMLThemeColor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ThemeColor'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLThemeColor);
	End;

	Function writeXMLThemeColor(str);
	Begin
		XMLThemeColor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ThemeColorTint read readXMLThemeColorTint write writeXMLThemeColorTint;
	Function readXMLThemeColorTint();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ThemeColorTint'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLThemeColorTint);
	End;

	Function writeXMLThemeColorTint(str);
	Begin
		XMLThemeColorTint := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property LineStyle read readXMLLineStyle write writeXMLLineStyle;
	Function readXMLLineStyle();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('LineStyle'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLLineStyle);
	End;

	Function writeXMLLineStyle(str);
	Begin
		XMLLineStyle := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("LineStyle", "style", XMLLineStyle, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Color","name":"color","obj":XMLColor,"attrEx":"rgb","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ThemeColor","name":"color","obj":XMLThemeColor,"attrEx":"theme","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ThemeColorTint","name":"color","obj":XMLThemeColorTint,"attrEx":"tint","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Weight","name":"weight","obj":Weight,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"TintAndShade","name":"tintandshade","obj":TintAndShade,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	XMLLineStyle;

	//Nodes
	XMLColor;
	XMLThemeColor;
	XMLThemeColorTint;
	Weight;
	TintAndShade;
End;

///////////////////////////////////////////////////////////////
/// TBorders
///////////////////////////////////////////////////////////////
type TBorders=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'border');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Left := new TBorder(self, 'left');
		Right := new TBorder(self, 'right');
		Top := new TBorder(self, 'top');
		Bottom := new TBorder(self, 'bottom');
		Diagonal := new TBorder(self, 'diagonal');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Left.InitRootNode(node);
		Right.InitRootNode(node);
		Top.InitRootNode(node);
		Bottom.InitRootNode(node);
		Diagonal.InitRootNode(node);
	End;

	Property DiagonalDown read readXMLDiagonalDown write writeXMLDiagonalDown;
	Function readXMLDiagonalDown();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('DiagonalDown'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLDiagonalDown);
	End;

	Function writeXMLDiagonalDown(str);
	Begin
		XMLDiagonalDown := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property DiagonalUp read readXMLDiagonalUp write writeXMLDiagonalUp;
	Function readXMLDiagonalUp();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('DiagonalUp'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLDiagonalUp);
	End;

	Function writeXMLDiagonalUp(str);
	Begin
		XMLDiagonalUp := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("DiagonalDown", "diagonalDown", XMLDiagonalDown, ""),("DiagonalUp", "diagonalUp", XMLDiagonalUp, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Left","name":Left.NodeName,"obj":Left,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TBorder")
			,("field":"Right","name":Right.NodeName,"obj":Right,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TBorder")
			,("field":"Top","name":Top.NodeName,"obj":Top,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TBorder")
			,("field":"Bottom","name":Bottom.NodeName,"obj":Bottom,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TBorder")
			,("field":"Diagonal","name":Diagonal.NodeName,"obj":Diagonal,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TBorder")
			) union ExtNodes;
	End;

	//Attributes
	XMLDiagonalDown;
	XMLDiagonalUp;

	//Nodes
	Left;
	Right;
	Top;
	Bottom;
	Diagonal;
End;

///////////////////////////////////////////////////////////////
/// TNumFmts
///////////////////////////////////////////////////////////////
type TNumFmts=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'numFmts');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property FormatCode read readXMLFormatCode write writeXMLFormatCode;
	Function readXMLFormatCode();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('FormatCode'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLFormatCode);
	End;

	Function writeXMLFormatCode(str);
	Begin
		XMLFormatCode := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("NumFmtId", "numFmtId", NumFmtId, ""),("FormatCode", "formatCode", XMLFormatCode, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	NumFmtId;
	XMLFormatCode;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TGradient
///////////////////////////////////////////////////////////////
type TGradient=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'gradientFill');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Stop1 := new TStop(self, 'stop');
		Stop2 := new TStop(self, 'stop');
		Stop3 := new TStop(self, 'stop');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Stop1.InitRootNode(node);
		Stop2.InitRootNode(node);
		Stop3.InitRootNode(node);
	End;

	Property Degree read readXMLDegree write writeXMLDegree;
	Function readXMLDegree();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Degree'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLDegree);
	End;

	Function writeXMLDegree(str);
	Begin
		XMLDegree := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Type read readXMLType write writeXMLType;
	Function readXMLType();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Type'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLType);
	End;

	Function writeXMLType(str);
	Begin
		XMLType := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Left read readXMLLeft write writeXMLLeft;
	Function readXMLLeft();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Left'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLLeft);
	End;

	Function writeXMLLeft(str);
	Begin
		XMLLeft := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Right read readXMLRight write writeXMLRight;
	Function readXMLRight();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Right'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLRight);
	End;

	Function writeXMLRight(str);
	Begin
		XMLRight := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Top read readXMLTop write writeXMLTop;
	Function readXMLTop();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Top'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLTop);
	End;

	Function writeXMLTop(str);
	Begin
		XMLTop := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Bottom read readXMLBottom write writeXMLBottom;
	Function readXMLBottom();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Bottom'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLBottom);
	End;

	Function writeXMLBottom(str);
	Begin
		XMLBottom := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Degree", "degree", XMLDegree, ""),("Type", "type", XMLType, ""),("Left", "left", XMLLeft, ""),("Right", "right", XMLRight, ""),("Top", "top", XMLTop, ""),("Bottom", "bottom", XMLBottom, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Stop1","name":Stop1.NodeName,"obj":Stop1,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TStop")
			,("field":"Stop2","name":Stop2.NodeName,"obj":Stop2,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TStop")
			,("field":"Stop3","name":Stop3.NodeName,"obj":Stop3,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TStop")
			) union ExtNodes;
	End;

	//Attributes
	XMLDegree;
	XMLType;
	XMLLeft;
	XMLRight;
	XMLTop;
	XMLBottom;

	//Nodes
	Stop1;
	Stop2;
	Stop3;
End;

///////////////////////////////////////////////////////////////
/// TFills
///////////////////////////////////////////////////////////////
type TFills=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'fill');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Pattern := new TPattern(self, 'patternFill');
		Gradient := new TGradient(self, 'gradientFill');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Pattern.InitRootNode(node);
		Gradient.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Pattern","name":Pattern.NodeName,"obj":Pattern,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TPattern")
			,("field":"Gradient","name":Gradient.NodeName,"obj":Gradient,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TGradient")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Pattern;
	Gradient;
End;

///////////////////////////////////////////////////////////////
/// TPattern
///////////////////////////////////////////////////////////////
type TPattern=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'patternFill');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property PatternType read readXMLPatternType write writeXMLPatternType;
	Function readXMLPatternType();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('PatternType'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLPatternType);
	End;

	Function writeXMLPatternType(str);
	Begin
		XMLPatternType := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ForegroundColor read readXMLForegroundColor write writeXMLForegroundColor;
	Function readXMLForegroundColor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ForegroundColor'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLForegroundColor);
	End;

	Function writeXMLForegroundColor(str);
	Begin
		XMLForegroundColor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property BackgroundColor read readXMLBackgroundColor write writeXMLBackgroundColor;
	Function readXMLBackgroundColor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('BackgroundColor'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLBackgroundColor);
	End;

	Function writeXMLBackgroundColor(str);
	Begin
		XMLBackgroundColor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ForegroundThemeColor read readXMLForegroundThemeColor write writeXMLForegroundThemeColor;
	Function readXMLForegroundThemeColor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ForegroundThemeColor'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLForegroundThemeColor);
	End;

	Function writeXMLForegroundThemeColor(str);
	Begin
		XMLForegroundThemeColor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property BackgroundThemeColor read readXMLBackgroundThemeColor write writeXMLBackgroundThemeColor;
	Function readXMLBackgroundThemeColor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('BackgroundThemeColor'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLBackgroundThemeColor);
	End;

	Function writeXMLBackgroundThemeColor(str);
	Begin
		XMLBackgroundThemeColor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ForegroundThemeColorTint read readXMLForegroundThemeColorTint write writeXMLForegroundThemeColorTint;
	Function readXMLForegroundThemeColorTint();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ForegroundThemeColorTint'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLForegroundThemeColorTint);
	End;

	Function writeXMLForegroundThemeColorTint(str);
	Begin
		XMLForegroundThemeColorTint := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property BackgroundThemeColorTint read readXMLBackgroundThemeColorTint write writeXMLBackgroundThemeColorTint;
	Function readXMLBackgroundThemeColorTint();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('BackgroundThemeColorTint'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLBackgroundThemeColorTint);
	End;

	Function writeXMLBackgroundThemeColorTint(str);
	Begin
		XMLBackgroundThemeColorTint := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("PatternType", "patternType", XMLPatternType, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"ForegroundColor","name":"fgColor","obj":XMLForegroundColor,"attrEx":"rgb","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"BackgroundColor","name":"bgColor","obj":XMLBackgroundColor,"attrEx":"rgb","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ForegroundThemeColor","name":"fgColor","obj":XMLForegroundThemeColor,"attrEx":"theme","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"BackgroundThemeColor","name":"bgColor","obj":XMLBackgroundThemeColor,"attrEx":"theme","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ForegroundThemeColorTint","name":"fgColor","obj":XMLForegroundThemeColorTint,"attrEx":"tint","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"BackgroundThemeColorTint","name":"bgColor","obj":XMLBackgroundThemeColorTint,"attrEx":"tint","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	XMLPatternType;

	//Nodes
	XMLForegroundColor;
	XMLBackgroundColor;
	XMLForegroundThemeColor;
	XMLBackgroundThemeColor;
	XMLForegroundThemeColorTint;
	XMLBackgroundThemeColorTint;
End;

///////////////////////////////////////////////////////////////
/// TStop
///////////////////////////////////////////////////////////////
type TStop=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'stop');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property Position read readXMLPosition write writeXMLPosition;
	Function readXMLPosition();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Position'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLPosition);
	End;

	Function writeXMLPosition(str);
	Begin
		XMLPosition := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Color read readXMLColor write writeXMLColor;
	Function readXMLColor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Color'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLColor);
	End;

	Function writeXMLColor(str);
	Begin
		XMLColor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ColorIndex read readXMLColorIndex write writeXMLColorIndex;
	Function readXMLColorIndex();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ColorIndex'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLColorIndex);
	End;

	Function writeXMLColorIndex(str);
	Begin
		XMLColorIndex := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ThemeColor read readXMLThemeColor write writeXMLThemeColor;
	Function readXMLThemeColor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ThemeColor'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLThemeColor);
	End;

	Function writeXMLThemeColor(str);
	Begin
		XMLThemeColor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ThemeColorTint read readXMLThemeColorTint write writeXMLThemeColorTint;
	Function readXMLThemeColorTint();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ThemeColorTint'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLThemeColorTint);
	End;

	Function writeXMLThemeColorTint(str);
	Begin
		XMLThemeColorTint := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Position", "position", XMLPosition, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Color","name":"color","obj":XMLColor,"attrEx":"rgb","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ColorIndex","name":"color","obj":XMLColorIndex,"attrEx":"index","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ThemeColor","name":"color","obj":XMLThemeColor,"attrEx":"theme","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ThemeColorTint","name":"color","obj":XMLThemeColorTint,"attrEx":"tint","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	XMLPosition;

	//Nodes
	XMLColor;
	XMLColorIndex;
	XMLThemeColor;
	XMLThemeColorTint;
End;

///////////////////////////////////////////////////////////////
/// TAlignment
///////////////////////////////////////////////////////////////
type TAlignment=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'alignment');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property Horizontal read readXMLHorizontal write writeXMLHorizontal;
	Function readXMLHorizontal();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Horizontal'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLHorizontal);
	End;

	Function writeXMLHorizontal(str);
	Begin
		XMLHorizontal := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Vertical read readXMLVertical write writeXMLVertical;
	Function readXMLVertical();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Vertical'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLVertical);
	End;

	Function writeXMLVertical(str);
	Begin
		XMLVertical := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property WrapText read readXMLWrapText write writeXMLWrapText;
	Function readXMLWrapText();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('WrapText'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLWrapText);
	End;

	Function writeXMLWrapText(str);
	Begin
		XMLWrapText := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ReadingOrder read readXMLReadingOrder write writeXMLReadingOrder;
	Function readXMLReadingOrder();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ReadingOrder'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLReadingOrder);
	End;

	Function writeXMLReadingOrder(str);
	Begin
		XMLReadingOrder := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property TextRotation read readXMLTextRotation write writeXMLTextRotation;
	Function readXMLTextRotation();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('TextRotation'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLTextRotation);
	End;

	Function writeXMLTextRotation(str);
	Begin
		XMLTextRotation := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Horizontal", "horizontal", XMLHorizontal, ""),("Vertical", "vertical", XMLVertical, ""),("WrapText", "wrapText", XMLWrapText, ""),("ReadingOrder", "readingOrder", XMLReadingOrder, ""),("TextRotation", "textRotation", XMLTextRotation, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	XMLHorizontal;
	XMLVertical;
	XMLWrapText;
	XMLReadingOrder;
	XMLTextRotation;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TProtection
///////////////////////////////////////////////////////////////
type TProtection=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'protection');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property Lock read readXMLLock write writeXMLLock;
	Function readXMLLock();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Lock'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLLock);
	End;

	Function writeXMLLock(str);
	Begin
		XMLLock := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Hide read readXMLHide write writeXMLHide;
	Function readXMLHide();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Hide'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLHide);
	End;

	Function writeXMLHide(str);
	Begin
		XMLHide := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Lock", "locked", XMLLock, ""),("Hide", "hidden", XMLHide, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	XMLLock;
	XMLHide;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TStyle
///////////////////////////////////////////////////////////////
type TStyle=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'xf');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Border := new TBorders(self, 'border');
		Font := new TFont(self, 'font');
		NumberFormat := new TNumFmts(self, 'numFmt');
		Fill := new TFills(self, 'fill');
		Alignment := new TAlignment(self, 'alignment');
		Protection := new TProtection(self, 'protection');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Border.InitRootNode(node);
		Font.InitRootNode(node);
		NumberFormat.InitRootNode(node);
		Fill.InitRootNode(node);
		Alignment.InitRootNode(node);
		Protection.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Border","name":Border.NodeName,"obj":Border,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TBorders")
			,("field":"Font","name":Font.NodeName,"obj":Font,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TFont")
			,("field":"NumberFormat","name":NumberFormat.NodeName,"obj":NumberFormat,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TNumFmts")
			,("field":"Fill","name":Fill.NodeName,"obj":Fill,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TFills")
			,("field":"Alignment","name":Alignment.NodeName,"obj":Alignment,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TAlignment")
			,("field":"Protection","name":Protection.NodeName,"obj":Protection,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TProtection")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Border;
	Font;
	NumberFormat;
	Fill;
	Alignment;
	Protection;
End;

///////////////////////////////////////////////////////////////
/// TXf
///////////////////////////////////////////////////////////////
type TXf=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'xf');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Alignment := new TAlignment(self, 'alignment');
		Protection := new TProtection(self, 'protection');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Alignment.InitRootNode(node);
		Protection.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("NumFmtId", "numFmtId", NumFmtId, ""),("FontId", "fontId", FontId, ""),("FillId", "fillId", FillId, ""),("BorderId", "borderId", BorderId, ""),("XfId", "xfId", XfId, ""),("ApplyFont", "applyFont", ApplyFont, ""),("ApplyFill", "applyFill", ApplyFill, ""),("ApplyBorder", "applyBorder", ApplyBorder, ""),("ApplyAlignment", "applyAlignment", ApplyAlignment, ""),("ApplyProtection", "applyProtection", ApplyProtection, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Alignment","name":Alignment.NodeName,"obj":Alignment,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TAlignment")
			,("field":"Protection","name":Protection.NodeName,"obj":Protection,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TProtection")
			) union ExtNodes;
	End;

	//Attributes
	NumFmtId;
	FontId;
	FillId;
	BorderId;
	XfId;
	ApplyFont;
	ApplyFill;
	ApplyBorder;
	ApplyAlignment;
	ApplyProtection;

	//Nodes
	Alignment;
	Protection;
End;

///////////////////////////////////////////////////////////////
/// THeaderFooter
///////////////////////////////////////////////////////////////
type THeaderFooter=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'headerFooter');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("DifferentOddEven", "differentOddEven", DifferentOddEven, ""),("DifferentFirst", "differentFirst", DifferentFirst, ""),("ScaleWithDoc", "scaleWithDoc", ScaleWithDoc, ""),("AlignWithMargin", "alignWithMargins", AlignWithMargin, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"OddHeader","name":"oddHeader","obj":OddHeader,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"OddFooter","name":"oddFooter","obj":OddFooter,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"EvenHeader","name":"evenHeader","obj":EvenHeader,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"EvenFooter","name":"evenFooter","obj":EvenFooter,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"FirstHeader","name":"firstHeader","obj":FirstHeader,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"FirstFooter","name":"firstFooter","obj":FirstFooter,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	DifferentOddEven;
	DifferentFirst;
	ScaleWithDoc;
	AlignWithMargin;

	//Nodes
	OddHeader;
	OddFooter;
	EvenHeader;
	EvenFooter;
	FirstHeader;
	FirstFooter;
End;

///////////////////////////////////////////////////////////////
/// TMargins
///////////////////////////////////////////////////////////////
type TMargins=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'pageMargins');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property Left read readXMLLeft write writeXMLLeft;
	Function readXMLLeft();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Left'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLLeft);
	End;

	Function writeXMLLeft(str);
	Begin
		XMLLeft := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Right read readXMLRight write writeXMLRight;
	Function readXMLRight();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Right'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLRight);
	End;

	Function writeXMLRight(str);
	Begin
		XMLRight := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Top read readXMLTop write writeXMLTop;
	Function readXMLTop();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Top'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLTop);
	End;

	Function writeXMLTop(str);
	Begin
		XMLTop := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Bottom read readXMLBottom write writeXMLBottom;
	Function readXMLBottom();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Bottom'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLBottom);
	End;

	Function writeXMLBottom(str);
	Begin
		XMLBottom := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Header read readXMLHeader write writeXMLHeader;
	Function readXMLHeader();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Header'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLHeader);
	End;

	Function writeXMLHeader(str);
	Begin
		XMLHeader := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Footer read readXMLFooter write writeXMLFooter;
	Function readXMLFooter();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Footer'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLFooter);
	End;

	Function writeXMLFooter(str);
	Begin
		XMLFooter := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Left", "left", XMLLeft, ""),("Right", "right", XMLRight, ""),("Top", "top", XMLTop, ""),("Bottom", "bottom", XMLBottom, ""),("Header", "header", XMLHeader, ""),("Footer", "footer", XMLFooter, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	XMLLeft;
	XMLRight;
	XMLTop;
	XMLBottom;
	XMLHeader;
	XMLFooter;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// THyperLink
///////////////////////////////////////////////////////////////
type THyperLink=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'hyperlink');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property LinkUrl read readXMLLinkUrl write writeXMLLinkUrl;
	Function readXMLLinkUrl();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('LinkUrl'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLLinkUrl);
	End;

	Function writeXMLLinkUrl(str);
	Begin
		XMLLinkUrl := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Display read readXMLDisplay write writeXMLDisplay;
	Function readXMLDisplay();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Display'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLDisplay);
	End;

	Function writeXMLDisplay(str);
	Begin
		XMLDisplay := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Tooltip read readXMLTooltip write writeXMLTooltip;
	Function readXMLTooltip();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Tooltip'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLTooltip);
	End;

	Function writeXMLTooltip(str);
	Begin
		XMLTooltip := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Location read readXMLLocation write writeXMLLocation;
	Function readXMLLocation();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Location'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLLocation);
	End;

	Function writeXMLLocation(str);
	Begin
		XMLLocation := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("LinkType", "linkType", LinkType, ""),("LinkUrl", "linkUrl", XMLLinkUrl, ""),("Axis", "ref", Axis, ""),("Display", "display", XMLDisplay, ""),("Tooltip", "tooltip", XMLTooltip, ""),("RId", "r:id", RId, ""),("Location", "location", XMLLocation, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	LinkType;
	XMLLinkUrl;
	Axis;
	XMLDisplay;
	XMLTooltip;
	RId;
	XMLLocation;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TSheetView
///////////////////////////////////////////////////////////////
type TSheetView=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'sheetView');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property ShowGridLines read readXMLShowGridLines write writeXMLShowGridLines;
	Function readXMLShowGridLines();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ShowGridLines'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLShowGridLines);
	End;

	Function writeXMLShowGridLines(str);
	Begin
		XMLShowGridLines := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ShowRowColHeaders read readXMLShowRowColHeaders write writeXMLShowRowColHeaders;
	Function readXMLShowRowColHeaders();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ShowRowColHeaders'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLShowRowColHeaders);
	End;

	Function writeXMLShowRowColHeaders(str);
	Begin
		XMLShowRowColHeaders := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property TabSelected read readXMLTabSelected write writeXMLTabSelected;
	Function readXMLTabSelected();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('TabSelected'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLTabSelected);
	End;

	Function writeXMLTabSelected(str);
	Begin
		XMLTabSelected := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property View read readXMLView write writeXMLView;
	Function readXMLView();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('View'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLView);
	End;

	Function writeXMLView(str);
	Begin
		XMLView := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ZoomScale read readXMLZoomScale write writeXMLZoomScale;
	Function readXMLZoomScale();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ZoomScale'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLZoomScale);
	End;

	Function writeXMLZoomScale(str);
	Begin
		XMLZoomScale := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ZoomScaleNormal read readXMLZoomScaleNormal write writeXMLZoomScaleNormal;
	Function readXMLZoomScaleNormal();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ZoomScaleNormal'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLZoomScaleNormal);
	End;

	Function writeXMLZoomScaleNormal(str);
	Begin
		XMLZoomScaleNormal := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property WorkbookViewId read readXMLWorkbookViewId write writeXMLWorkbookViewId;
	Function readXMLWorkbookViewId();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('WorkbookViewId'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLWorkbookViewId);
	End;

	Function writeXMLWorkbookViewId(str);
	Begin
		XMLWorkbookViewId := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("ShowGridLines", "showGridLines", XMLShowGridLines, ""),("ShowRowColHeaders", "showRowColHeaders", XMLShowRowColHeaders, ""),("TabSelected", "tabSelected", XMLTabSelected, ""),("View", "view", XMLView, ""),("ZoomScale", "zoomScale", XMLZoomScale, ""),("ZoomScaleNormal", "zoomScaleNormal", XMLZoomScaleNormal, ""),("WorkbookViewId", "workbookViewId", XMLWorkbookViewId, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	XMLShowGridLines;
	XMLShowRowColHeaders;
	XMLTabSelected;
	XMLView;
	XMLZoomScale;
	XMLZoomScaleNormal;
	XMLWorkbookViewId;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TPane
///////////////////////////////////////////////////////////////
type TPane=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'pane');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property XSplit read readXMLXSplit write writeXMLXSplit;
	Function readXMLXSplit();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('XSplit'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLXSplit);
	End;

	Function writeXMLXSplit(str);
	Begin
		XMLXSplit := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property YSplit read readXMLYSplit write writeXMLYSplit;
	Function readXMLYSplit();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('YSplit'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLYSplit);
	End;

	Function writeXMLYSplit(str);
	Begin
		XMLYSplit := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property TopLeftCell read readXMLTopLeftCell write writeXMLTopLeftCell;
	Function readXMLTopLeftCell();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('TopLeftCell'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLTopLeftCell);
	End;

	Function writeXMLTopLeftCell(str);
	Begin
		XMLTopLeftCell := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ActivePane read readXMLActivePane write writeXMLActivePane;
	Function readXMLActivePane();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ActivePane'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLActivePane);
	End;

	Function writeXMLActivePane(str);
	Begin
		XMLActivePane := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property State read readXMLState write writeXMLState;
	Function readXMLState();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('State'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLState);
	End;

	Function writeXMLState(str);
	Begin
		XMLState := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("XSplit", "xSplit", XMLXSplit, ""),("YSplit", "ySplit", XMLYSplit, ""),("TopLeftCell", "topLeftCell", XMLTopLeftCell, ""),("ActivePane", "activePane", XMLActivePane, ""),("State", "state", XMLState, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	XMLXSplit;
	XMLYSplit;
	XMLTopLeftCell;
	XMLActivePane;
	XMLState;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TSelection
///////////////////////////////////////////////////////////////
type TSelection=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'selection');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property Pane read readXMLPane write writeXMLPane;
	Function readXMLPane();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Pane'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLPane);
	End;

	Function writeXMLPane(str);
	Begin
		XMLPane := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ActiveCell read readXMLActiveCell write writeXMLActiveCell;
	Function readXMLActiveCell();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ActiveCell'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLActiveCell);
	End;

	Function writeXMLActiveCell(str);
	Begin
		XMLActiveCell := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Sqref read readXMLSqref write writeXMLSqref;
	Function readXMLSqref();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Sqref'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLSqref);
	End;

	Function writeXMLSqref(str);
	Begin
		XMLSqref := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Pane", "pane", XMLPane, ""),("ActiveCell", "activeCell", XMLActiveCell, ""),("Sqref", "sqref", XMLSqref, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	XMLPane;
	XMLActiveCell;
	XMLSqref;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TPageLayout
///////////////////////////////////////////////////////////////
type TPageLayout=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'pageSetup');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("PaperSize", "paperSize", PaperSize, ""),("Scale", "scale", Scale, ""),("FitToWidth", "fitToWidth", FitToWidth, ""),("FitToHeight", "fitToHeight", FitToHeight, ""),("UseFirstPageNumber", "cellComments", UseFirstPageNumber, ""),("FirstPageNumber", "firstPageNumber", FirstPageNumber, ""),("PageOrder", "pageOrder", PageOrder, ""),("Orientation", "orientation", Orientation, ""),("BlackAndWhite", "blackAndWhite", BlackAndWhite, ""),("Draft", "draft", Draft, ""),("CellComments", "cellComments", CellComments, ""),("CellError", "errors", CellError, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	PaperSize;
	Scale;
	FitToWidth;
	FitToHeight;
	UseFirstPageNumber;
	FirstPageNumber;
	PageOrder;
	Orientation;
	BlackAndWhite;
	Draft;
	CellComments;
	CellError;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TAppProperty
///////////////////////////////////////////////////////////////
type TAppProperty=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'Properties');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property Application read readXMLApplication write writeXMLApplication;
	Function readXMLApplication();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Application'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLApplication);
	End;

	Function writeXMLApplication(str);
	Begin
		XMLApplication := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property DocSecurity read readXMLDocSecurity write writeXMLDocSecurity;
	Function readXMLDocSecurity();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('DocSecurity'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLDocSecurity);
	End;

	Function writeXMLDocSecurity(str);
	Begin
		XMLDocSecurity := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ScaleCrop read readXMLScaleCrop write writeXMLScaleCrop;
	Function readXMLScaleCrop();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ScaleCrop'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLScaleCrop);
	End;

	Function writeXMLScaleCrop(str);
	Begin
		XMLScaleCrop := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Manager read readXMLManager write writeXMLManager;
	Function readXMLManager();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Manager'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLManager);
	End;

	Function writeXMLManager(str);
	Begin
		XMLManager := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Company read readXMLCompany write writeXMLCompany;
	Function readXMLCompany();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Company'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLCompany);
	End;

	Function writeXMLCompany(str);
	Begin
		XMLCompany := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property LinksUpToDate read readXMLLinksUpToDate write writeXMLLinksUpToDate;
	Function readXMLLinksUpToDate();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('LinksUpToDate'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLLinksUpToDate);
	End;

	Function writeXMLLinksUpToDate(str);
	Begin
		XMLLinksUpToDate := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property SharedDoc read readXMLSharedDoc write writeXMLSharedDoc;
	Function readXMLSharedDoc();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('SharedDoc'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLSharedDoc);
	End;

	Function writeXMLSharedDoc(str);
	Begin
		XMLSharedDoc := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property HyperlinkBase read readXMLHyperlinkBase write writeXMLHyperlinkBase;
	Function readXMLHyperlinkBase();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('HyperlinkBase'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLHyperlinkBase);
	End;

	Function writeXMLHyperlinkBase(str);
	Begin
		XMLHyperlinkBase := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property HyperlinksChanged read readXMLHyperlinksChanged write writeXMLHyperlinksChanged;
	Function readXMLHyperlinksChanged();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('HyperlinksChanged'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLHyperlinksChanged);
	End;

	Function writeXMLHyperlinksChanged(str);
	Begin
		XMLHyperlinksChanged := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Version read readXMLVersion write writeXMLVersion;
	Function readXMLVersion();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Version'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLVersion);
	End;

	Function writeXMLVersion(str);
	Begin
		XMLVersion := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Application","name":"Application","obj":XMLApplication,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"DocSecurity","name":"DocSecurity","obj":XMLDocSecurity,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"ScaleCrop","name":"ScaleCrop","obj":XMLScaleCrop,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Manager","name":"Manager","obj":XMLManager,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Company","name":"Company","obj":XMLCompany,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"LinksUpToDate","name":"LinksUpToDate","obj":XMLLinksUpToDate,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"SharedDoc","name":"SharedDoc","obj":XMLSharedDoc,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"HyperlinkBase","name":"HyperlinkBase","obj":XMLHyperlinkBase,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"HyperlinksChanged","name":"HyperlinksChanged","obj":XMLHyperlinksChanged,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Version","name":"AppVersion","obj":XMLVersion,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	XMLApplication;
	XMLDocSecurity;
	XMLScaleCrop;
	XMLManager;
	XMLCompany;
	XMLLinksUpToDate;
	XMLSharedDoc;
	XMLHyperlinkBase;
	XMLHyperlinksChanged;
	XMLVersion;
End;

///////////////////////////////////////////////////////////////
/// TCoreProperty
///////////////////////////////////////////////////////////////
type TCoreProperty=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'cp:coreProperties');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property Title read readXMLTitle write writeXMLTitle;
	Function readXMLTitle();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Title'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLTitle);
	End;

	Function writeXMLTitle(str);
	Begin
		XMLTitle := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Subject read readXMLSubject write writeXMLSubject;
	Function readXMLSubject();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Subject'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLSubject);
	End;

	Function writeXMLSubject(str);
	Begin
		XMLSubject := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Creator read readXMLCreator write writeXMLCreator;
	Function readXMLCreator();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Creator'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLCreator);
	End;

	Function writeXMLCreator(str);
	Begin
		XMLCreator := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Keywords read readXMLKeywords write writeXMLKeywords;
	Function readXMLKeywords();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Keywords'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLKeywords);
	End;

	Function writeXMLKeywords(str);
	Begin
		XMLKeywords := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Description read readXMLDescription write writeXMLDescription;
	Function readXMLDescription();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Description'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLDescription);
	End;

	Function writeXMLDescription(str);
	Begin
		XMLDescription := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property LastModifiedBy read readXMLLastModifiedBy write writeXMLLastModifiedBy;
	Function readXMLLastModifiedBy();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('LastModifiedBy'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLLastModifiedBy);
	End;

	Function writeXMLLastModifiedBy(str);
	Begin
		XMLLastModifiedBy := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property LastPrinted read readXMLLastPrinted write writeXMLLastPrinted;
	Function readXMLLastPrinted();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('LastPrinted'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLLastPrinted);
	End;

	Function writeXMLLastPrinted(str);
	Begin
		XMLLastPrinted := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Category read readXMLCategory write writeXMLCategory;
	Function readXMLCategory();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Category'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLCategory);
	End;

	Function writeXMLCategory(str);
	Begin
		XMLCategory := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ContentStatus read readXMLContentStatus write writeXMLContentStatus;
	Function readXMLContentStatus();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ContentStatus'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLContentStatus);
	End;

	Function writeXMLContentStatus(str);
	Begin
		XMLContentStatus := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Title","name":"dc:title","obj":XMLTitle,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Subject","name":"dc:subject","obj":XMLSubject,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Creator","name":"dc:creator","obj":XMLCreator,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Keywords","name":"cp:keywords","obj":XMLKeywords,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Description","name":"dc:description","obj":XMLDescription,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"LastModifiedBy","name":"cp:lastModifiedBy","obj":XMLLastModifiedBy,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"LastPrinted","name":"cp:lastPrinted","obj":XMLLastPrinted,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Category","name":"cp:category","obj":XMLCategory,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"ContentStatus","name":"cp:contentStatus","obj":XMLContentStatus,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	XMLTitle;
	XMLSubject;
	XMLCreator;
	XMLKeywords;
	XMLDescription;
	XMLLastModifiedBy;
	XMLLastPrinted;
	XMLCategory;
	XMLContentStatus;
End;

///////////////////////////////////////////////////////////////
/// TBr
///////////////////////////////////////////////////////////////
type TBr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:br');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Type", "w:type", Type, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Type;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TwFont
///////////////////////////////////////////////////////////////
type TwFont=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:rFonts');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property eastAsia read readXMLeastAsia write writeXMLeastAsia;
	Function readXMLeastAsia();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('eastAsia'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLeastAsia);
	End;

	Function writeXMLeastAsia(str);
	Begin
		XMLeastAsia := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property eastAsiaTheme read readXMLeastAsiaTheme write writeXMLeastAsiaTheme;
	Function readXMLeastAsiaTheme();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('eastAsiaTheme'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLeastAsiaTheme);
	End;

	Function writeXMLeastAsiaTheme(str);
	Begin
		XMLeastAsiaTheme := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property hAnsi read readXMLhAnsi write writeXMLhAnsi;
	Function readXMLhAnsi();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('hAnsi'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLhAnsi);
	End;

	Function writeXMLhAnsi(str);
	Begin
		XMLhAnsi := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property hAnsiTheme read readXMLhAnsiTheme write writeXMLhAnsiTheme;
	Function readXMLhAnsiTheme();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('hAnsiTheme'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLhAnsiTheme);
	End;

	Function writeXMLhAnsiTheme(str);
	Begin
		XMLhAnsiTheme := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property hint read readXMLhint write writeXMLhint;
	Function readXMLhint();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('hint'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLhint);
	End;

	Function writeXMLhint(str);
	Begin
		XMLhint := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ascii read readXMLascii write writeXMLascii;
	Function readXMLascii();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ascii'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLascii);
	End;

	Function writeXMLascii(str);
	Begin
		XMLascii := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property asciiTheme read readXMLasciiTheme write writeXMLasciiTheme;
	Function readXMLasciiTheme();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('asciiTheme'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLasciiTheme);
	End;

	Function writeXMLasciiTheme(str);
	Begin
		XMLasciiTheme := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property cs read readXMLcs write writeXMLcs;
	Function readXMLcs();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('cs'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLcs);
	End;

	Function writeXMLcs(str);
	Begin
		XMLcs := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property csTheme read readXMLcsTheme write writeXMLcsTheme;
	Function readXMLcsTheme();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('csTheme'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLcsTheme);
	End;

	Function writeXMLcsTheme(str);
	Begin
		XMLcsTheme := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("eastAsia", "w:eastAsia", XMLeastAsia, "东亚字体"),("eastAsiaTheme", "w:eastAsiaTheme", XMLeastAsiaTheme, "东亚主题字体"),("hAnsi", "w:hAnsi", XMLhAnsi, "Unicode范围内的所有字符（该范围不属于上面定义的三个类别之一）字体."),("hAnsiTheme", "w:hAnsiTheme", XMLhAnsiTheme, "Unicode范围内的所有字符（该范围不属于上面定义的三个类别之一）主题字体. "),("hint", "w:hint", XMLhint, "指定用于设置当前运行中任何不明确字符格式的字体类型."),("ascii", "w:ascii", XMLascii, "ASCII range (0 - 127) 字体."),("asciiTheme", "w:asciiTheme", XMLasciiTheme, "ASCII range (0 - 127) 主题字体."),("cs", "w:cs", XMLcs, "字体：格式化复杂脚本Unicode范围内的所有字符."),("csTheme", "w:csTheme", XMLcsTheme, "主题字体：格式化复杂脚本Unicode范围内的所有字符. ")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	XMLeastAsia;
	XMLeastAsiaTheme;
	XMLhAnsi;
	XMLhAnsiTheme;
	XMLhint;
	XMLascii;
	XMLasciiTheme;
	XMLcs;
	XMLcsTheme;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TwrPr
///////////////////////////////////////////////////////////////
type TwrPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:rPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		rFont := new TwFont(self, 'w:rFonts');
		Del := new TOptInfo(self, 'w:del');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		rFont.InitRootNode(node);
		Del.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"rFont","name":rFont.NodeName,"obj":rFont,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TwFont")
			,("field":"Bold","name":"w:b","obj":Bold,"attrEx":"w:val","nodeType":"empty","attrName":"", "desc":"黑体", "class":"")
			,("field":"noProof","name":"w:noProof","obj":noProof,"attrEx":"","nodeType":"empty","attrName":"", "desc":"不检查拼写或语法)", "class":"")
			,("field":"Color","name":"w:color","obj":Color,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"字体颜色", "class":"")
			,("field":"bCs","name":"w:bCs","obj":bCs,"attrEx":"w:val","nodeType":"empty","attrName":"", "desc":"复杂脚本黑体", "class":"")
			,("field":"Italic","name":"w:i","obj":Italic,"attrEx":"","nodeType":"empty","attrName":"", "desc":"斜体", "class":"")
			,("field":"Strike","name":"w:strike","obj":Strike,"attrEx":"","nodeType":"empty","attrName":"", "desc":"单个删除线", "class":"")
			,("field":"dStrike","name":"w:dstrike","obj":dStrike,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"两个删除线", "class":"")
			,("field":"kern","name":"w:kern","obj":kern,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"字体紧排", "class":"")
			,("field":"Sz","name":"w:sz","obj":Sz,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"字体大小", "class":"")
			,("field":"szCs","name":"w:szCs","obj":szCs,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"复杂脚本字体大小", "class":"")
			,("field":"U","name":"w:u","obj":U,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"下划线", "class":"")
			,("field":"vertAlign","name":"w:vertAlign","obj":vertAlign,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"对齐方式.", "class":"")
			,("field":"eastAsia","name":"w:lang","obj":eastAsia,"attrEx":"w:eastAsia","nodeType":"","attrName":"", "desc":"处理使用东亚字符的运行内容时应使用的语言.", "class":"")
			,("field":"Lang","name":"w:lang","obj":Lang,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"处理使用拉丁字符的本次运行内容时用于检查拼写和语法的语言.", "class":"")
			,("field":"bidi","name":"w:lang","obj":bidi,"attrEx":"w:bidi","nodeType":"","attrName":"", "desc":"处理使用复杂脚本字符的运行内容时应使用的语言.", "class":"")
			,("field":"Del","name":Del.NodeName,"obj":Del,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TOptInfo")
			,("field":"StyleId","name":"w:rStyle","obj":StyleId,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"WebHidden","name":"w:webHidden","obj":WebHidden,"attrEx":"w:val","nodeType":"empty","attrName":"", "desc":"disable", "class":"")
			) union ExtNodes;
	End;

	Property Name write writeName;
	Function writeName(n);
	Begin
		SetName(n, false);
	End;
	
	Function SetName(n, isUtf8);
	Begin
		nName := n;
		if not isUtf8 then
			nName := class(TSXml).CurCodePageToUtf8(n);
		rFont.XMLcs := nName;
		rFont.XMLeastAsia := nName;
		rFont.XMLhAnsi := nName;
		rFont.XMLascii := nName;
	End;
	
	Property Size read readSize write writeSize;
	Function writeSize(n);
	Begin
		Sz := n * 2;
	End;
	Function readSize();
	Begin
		return int(Sz / 2);
	End;

	//Attributes

	//Nodes
	rFont;
	Bold;
	noProof;
	Color;
	bCs;
	Italic;
	Strike;
	dStrike;
	kern;
	Sz;
	szCs;
	U;
	vertAlign;
	eastAsia;
	Lang;
	bidi;
	Del;
	StyleId;
	WebHidden;
End;

///////////////////////////////////////////////////////////////
/// TNumPr
///////////////////////////////////////////////////////////////
type TNumPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:numPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Level","name":"w:ilvl","obj":Level,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"项目层级", "class":"")
			,("field":"numId","name":"w:numId","obj":numId,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"项目编号ID", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Level;
	numId;
End;

///////////////////////////////////////////////////////////////
/// TTextBoxImpl
///////////////////////////////////////////////////////////////
type TTextBoxImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:txbxContent');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		P := new TParagraphImpl(self, 'P');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		P.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"P","name":P.NodeName,"obj":P,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TParagraphImpl")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	P;
End;

///////////////////////////////////////////////////////////////
/// TWHyperLinkImpl
///////////////////////////////////////////////////////////////
type TWHyperLinkImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:hyperlink');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Anchor", "w:anchor", Anchor, ""),("History", "w:history", History, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Anchor;
	History;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TwpPr
///////////////////////////////////////////////////////////////
type TwpPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:pPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		NumPr := new TNumPr(self, 'w:numPr');
		Tabs := new TTabStops(self, 'w:tabs');
		rPr := new TwrPr(self, 'w:rPr');
		Bdr := new TpBdr(self, 'w:pBdr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		NumPr.InitRootNode(node);
		Tabs.InitRootNode(node);
		rPr.InitRootNode(node);
		Bdr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"StyleId","name":"w:pStyle","obj":StyleId,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"段落样式ID", "class":"")
			,("field":"NumPr","name":NumPr.NodeName,"obj":NumPr,"attrEx":"","nodeType":"","attrName":"", "desc":"项目编号、数字编号", "class":"TNumPr")
			,("field":"Alignment","name":"w:jc","obj":Alignment,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"左、右、居中和对齐", "class":"")
			,("field":"FirstLineChars","name":"w:ind","obj":FirstLineChars,"attrEx":"w:firstLineChars","nodeType":"","attrName":"", "desc":"字符单位中的其他首行缩进", "class":"")
			,("field":"FirstLineIndent","name":"w:ind","obj":FirstLineIndent,"attrEx":"w:firstLine","nodeType":"","attrName":"", "desc":"指定段落第一行缩进的相对差异的值", "class":"")
			,("field":"RightChars","name":"w:ind","obj":RightChars,"attrEx":"w:rightChars","nodeType":"","attrName":"", "desc":"字符单位中的右缩进", "class":"")
			,("field":"RightIndent","name":"w:ind","obj":RightIndent,"attrEx":"w:right","nodeType":"","attrName":"", "desc":"指定段落的右边距和右边距之间的间距", "class":"")
			,("field":"LeftChars","name":"w:ind","obj":LeftChars,"attrEx":"w:leftChars","nodeType":"","attrName":"", "desc":"字符单位中的左缩进", "class":"")
			,("field":"LeftIndent","name":"w:ind","obj":LeftIndent,"attrEx":"w:left","nodeType":"","attrName":"", "desc":"当前文档中第一段的左缩进值", "class":"")
			,("field":"StartIndent","name":"w:ind","obj":StartIndent,"attrEx":"w:start","nodeType":"","attrName":"", "desc":"w:start 控制从左到右段落的左缩进或从右到左段落的右缩进，w:end 控制另一边", "class":"")
			,("field":"EndIndent","name":"w:ind","obj":EndIndent,"attrEx":"w:end","nodeType":"","attrName":"", "desc":"w:start 控制从左到右段落的左缩进或从右到左段落的右缩进，w:end 控制另一边", "class":"")
			,("field":"HangingChars","name":"w:ind","obj":HangingChars,"attrEx":"w:hangingChars","nodeType":"","attrName":"", "desc":"从字符单位的第一行中删除的缩进", "class":"")
			,("field":"Hanging","name":"w:ind","obj":Hanging,"attrEx":"w:hanging","nodeType":"","attrName":"", "desc":"从第一行中删除的缩进", "class":"")
			,("field":"LineSpacingRule","name":"w:spacing","obj":LineSpacingRule,"attrEx":"w:lineRule","nodeType":"","attrName":"", "desc":"该枚举指示 LineSpacing 应该被解释", "class":"")
			,("field":"LineSpacing","name":"w:spacing","obj":LineSpacing,"attrEx":"w:line","nodeType":"","attrName":"", "desc":"当前文档中第一段的行距", "class":"")
			,("field":"AfterLines","name":"w:spacing","obj":AfterLines,"attrEx":"w:afterLines","nodeType":"","attrName":"", "desc":"段落下方的间距（以行单位为单位）", "class":"")
			,("field":"SpaceAfter","name":"w:spacing","obj":SpaceAfter,"attrEx":"w:after","nodeType":"","attrName":"", "desc":"当前文档中第一段的段后间距", "class":"")
			,("field":"BeforeLines","name":"w:spacing","obj":BeforeLines,"attrEx":"w:beforeLines","nodeType":"","attrName":"", "desc":"段落上方的间距（以行单位为单位）行单位", "class":"")
			,("field":"SpaceBefore","name":"w:spacing","obj":SpaceBefore,"attrEx":"w:before","nodeType":"","attrName":"", "desc":"当前文档中第一段的段前间距", "class":"")
			,("field":"OutlineLevel","name":"w:outlineLvl","obj":OutlineLevel,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"设置当前文档中第一段的大纲级别", "class":"")
			,("field":"KeepTogether","name":"w:keepLines","obj":KeepTogether,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"段落是否应保持完整且不应跨越页面边界", "class":"")
			,("field":"KeepWithNext","name":"w:keepNext","obj":KeepWithNext,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"该段是否应与下一段保持在同一页上", "class":"")
			,("field":"PageBreakBefore","name":"w:pageBreakBefore","obj":PageBreakBefore,"attrEx":"","nodeType":"empty","attrName":"", "desc":"该段该段出现在前一段之后的页面顶部", "class":"")
			,("field":"WidowControl","name":"w:widowControl","obj":WidowControl,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"当Word对文档重新分页时，如果段落中的第一行和最后一行与段落的其余部分保持在同一页上", "class":"")
			,("field":"TextAlignment","name":"w:textAlignment","obj":TextAlignment,"attrEx":"","nodeType":"empty","attrName":"", "desc":"该值指示文本内容的水平对齐方式", "class":"")
			,("field":"AdjustRightInd","name":"w:adjustRightInd","obj":AdjustRightInd,"attrEx":"","nodeType":"empty","attrName":"", "desc":"使用文档网格时自动调整右缩进", "class":"")
			,("field":"AutoSpaceDE","name":"w:autoSpaceDE","obj":AutoSpaceDE,"attrEx":"","nodeType":"empty","attrName":"", "desc":"自动调整拉丁语和东亚文本的间距", "class":"")
			,("field":"AutoSpaceDN","name":"w:autoSpaceDN","obj":AutoSpaceDN,"attrEx":"","nodeType":"empty","attrName":"", "desc":"自动调整东亚文本和数字的间距", "class":"")
			,("field":"Tabs","name":Tabs.NodeName,"obj":Tabs,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TTabStops")
			,("field":"rPr","name":rPr.NodeName,"obj":rPr,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TwrPr")
			,("field":"cnfStyle","name":"w:cnfStyle","obj":cnfStyle,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"段落条件格式：此元素指定格式属性的已应用于此段落，如果该段落包含在表格单元格的条件的表格样式的集。https://learn.microsoft.com/zh-cn/dotnet/api/documentformat.openxml.wordprocessing.conditionalformatstyle?view=openxml-2.8.1", "class":"")
			,("field":"textFlow","name":"w:textFlow","obj":textFlow,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"Bdr","name":Bdr.NodeName,"obj":Bdr,"attrEx":"","nodeType":"","attrName":"", "desc":"文字边框", "class":"TpBdr")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	StyleId;
	NumPr;
	Alignment;
	FirstLineChars;
	FirstLineIndent;
	RightChars;
	RightIndent;
	LeftChars;
	LeftIndent;
	StartIndent;
	EndIndent;
	HangingChars;
	Hanging;
	LineSpacingRule;
	LineSpacing;
	AfterLines;
	SpaceAfter;
	BeforeLines;
	SpaceBefore;
	OutlineLevel;
	KeepTogether;
	KeepWithNext;
	PageBreakBefore;
	WidowControl;
	TextAlignment;
	AdjustRightInd;
	AutoSpaceDE;
	AutoSpaceDN;
	Tabs;
	rPr;
	cnfStyle;
	textFlow;
	Bdr;
End;

///////////////////////////////////////////////////////////////
/// TcNvGraphicFramePr
///////////////////////////////////////////////////////////////
type TcNvGraphicFramePr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'wp:TcNvGraphicFramePr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"noChangeAspect","name":"a:graphicFrameLocks","obj":noChangeAspect,"attrEx":"noChangeAspect","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"xmlns","name":"a:graphicFrameLocks","obj":xmlns,"attrEx":"xmlns:a","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	noChangeAspect;
	xmlns;
End;

///////////////////////////////////////////////////////////////
/// TnvPicPr
///////////////////////////////////////////////////////////////
type TnvPicPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'pic:nvPicPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		CNvPr := new TCNvPr(self, 'pic:cNvPr');
		CNvPicPr := new TcNvPicPr(self, 'xdr:cNvPicPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		CNvPr.InitRootNode(node);
		CNvPicPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"CNvPr","name":CNvPr.NodeName,"obj":CNvPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TCNvPr")
			,("field":"CNvPicPr","name":CNvPicPr.NodeName,"obj":CNvPicPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcNvPicPr")
			,("field":"CNvSpPr","name":"xdr:cNvSpPr","obj":CNvSpPr,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	CNvPr;
	CNvPicPr;
	CNvSpPr;
End;

///////////////////////////////////////////////////////////////
/// TCNvPr
///////////////////////////////////////////////////////////////
type TCNvPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'pic:cNvPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		ExtLst := new TExtLst(self, 'a:extLst');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		ExtLst.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("ID", "id", ID, ""),("Name", "name", Name, ""),("Descr", "descr", Descr, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"ExtLst","name":ExtLst.NodeName,"obj":ExtLst,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TExtLst")
			) union ExtNodes;
	End;

	//Attributes
	ID;
	Name;
	Descr;

	//Nodes
	ExtLst;
End;

///////////////////////////////////////////////////////////////
/// TExtLst
///////////////////////////////////////////////////////////////
type TExtLst=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:extLst');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Ext := new TAext(self, 'a:ext');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Ext.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Ext","name":Ext.NodeName,"obj":Ext,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TAext")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Ext;
End;

///////////////////////////////////////////////////////////////
/// TAext
///////////////////////////////////////////////////////////////
type TAext=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:ext');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Uri", "uri", Uri, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Xmlns16","name":"a16:creationId","obj":Xmlns16,"attrEx":"xmlns:a16","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Id","name":"a16:creationId","obj":Id,"attrEx":"id","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	Uri;

	//Nodes
	Xmlns16;
	Id;
End;

///////////////////////////////////////////////////////////////
/// TprstGeom
///////////////////////////////////////////////////////////////
type TprstGeom=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:prstGeom');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Prst", "prst", Prst, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"AvLst","name":"a:avLst","obj":AvLst,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	Prst;

	//Nodes
	AvLst;
End;

///////////////////////////////////////////////////////////////
/// TblipFill
///////////////////////////////////////////////////////////////
type TblipFill=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'pic:blipFill');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Blip := new TBlip(self, 'a:blip');
		Stretch := new TStretch(self, 'a:stretch');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Blip.InitRootNode(node);
		Stretch.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Blip","name":Blip.NodeName,"obj":Blip,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TBlip")
			,("field":"Stretch","name":Stretch.NodeName,"obj":Stretch,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TStretch")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Blip;
	Stretch;
End;

///////////////////////////////////////////////////////////////
/// TwLine
///////////////////////////////////////////////////////////////
type TwLine=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:ln');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		SolidFill := new TSolidFill(self, 'a:solidFill');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		SolidFill.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"SolidFill","name":SolidFill.NodeName,"obj":SolidFill,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TSolidFill")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	SolidFill;
End;

///////////////////////////////////////////////////////////////
/// TpicsPpr
///////////////////////////////////////////////////////////////
type TpicsPpr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'pic:spPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		XFrm := new TXfrm(self, 'a:xfrm');
		PrstGeom := new TprstGeom(self, 'a:prstGeom');
		Line := new TwLine(self, 'a:ln');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		XFrm.InitRootNode(node);
		PrstGeom.InitRootNode(node);
		Line.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"XFrm","name":XFrm.NodeName,"obj":XFrm,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TXfrm")
			,("field":"PrstGeom","name":PrstGeom.NodeName,"obj":PrstGeom,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TprstGeom")
			,("field":"Line","name":Line.NodeName,"obj":Line,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TwLine")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	XFrm;
	PrstGeom;
	Line;
End;

///////////////////////////////////////////////////////////////
/// TBlip
///////////////////////////////////////////////////////////////
type TBlip=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:blip');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Xmlns", "xmlns:r", Xmlns, ""),("Embed", "r:embed", Embed, ""),("Cstate", "cstate", Cstate, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Xmlns;
	Embed;
	Cstate;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TStretch
///////////////////////////////////////////////////////////////
type TStretch=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:stretch');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"FillRect","name":"a:fillRect","obj":FillRect,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	FillRect;
End;

///////////////////////////////////////////////////////////////
/// TRef
///////////////////////////////////////////////////////////////
type TRef=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:stretch');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		SchemeClr := new TScheme(self, 'a:schemeClr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		SchemeClr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Idx", "idx", Idx, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"SchemeClr","name":SchemeClr.NodeName,"obj":SchemeClr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TScheme")
			) union ExtNodes;
	End;

	//Attributes
	Idx;

	//Nodes
	SchemeClr;
End;

///////////////////////////////////////////////////////////////
/// TScheme
///////////////////////////////////////////////////////////////
type TScheme=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:schemeClr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Val", "val", Val, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Shade","name":"a:shade","obj":Shade,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	Val;

	//Nodes
	Shade;
End;

///////////////////////////////////////////////////////////////
/// TXdrStyle
///////////////////////////////////////////////////////////////
type TXdrStyle=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:stretch');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		LnRef := new TRef(self, 'a:lnRef');
		FillRef := new TRef(self, 'a:fillRef');
		EffectRef := new TRef(self, 'a:effectRef');
		FontRef := new TRef(self, 'a:fontRef');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		LnRef.InitRootNode(node);
		FillRef.InitRootNode(node);
		EffectRef.InitRootNode(node);
		FontRef.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"LnRef","name":LnRef.NodeName,"obj":LnRef,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TRef")
			,("field":"FillRef","name":FillRef.NodeName,"obj":FillRef,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TRef")
			,("field":"EffectRef","name":EffectRef.NodeName,"obj":EffectRef,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TRef")
			,("field":"FontRef","name":FontRef.NodeName,"obj":FontRef,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TRef")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	LnRef;
	FillRef;
	EffectRef;
	FontRef;
End;

///////////////////////////////////////////////////////////////
/// TPic
///////////////////////////////////////////////////////////////
type TPic=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'pic:pic');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		NvPicPr := new TnvPicPr(self, 'pic:nvPicPr');
		BlipFill := new TblipFill(self, 'pic:blipFill');
		SpPr := new TSpPr(self, 'pic:spPr');
		Style := new TXdrStyle(self, 'xdr:style');
		TxBody := new TTxPr(self, 'xdr:txBody');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		NvPicPr.InitRootNode(node);
		BlipFill.InitRootNode(node);
		SpPr.InitRootNode(node);
		Style.InitRootNode(node);
		TxBody.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Macro", "macro", Macro, ""),("Textlink", "textlink", Textlink, ""),("Xmlns", "xmlns:pic", Xmlns, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"NvPicPr","name":NvPicPr.NodeName,"obj":NvPicPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TnvPicPr")
			,("field":"BlipFill","name":BlipFill.NodeName,"obj":BlipFill,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TblipFill")
			,("field":"SpPr","name":SpPr.NodeName,"obj":SpPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TSpPr")
			,("field":"Style","name":Style.NodeName,"obj":Style,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TXdrStyle")
			,("field":"TxBody","name":TxBody.NodeName,"obj":TxBody,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TTxPr")
			) union ExtNodes;
	End;

	//Attributes
	Macro;
	Textlink;
	Xmlns;

	//Nodes
	NvPicPr;
	BlipFill;
	SpPr;
	Style;
	TxBody;
End;

///////////////////////////////////////////////////////////////
/// TGraphicData
///////////////////////////////////////////////////////////////
type TGraphicData=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:graphicData');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Pic := new TPic(self, 'pic:pic');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Pic.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("uri", "uri", uri, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"C","name":"c:chart","obj":C,"attrEx":"xmlns:c","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"R","name":"c:chart","obj":R,"attrEx":"xmlns:r","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Rid","name":"c:chart","obj":Rid,"attrEx":"r:id","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Pic","name":Pic.NodeName,"obj":Pic,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TPic")
			) union ExtNodes;
	End;

	//Attributes
	uri;

	//Nodes
	C;
	R;
	Rid;
	Pic;
End;

///////////////////////////////////////////////////////////////
/// TGraphic
///////////////////////////////////////////////////////////////
type TGraphic=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'a:graphic');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		GraphicData := new TGraphicData(self, 'a:graphicData');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		GraphicData.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("xmlns", "xmlns:a", xmlns, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"GraphicData","name":GraphicData.NodeName,"obj":GraphicData,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TGraphicData")
			) union ExtNodes;
	End;

	//Attributes
	xmlns;

	//Nodes
	GraphicData;
End;

///////////////////////////////////////////////////////////////
/// TwInline
///////////////////////////////////////////////////////////////
type TwInline=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'wp:inline');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		cNvGraphicFramePr := new TcNvGraphicFramePr(self, 'wp:cNvGraphicFramePr');
		Graphic := new TGraphic(self, 'a:graphic');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		cNvGraphicFramePr.InitRootNode(node);
		Graphic.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("distT", "distT", distT, ""),("distB", "distB", distB, ""),("distL", "distL", distL, ""),("distR", "distR", distR, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"cx","name":"wp:extent","obj":cx,"attrEx":"cx","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"cy","name":"wp:extent","obj":cy,"attrEx":"cy","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"l","name":"wp:effectExtent","obj":l,"attrEx":"l","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"t","name":"wp:effectExtent","obj":t,"attrEx":"t","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"r","name":"wp:effectExtent","obj":r,"attrEx":"r","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"b","name":"wp:effectExtent","obj":b,"attrEx":"b","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"ID","name":"wp:docPr","obj":ID,"attrEx":"id","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Name","name":"wp:docPr","obj":Name,"attrEx":"name","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Descr","name":"wp:docPr","obj":Descr,"attrEx":"descr","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"cNvGraphicFramePr","name":cNvGraphicFramePr.NodeName,"obj":cNvGraphicFramePr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TcNvGraphicFramePr")
			,("field":"Graphic","name":Graphic.NodeName,"obj":Graphic,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TGraphic")
			) union ExtNodes;
	End;

	//Attributes
	distT;
	distB;
	distL;
	distR;

	//Nodes
	cx;
	cy;
	l;
	t;
	r;
	b;
	ID;
	Name;
	Descr;
	cNvGraphicFramePr;
	Graphic;
End;

///////////////////////////////////////////////////////////////
/// TwDrawing
///////////////////////////////////////////////////////////////
type TwDrawing=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:drawing');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		WInline := new TwInline(self, 'wp:inline');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		WInline.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"WInline","name":WInline.NodeName,"obj":WInline,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TwInline")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	WInline;
End;

///////////////////////////////////////////////////////////////
/// TText
///////////////////////////////////////////////////////////////
type TText=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:t');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Space", "xml:space", Space, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Text","name":"Text","obj":Text,"attrEx":"","nodeType":"tcdata","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	Space;

	//Nodes
	Text;
End;

///////////////////////////////////////////////////////////////
/// TRunImpl
///////////////////////////////////////////////////////////////
type TRunImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:r');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		rPr := new TwrPr(self, 'w:rPr');
		Br := new TBr(self, 'w:br');
		Drawing := new TwDrawing(self, 'w:drawing');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		rPr.InitRootNode(node);
		Br.InitRootNode(node);
		Drawing.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("xmlns", "xmlns:w", xmlns, ""),("rsidR", "w:rsidR", rsidR, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"rPr","name":rPr.NodeName,"obj":rPr,"attrEx":"","nodeType":"","attrName":"", "desc":"字体属性", "class":"TwrPr")
			,("field":"fldCharType","name":"w:fldChar","obj":fldCharType,"attrEx":"w:fldCharType","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Dirty","name":"w:fldChar","obj":Dirty,"attrEx":"w:dirty","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"InstrText","name":"w:instrText","obj":InstrText,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"InstrTextSpace","name":"w:instrText","obj":InstrTextSpace,"attrEx":"xml:space","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Tab","name":"w:tab","obj":Tab,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			,("field":"Br","name":Br.NodeName,"obj":Br,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TBr")
			,("field":"T","name":"w:t","obj":T,"attrEx":"","nodeType":"pcdata","attrName":"", "desc":"", "class":"")
			,("field":"Space","name":"w:t","obj":Space,"attrEx":"xml:space","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Drawing","name":Drawing.NodeName,"obj":Drawing,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TwDrawing")
			) union ExtNodes;
	End;

	//Attributes
	xmlns;
	rsidR;

	//Nodes
	rPr;
	fldCharType;
	Dirty;
	InstrText;
	InstrTextSpace;
	Tab;
	Br;
	T;
	Space;
	Drawing;
End;

///////////////////////////////////////////////////////////////
/// TBookMark
///////////////////////////////////////////////////////////////
type TBookMark=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:bookmarkStart');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("name", "w:name", name, ""),("id", "w:id", id, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	name;
	id;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TFldSimple
///////////////////////////////////////////////////////////////
type TFldSimple=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:fldSimple');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Run := new TRun(self, 'w:r');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Run.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("instr", "w:instr", instr, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Run","name":Run.NodeName,"obj":Run,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TRun")
			) union ExtNodes;
	End;

	//Attributes
	instr;

	//Nodes
	Run;
End;

///////////////////////////////////////////////////////////////
/// TParagraphImpl
///////////////////////////////////////////////////////////////
type TParagraphImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:p');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		pPr := new TwpPr(self, 'w:pPr');
		markStart := new TBookMark(self, 'w:bookmarkStart');
		Run := new TRun(self, 'w:r');
		markEnd := new TBookMark(self, 'w:bookmarkEnd');
		PageNo := new TFldSimple(self, 'w:fldSimple');
		OfRun := new TRun(self, 'w:r');
		TotalPageNo := new TFldSimple(self, 'w:fldSimple');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		pPr.InitRootNode(node);
		markStart.InitRootNode(node);
		Run.InitRootNode(node);
		markEnd.InitRootNode(node);
		PageNo.InitRootNode(node);
		OfRun.InitRootNode(node);
		TotalPageNo.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"pPr","name":pPr.NodeName,"obj":pPr,"attrEx":"","nodeType":"","attrName":"", "desc":"段落格式", "class":"TwpPr")
			,("field":"markStart","name":markStart.NodeName,"obj":markStart,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TBookMark")
			,("field":"Run","name":Run.NodeName,"obj":Run,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TRun")
			,("field":"markEnd","name":markEnd.NodeName,"obj":markEnd,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TBookMark")
			,("field":"PageNo","name":PageNo.NodeName,"obj":PageNo,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TFldSimple")
			,("field":"OfRun","name":OfRun.NodeName,"obj":OfRun,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TRun")
			,("field":"TotalPageNo","name":TotalPageNo.NodeName,"obj":TotalPageNo,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TFldSimple")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	pPr;
	markStart;
	Run;
	markEnd;
	PageNo;
	OfRun;
	TotalPageNo;
End;

///////////////////////////////////////////////////////////////
/// TwBody
///////////////////////////////////////////////////////////////
type TwBody=class(NodeInfo, TDocumentBody)
	Function Create(); overload;
	Begin
		Create(nil, 'w:body');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		ps := array();
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"ps","name":"w:p","obj":ps,"attrEx":"","nodeType":"","attrName":"","arrObj":"array", "desc":"", "class":"TParagraphImpl")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	ps;
End;

///////////////////////////////////////////////////////////////
/// TOptInfo
///////////////////////////////////////////////////////////////
type TOptInfo=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:cellDel');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property Author read readXMLAuthor write writeXMLAuthor;
	Function readXMLAuthor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Author'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLAuthor);
	End;

	Function writeXMLAuthor(str);
	Begin
		XMLAuthor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Author", "w:author", XMLAuthor, "作者"),("Date", "w:date", Date, "修改日期"),("ID", "w:id", ID, "disable")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	XMLAuthor;
	Date;
	ID;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TRevisionImpl
///////////////////////////////////////////////////////////////
type TRevisionImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:del');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property Author read readXMLAuthor write writeXMLAuthor;
	Function readXMLAuthor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Author'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLAuthor);
	End;

	Function writeXMLAuthor(str);
	Begin
		XMLAuthor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Author", "w:author", XMLAuthor, "作者"),("Date", "w:date", Date, "修改日期"),("ID", "w:id", ID, "disable")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	XMLAuthor;
	Date;
	ID;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TDocCommentImpl
///////////////////////////////////////////////////////////////
type TDocCommentImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:comment');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		P := new TParagraphImpl(self, 'w:p');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		P.InitRootNode(node);
	End;

	Property Author read readXMLAuthor write writeXMLAuthor;
	Function readXMLAuthor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Author'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLAuthor);
	End;

	Function writeXMLAuthor(str);
	Begin
		XMLAuthor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Author", "w:author", XMLAuthor, "作者"),("Date", "w:date", Date, "修改日期"),("ID", "w:id", ID, "disable")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"P","name":P.NodeName,"obj":P,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TParagraphImpl")
			) union ExtNodes;
	End;

	//Attributes
	XMLAuthor;
	Date;
	ID;

	//Nodes
	P;
End;

///////////////////////////////////////////////////////////////
/// TCol
///////////////////////////////////////////////////////////////
type TCol=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:cols');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("W", "w:w", W, "Column Width"),("space", "w:space", space, "Space Before Following Column")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	W;
	space;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TCols
///////////////////////////////////////////////////////////////
type TCols=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:cols');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		col := array();
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("equalWidth", "w:equalWidth", equalWidth, "Equal Column Widths"),("num", "w:num", num, "Number of Equal Width Columns"),("sep", "w:sep", sep, "Draw Line Between Columns"),("space", "w:space", space, "Spacing Between Equal Width Columns")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"col","name":"w:col","obj":col,"attrEx":"","nodeType":"","attrName":"","arrObj":"array", "desc":"Column Definitions", "class":"TCol")
			) union ExtNodes;
	End;

	//Attributes
	equalWidth;
	num;
	sep;
	space;

	//Nodes
	col;
End;

///////////////////////////////////////////////////////////////
/// TPageMargin
///////////////////////////////////////////////////////////////
type TPageMargin=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:pgMar');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("gutter", "w:gutter", gutter, "当前节中每页的页边距."),("footer", "w:footer", footer, "指定从页面底部边缘到页脚底部边缘的距离（以二十分之一点为单位）."),("header", "w:header", header, "指定从页面上边缘到页眉上边缘的距离（以二十分之一为单位）."),("left", "w:left", left, "指定页面左边缘与此文档文本范围左边缘之间的距离（以点的二十分之一为单位）."),("bottom", "w:bottom", bottom, "指定主文档的文本页边距底部与本节中所有页面的页面底部之间的距离（以二十分之一为单位）."),("right", "w:right", right, "指定页面右边缘与此文档文本范围右边缘之间的距离（以点的二十分之一为单位）."),("top", "w:top", top, "指定主文档的文本页边距顶部与本节中所有页面的页面顶部之间的距离（以二十分之一为单位）.")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	gutter;
	footer;
	header;
	left;
	bottom;
	right;
	top;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TDocGrid
///////////////////////////////////////////////////////////////
type TDocGrid=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:docGrid');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("charSpace", "w:charSpace", charSpace, "字符间距"),("charSize", "w:charSize", charSize, "文档网格字符间距"),("linePitch", "w:linePitch", linePitch, "文档网格线间距"),("Type", "w:type", Type, "文档网格线类型")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	charSpace;
	charSize;
	linePitch;
	Type;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TReference
///////////////////////////////////////////////////////////////
type TReference=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:headerReference');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Type", "w:type", Type, ""),("ID", "r:id", ID, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Type;
	ID;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TPageBorders
///////////////////////////////////////////////////////////////
type TPageBorders=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:pgBorders');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Top := new TwBorder(self, 'w:top');
		Left := new TwBorder(self, 'w:left');
		Bottom := new TwBorder(self, 'w:bottom');
		Right := new TwBorder(self, 'w:right');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Top.InitRootNode(node);
		Left.InitRootNode(node);
		Bottom.InitRootNode(node);
		Right.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("offsetFrom", "w:offsetFrom", offsetFrom, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Top","name":Top.NodeName,"obj":Top,"attrEx":"","nodeType":"","attrName":"", "desc":"边框属性", "class":"TwBorder")
			,("field":"Left","name":Left.NodeName,"obj":Left,"attrEx":"","nodeType":"","attrName":"", "desc":"边框属性", "class":"TwBorder")
			,("field":"Bottom","name":Bottom.NodeName,"obj":Bottom,"attrEx":"","nodeType":"","attrName":"", "desc":"边框属性", "class":"TwBorder")
			,("field":"Right","name":Right.NodeName,"obj":Right,"attrEx":"","nodeType":"","attrName":"", "desc":"边框属性", "class":"TwBorder")
			) union ExtNodes;
	End;

	//Attributes
	offsetFrom;

	//Nodes
	Top;
	Left;
	Bottom;
	Right;
End;

///////////////////////////////////////////////////////////////
/// TPage
///////////////////////////////////////////////////////////////
type TPage=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:pgSz');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Code", "w:code", Code, "纸张类型（指定打印机特定的纸张代码）."),("Height", "w:h", Height, "当前节中所有页面的高度（以二十分之一点为单位）.")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Width","name":"w:w","obj":Width,"attrEx":"","nodeType":"","attrName":"", "desc":"此属性表示当前节中所有页面的宽度（以二十分之一为单位）.", "class":"")
			,("field":"Orient ","name":"w:orient ","obj":Orient ,"attrEx":"","nodeType":"","attrName":"", "desc":"指定此节中所有页面的方向.", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	Code;
	Height;

	//Nodes
	Width;
	Orient ;
End;

///////////////////////////////////////////////////////////////
/// TDocSectionImpl
///////////////////////////////////////////////////////////////
type TDocSectionImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:sectPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Header := new TReference(self, 'w:headerReference');
		Footer := new TReference(self, 'w:footerReference');
		cols := new TCols(self, 'w:cols');
		docGrid := new TDocGrid(self, 'w:docGrid');
		pgMar := new TPageMargin(self, 'w:pgMar');
		Page := new TPage(self, 'w:pgSz');
		Borders := new TPageBorders(self, 'w:pgBorders');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Header.InitRootNode(node);
		Footer.InitRootNode(node);
		cols.InitRootNode(node);
		docGrid.InitRootNode(node);
		pgMar.InitRootNode(node);
		Page.InitRootNode(node);
		Borders.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Header","name":Header.NodeName,"obj":Header,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TReference")
			,("field":"Footer","name":Footer.NodeName,"obj":Footer,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TReference")
			,("field":"bidi","name":"w:bidi","obj":bidi,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"章节从右到左的布局", "class":"")
			,("field":"cols","name":cols.NodeName,"obj":cols,"attrEx":"","nodeType":"","attrName":"", "desc":"Column Definitions", "class":"TCols")
			,("field":"docGrid","name":docGrid.NodeName,"obj":docGrid,"attrEx":"","nodeType":"","attrName":"", "desc":"Document Grid", "class":"TDocGrid")
			,("field":"pgMar","name":pgMar.NodeName,"obj":pgMar,"attrEx":"","nodeType":"","attrName":"", "desc":"Page Margin设置", "class":"TPageMargin")
			,("field":"Page","name":Page.NodeName,"obj":Page,"attrEx":"","nodeType":"","attrName":"", "desc":"页面设置", "class":"TPage")
			,("field":"Borders","name":Borders.NodeName,"obj":Borders,"attrEx":"","nodeType":"","attrName":"", "desc":"页面边框属性", "class":"TPageBorders")
			,("field":"titlePg","name":"w:titlePg","obj":titlePg,"attrEx":"","nodeType":"empty","attrName":"", "desc":"第一页是否有不同的页眉和页脚.", "class":"")
			,("field":"vAlign","name":"w:vAlign","obj":vAlign,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"当前章节，文本上下边距的垂直对齐方式.", "class":"")
			,("field":"Type","name":"w:type","obj":Type,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"当前节的类型（指定当前节的内容相对于上一节的放置方式）.", "class":"")
			,("field":"textDirection","name":"w:textDirection","obj":textDirection,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"此节的文本方向.", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Header;
	Footer;
	bidi;
	cols;
	docGrid;
	pgMar;
	Page;
	Borders;
	titlePg;
	vAlign;
	Type;
	textDirection;
End;

///////////////////////////////////////////////////////////////
/// TcellMerge
///////////////////////////////////////////////////////////////
type TcellMerge=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:cellMerge');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property Author read readXMLAuthor write writeXMLAuthor;
	Function readXMLAuthor();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Author'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLAuthor);
	End;

	Function writeXMLAuthor(str);
	Begin
		XMLAuthor := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Author", "w:author", XMLAuthor, ""),("Date", "w:date", Date, ""),("ID", "w:id", ID, ""),("vmerge", "w:vmerge", vmerge, "垂直合并设置。"),("vmergeOrig", "w:vmergeOrig", vmergeOrig, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	XMLAuthor;
	Date;
	ID;
	vmerge;
	vmergeOrig;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TwTcPr
///////////////////////////////////////////////////////////////
type TwTcPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tcPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Shading := new TwShading(self, 'w:shd');
		CellMar := new TTblCellMar(self, 'w:tcMar');
		Borders := new TwTblBorders(self, 'w:tcBorders');
		Del := new TOptInfo(self, 'w:cellDel');
		Ins := new TOptInfo(self, 'w:cellIns');
		cellMerge := new TcellMerge(self, 'w:cellMerge');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Shading.InitRootNode(node);
		CellMar.InitRootNode(node);
		Borders.InitRootNode(node);
		Del.InitRootNode(node);
		Ins.InitRootNode(node);
		cellMerge.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Width","name":"w:tcW","obj":Width,"attrEx":"w:w","nodeType":"","attrName":"", "desc":"表格单元格宽度", "class":"")
			,("field":"Type","name":"w:tcW","obj":Type,"attrEx":"w:type","nodeType":"","attrName":"", "desc":"宽度属性的单位。此属性用于定义表格的各种属性，包括：单元格间距、首选宽度和表格边距。", "class":"")
			,("field":"Shading","name":Shading.NodeName,"obj":Shading,"attrEx":"","nodeType":"","attrName":"", "desc":"表头底纹", "class":"TwShading")
			,("field":"cnfStyle","name":"w:cnfStyle","obj":cnfStyle,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"此表格单元的条件表格样式格式设置属性集。", "class":"")
			,("field":"CellMar","name":CellMar.NodeName,"obj":CellMar,"attrEx":"","nodeType":"","attrName":"", "desc":"单元格边距设置", "class":"TTblCellMar")
			,("field":"Borders","name":Borders.NodeName,"obj":Borders,"attrEx":"","nodeType":"","attrName":"", "desc":"边框属性", "class":"TwTblBorders")
			,("field":"gridSpan","name":"w:gridSpan","obj":gridSpan,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"当前表单元格所跨的网格列", "class":"")
			,("field":"hideMark","name":"w:hideMark","obj":hideMark,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"忽略行高度计算中的单元格结尾标记", "class":"")
			,("field":"hmerge","name":"w:hmerge","obj":hmerge,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"水平合并单元格", "class":"")
			,("field":"noWrap","name":"w:noWrap","obj":noWrap,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"不换行单元格内容", "class":"")
			,("field":"tcFitText","name":"w:tcFitText","obj":tcFitText,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"调整单元格内的文本", "class":"")
			,("field":"textDirection","name":"w:textDirection","obj":textDirection,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"表格单元格文本文字方向", "class":"")
			,("field":"Del","name":Del.NodeName,"obj":Del,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TOptInfo")
			,("field":"Ins","name":Ins.NodeName,"obj":Ins,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TOptInfo")
			,("field":"cellMerge","name":cellMerge.NodeName,"obj":cellMerge,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TcellMerge")
			,("field":"vAlign","name":"w:vAlign","obj":vAlign,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"表格单元格垂直对齐", "class":"")
			,("field":"vmerge","name":"w:vmerge","obj":vmerge,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"垂直合并单元格", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Width;
	Type;
	Shading;
	cnfStyle;
	CellMar;
	Borders;
	gridSpan;
	hideMark;
	hmerge;
	noWrap;
	tcFitText;
	textDirection;
	Del;
	Ins;
	cellMerge;
	vAlign;
	vmerge;
End;

///////////////////////////////////////////////////////////////
/// TwTc
///////////////////////////////////////////////////////////////
type TwTc=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tc');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		TcPr := new TwTcPr(self, 'w:tcPr');
		P := new TParagraphImpl(self, 'w:p');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		TcPr.InitRootNode(node);
		P.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"TcPr","name":TcPr.NodeName,"obj":TcPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TwTcPr")
			,("field":"P","name":P.NodeName,"obj":P,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TParagraphImpl")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	TcPr;
	P;
End;

///////////////////////////////////////////////////////////////
/// TwTrPr
///////////////////////////////////////////////////////////////
type TwTrPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:trPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Del := new TOptInfo(self, 'w:del');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Del.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Height","name":"w:trHeight","obj":Height,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"行高", "class":"")
			,("field":"Rule","name":"w:trHeight","obj":Rule,"attrEx":"w:hRule","nodeType":"","attrName":"", "desc":"如果Rule的值为自动，则应根据其内容的高度自动确定表行的高度，忽略Height值；如果Rule的值至少为least，则表行的高度应至少为Height属性的值；如果Rule的值是精确的，那么表行的高度应该正好是Height属性的值。", "class":"")
			,("field":"Alignment","name":"w:jc","obj":Alignment,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"对齐方式（left、right、center）", "class":"")
			,("field":"CantSplit","name":"w:cantSplit","obj":CantSplit,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"表行不能跨页分隔", "class":"")
			,("field":"cnfStyle","name":"w:cnfStyle","obj":cnfStyle,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"表行条件格式", "class":"")
			,("field":"gridAfter","name":"w:gridAfter","obj":gridAfter,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"最后一个单元格后的网格列", "class":"")
			,("field":"gridBefore","name":"w:gridBefore","obj":gridBefore,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"第一个单元格之前的网格列", "class":"")
			,("field":"hidden","name":"w:hidden","obj":hidden,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"隐藏表行标记", "class":"")
			,("field":"tblHeader","name":"w:tblHeader","obj":tblHeader,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"在每个新页面上重复表行", "class":"")
			,("field":"Del","name":Del.NodeName,"obj":Del,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"TOptInfo")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Height;
	Rule;
	Alignment;
	CantSplit;
	cnfStyle;
	gridAfter;
	gridBefore;
	hidden;
	tblHeader;
	Del;
End;

///////////////////////////////////////////////////////////////
/// TwShading
///////////////////////////////////////////////////////////////
type TwShading=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:shd');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Val", "w:val", Val, "指定用于将图案颜色覆盖在此段落底纹的背景色上的图案。此图案由应用于背景底纹颜色上的遮罩组成，以获得应显示图案颜色的位置。."),("Color", "w:color", Color, "前景颜色: RRGGBB format or auto"),("Fill", "w:fill", Fill, "背景颜色: RRGGBB format or auto"),("ThemeColor", "w:themeColor", ThemeColor, "前景主题颜色: theme color"),("ThemeFill", "w:themeFill", ThemeFill, "背景主题颜色: theme color"),("ThemeFillShade", "w:themeFillShade", ThemeFillShade, "阴影颜色: theme color"),("ThemeFillTint", "w:themeFillTint", ThemeFillTint, "tint 主题填充颜色."),("ThemeShade", "w:themeShade", ThemeShade, "主题阴影颜色."),("ThemeTint", "w:themeTint", ThemeTint, "tint主题阴影颜色.")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Val;
	Color;
	Fill;
	ThemeColor;
	ThemeFill;
	ThemeFillShade;
	ThemeFillTint;
	ThemeShade;
	ThemeTint;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TTblCellMar
///////////////////////////////////////////////////////////////
type TTblCellMar=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tblCellMar');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Top","name":"w:top","obj":Top,"attrEx":"w:w","nodeType":"","attrName":"", "desc":"表格单元格上边距，指定宽度属性的值.", "class":"")
			,("field":"TopType","name":"w:top","obj":TopType,"attrEx":"w:type","nodeType":"","attrName":"", "desc":"宽度属性的单位，auto（自动确定的宽度）、dxa（点的二十分之一宽度）nil（无宽度）pct（百分之五十宽度）", "class":"")
			,("field":"Left","name":"w:left","obj":Left,"attrEx":"w:w","nodeType":"","attrName":"", "desc":"表格单元格左边距，指定宽度属性的值.", "class":"")
			,("field":"LeftType","name":"w:left","obj":LeftType,"attrEx":"w:type","nodeType":"","attrName":"", "desc":"宽度属性的单位，auto（自动确定的宽度）、dxa（点的二十分之一宽度）nil（无宽度）pct（百分之五十宽度）", "class":"")
			,("field":"Bottom","name":"w:bottom","obj":Bottom,"attrEx":"w:w","nodeType":"","attrName":"", "desc":"表格单元格底边距，指定宽度属性的值..", "class":"")
			,("field":"BottomType","name":"w:bottom","obj":BottomType,"attrEx":"w:type","nodeType":"","attrName":"", "desc":"宽度属性的单位，auto（自动确定的宽度）、dxa（点的二十分之一宽度）nil（无宽度）pct（百分之五十宽度）", "class":"")
			,("field":"Right","name":"w:right","obj":Right,"attrEx":"w:w","nodeType":"","attrName":"", "desc":"表格单元格右边距，指定宽度属性的值..", "class":"")
			,("field":"RightType","name":"w:right","obj":RightType,"attrEx":"w:type","nodeType":"","attrName":"", "desc":"宽度属性的单位，auto（自动确定的宽度）、dxa（点的二十分之一宽度）nil（无宽度）pct（百分之五十宽度）", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Top;
	TopType;
	Left;
	LeftType;
	Bottom;
	BottomType;
	Right;
	RightType;
End;

///////////////////////////////////////////////////////////////
/// TTblPrEx
///////////////////////////////////////////////////////////////
type TTblPrEx=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tblPrEx');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Borders := new TwTblBorders(self, 'w:tblBorders');
		Shading := new TwShading(self, 'w:shd');
		CellMar := new TTblCellMar(self, 'w:tblCellMar');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Borders.InitRootNode(node);
		Shading.InitRootNode(node);
		CellMar.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Alignment","name":"w:jc","obj":Alignment,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Borders","name":Borders.NodeName,"obj":Borders,"attrEx":"","nodeType":"","attrName":"", "desc":"边框属性", "class":"TwTblBorders")
			,("field":"Shading","name":Shading.NodeName,"obj":Shading,"attrEx":"","nodeType":"","attrName":"", "desc":"表头底纹", "class":"TwShading")
			,("field":"CellMar","name":CellMar.NodeName,"obj":CellMar,"attrEx":"","nodeType":"","attrName":"", "desc":"单元格边距设置", "class":"TTblCellMar")
			,("field":"CellSpacing","name":"w:tblCellSpacing","obj":CellSpacing,"attrEx":"w:w","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"CellSpacingType","name":"w:tblCellSpacing","obj":CellSpacingType,"attrEx":"w:type","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Indent","name":"w:tblInd","obj":Indent,"attrEx":"w:w","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"IndentType","name":"w:tblInd","obj":IndentType,"attrEx":"w:type","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Autofit","name":"w:tblLayout","obj":Autofit,"attrEx":"w:type","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Val","name":"w:tblLook","obj":Val,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"NoVBand","name":"w:tblLook","obj":NoVBand,"attrEx":"w:noVBand","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"NoHBand","name":"w:tblLook","obj":NoHBand,"attrEx":"w:noHBand","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"LastRow","name":"w:tblLook","obj":LastRow,"attrEx":"w:lastRow","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"LastColumn","name":"w:tblLook","obj":LastColumn,"attrEx":"w:lastColumn","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"FirstRow","name":"w:tblLook","obj":FirstRow,"attrEx":"w:firstRow","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"FirstColumn","name":"w:tblLook","obj":FirstColumn,"attrEx":"w:firstColumn","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"Width","name":"w:tblW","obj":Width,"attrEx":"w:w","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"WidthType","name":"w:tblW","obj":WidthType,"attrEx":"w:type","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Alignment;
	Borders;
	Shading;
	CellMar;
	CellSpacing;
	CellSpacingType;
	Indent;
	IndentType;
	Autofit;
	Val;
	NoVBand;
	NoHBand;
	LastRow;
	LastColumn;
	FirstRow;
	FirstColumn;
	Width;
	WidthType;
End;

///////////////////////////////////////////////////////////////
/// TwTr
///////////////////////////////////////////////////////////////
type TwTr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		tblPrEx := new TTblPrEx(self, 'w:tblPrEx');
		TrPr := new TwTrPr(self, 'w:trPr');
		Tc := array();
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		tblPrEx.InitRootNode(node);
		TrPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"tblPrEx","name":tblPrEx.NodeName,"obj":tblPrEx,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TTblPrEx")
			,("field":"TrPr","name":TrPr.NodeName,"obj":TrPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TwTrPr")
			,("field":"Tc","name":"w:tc","obj":Tc,"attrEx":"","nodeType":"","attrName":"","arrObj":"array", "desc":"", "class":"TwTc")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	tblPrEx;
	TrPr;
	Tc;
End;

///////////////////////////////////////////////////////////////
/// TwBorder
///////////////////////////////////////////////////////////////
type TwBorder=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:top');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Val", "w:val", Val, "指定边框样式."),("Color", "w:color", Color, "边框颜色."),("ThemeColor", "w:themeColor", ThemeColor, "边框主题颜色."),("ThemeTint", "w:themeTint", ThemeTint, "指定应用于此边框实例提供的主题颜色（如果有）的色调值."),("Size", "w:sz", Size, "边框宽度."),("Frame", "w:frame", Frame, "指定是否应修改指定的边框，以通过将边框外观从离文本最近的边缘反转到离文本最远的边缘来创建框架效果."),("Shadow", "w:shadow", Shadow, "边框阴影."),("Space", "w:space", Space, "放置此边框的间距偏移."),("ThemeShade", "w:themeShade", ThemeShade, "边框阴影的主题颜色.")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Val;
	Color;
	ThemeColor;
	ThemeTint;
	Size;
	Frame;
	Shadow;
	Space;
	ThemeShade;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TwTblBorders
///////////////////////////////////////////////////////////////
type TwTblBorders=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tblBorders');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Top := new TwBorder(self, 'w:top');
		Left := new TwBorder(self, 'w:left');
		Bottom := new TwBorder(self, 'w:bottom');
		Right := new TwBorder(self, 'w:right');
		InsideH := new TwBorder(self, 'w:insideH');
		InsideV := new TwBorder(self, 'w:insideV');
		tr2bl := new TwBorder(self, 'w:tr2bl');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Top.InitRootNode(node);
		Left.InitRootNode(node);
		Bottom.InitRootNode(node);
		Right.InitRootNode(node);
		InsideH.InitRootNode(node);
		InsideV.InitRootNode(node);
		tr2bl.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Top","name":Top.NodeName,"obj":Top,"attrEx":"","nodeType":"","attrName":"", "desc":"边框属性", "class":"TwBorder")
			,("field":"Left","name":Left.NodeName,"obj":Left,"attrEx":"","nodeType":"","attrName":"", "desc":"左边框属性", "class":"TwBorder")
			,("field":"Bottom","name":Bottom.NodeName,"obj":Bottom,"attrEx":"","nodeType":"","attrName":"", "desc":"底边框属性", "class":"TwBorder")
			,("field":"Right","name":Right.NodeName,"obj":Right,"attrEx":"","nodeType":"","attrName":"", "desc":"右边框属性", "class":"TwBorder")
			,("field":"InsideH","name":InsideH.NodeName,"obj":InsideH,"attrEx":"","nodeType":"","attrName":"", "desc":"水平边框属性", "class":"TwBorder")
			,("field":"InsideV","name":InsideV.NodeName,"obj":InsideV,"attrEx":"","nodeType":"","attrName":"", "desc":"垂直边框属性", "class":"TwBorder")
			,("field":"tr2bl","name":tr2bl.NodeName,"obj":tr2bl,"attrEx":"","nodeType":"","attrName":"", "desc":"行边框属性", "class":"TwBorder")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Top;
	Left;
	Bottom;
	Right;
	InsideH;
	InsideV;
	tr2bl;
End;

///////////////////////////////////////////////////////////////
/// TwTblpPr
///////////////////////////////////////////////////////////////
type TwTblpPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tblpPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("bottomFromText", "w:bottomFromText ", bottomFromText, "指定当前浮动表与该浮动表下方段落中文本顶部之间应保持的最小距离。"),("horizAnchor", "w:horizAnchor", horizAnchor, "指定水平定位的基础对象。"),("leftFromText", "w:leftFromText", leftFromText, "指定当前浮动表与该浮动表左侧段落中文本边缘之间应保持的最小距离。"),("rightFromText", "w:rightFromText", rightFromText, "指定当前浮动表与该浮动表右侧段落中文本边缘之间应保持的最小距离。"),("tblpX", "w:tblpX", tblpX, "指定浮动表的绝对水平位置。此绝对位置是相对于horzAnchor属性为此浮动表指定的水平定位点指定的。"),("tblpXSpec", "w:tblpXSpec", tblpXSpec, "指定浮动表的相对水平位置。此相对位置是相对于此浮动表的horizAnchor属性指定的水平定位点指定的。"),("tblpY", "w:tblpY", tblpY, "指定浮动表的绝对垂直位置。此绝对位置是相对于此浮动表的vertAnchor属性指定的垂直锚点指定的。"),("tblpYSpec", "w:tblpYSpec", tblpYSpec, "指定浮动表的相对垂直位置。此相对位置是相对于此浮动表的vertAnchor属性指定的垂直锚点指定的。"),("topFromText", "w:topFromText", topFromText, "指定当前浮动表与该浮动表上方段落中文本底部边缘之间应保持的最小距离。"),("vertAnchor", "w:vertAnchor", vertAnchor, "指定应根据其计算tblpY属性中的垂直定位的基础对象。")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	bottomFromText;
	horizAnchor;
	leftFromText;
	rightFromText;
	tblpX;
	tblpXSpec;
	tblpY;
	tblpYSpec;
	topFromText;
	vertAnchor;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TwTblPr
///////////////////////////////////////////////////////////////
type TwTblPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tblPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Shading := new TwShading(self, 'w:shd');
		Borders := new TwTblBorders(self, 'w:tblBorders');
		CellMar := new TTblCellMar(self, 'w:tblCellMar');
		tblpPr := new TwTblpPr(self, 'w:tblpPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		Shading.InitRootNode(node);
		Borders.InitRootNode(node);
		CellMar.InitRootNode(node);
		tblpPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"StyleID","name":"w:tblStyle","obj":StyleID,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"样式ID", "class":"")
			,("field":"Width","name":"w:tblW","obj":Width,"attrEx":"w:w","nodeType":"","attrName":"", "desc":"表格宽度", "class":"")
			,("field":"WidthType","name":"w:tblW","obj":WidthType,"attrEx":"w:type","nodeType":"","attrName":"", "desc":"宽度属性的单位。此属性用于定义表格的各种属性，包括：单元格间距、首选宽度和表格边距。", "class":"")
			,("field":"Val","name":"w:tblLook","obj":Val,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"表格条件格式样式：表格样式最多可以指定六种不同的可选条件格式,如首行、尾行、首列、尾列等（16进制short）", "class":"")
			,("field":"NoVBand","name":"w:tblLook","obj":NoVBand,"attrEx":"w:noVBand","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"NoHBand","name":"w:tblLook","obj":NoHBand,"attrEx":"w:noHBand","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"LastRow","name":"w:tblLook","obj":LastRow,"attrEx":"w:lastRow","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"LastColumn","name":"w:tblLook","obj":LastColumn,"attrEx":"w:lastColumn","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"FirstRow","name":"w:tblLook","obj":FirstRow,"attrEx":"w:firstRow","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"FirstColumn","name":"w:tblLook","obj":FirstColumn,"attrEx":"w:firstColumn","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"Shading","name":Shading.NodeName,"obj":Shading,"attrEx":"","nodeType":"","attrName":"", "desc":"表头底纹", "class":"TwShading")
			,("field":"bidiVisual","name":"w:bidiVisual","obj":bidiVisual,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"从右到左可视化表格", "class":"")
			,("field":"Alignment","name":"w:jc","obj":Alignment,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"当前文本边距的对齐方式（left、right、center）", "class":"")
			,("field":"Indent","name":"w:tblInd","obj":Indent,"attrEx":"w:w","nodeType":"","attrName":"", "desc":"文档中当前表格前缘之前的缩进（从左到右表格中的左边缘，从右到左表格中的右边缘）。", "class":"")
			,("field":"IndentType","name":"w:tblInd","obj":IndentType,"attrEx":"w:type","nodeType":"","attrName":"", "desc":"约定Indent值的的单位，如果忽略此属性，则其值应假定为dxa（二十分之一点）。", "class":"")
			,("field":"Borders","name":Borders.NodeName,"obj":Borders,"attrEx":"","nodeType":"","attrName":"", "desc":"表格边框属性", "class":"TwTblBorders")
			,("field":"Autofit","name":"w:tblLayout","obj":Autofit,"attrEx":"w:type","nodeType":"","attrName":"", "desc":"布局该表内容的算法。当表格显示在文档中时，可以使用固定宽度或自动调整布局算法来显示表格。如果省略了该元素，则该元素的值应假定为自动。", "class":"")
			,("field":"CellMar","name":CellMar.NodeName,"obj":CellMar,"attrEx":"","nodeType":"","attrName":"", "desc":"单元格边距设置", "class":"TTblCellMar")
			,("field":"Overlap","name":"w:tblOverlap ","obj":Overlap,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"当前表是否允许其他浮动表重叠其范围。如果指定，则不应进行任何调整，以防止其属性通常会导致其重叠的表格在显示时重叠。如果关闭，则应根据需要调整表格，以防止它们在显示时重叠，方法是根据需要调整浮动表格属性。", "class":"")
			,("field":"tblpPr","name":tblpPr.NodeName,"obj":tblpPr,"attrEx":"","nodeType":"","attrName":"", "desc":"浮动表设置", "class":"TwTblpPr")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	StyleID;
	Width;
	WidthType;
	Val;
	NoVBand;
	NoHBand;
	LastRow;
	LastColumn;
	FirstRow;
	FirstColumn;
	Shading;
	bidiVisual;
	Alignment;
	Indent;
	IndentType;
	Borders;
	Autofit;
	CellMar;
	Overlap;
	tblpPr;
End;

///////////////////////////////////////////////////////////////
/// TwGridCol
///////////////////////////////////////////////////////////////
type TwGridCol=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:gridCol');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("W", "w:w", W, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	W;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TwTblGrid
///////////////////////////////////////////////////////////////
type TwTblGrid=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tblGrid');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		GridCol := array();
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"GridCol","name":"w:gridCol","obj":GridCol,"attrEx":"","nodeType":"","attrName":"","arrObj":"array", "desc":"", "class":"TwGridCol")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	GridCol;
End;

///////////////////////////////////////////////////////////////
/// TTableImpl
///////////////////////////////////////////////////////////////
type TTableImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tbl');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		TblPr := new TwTblPr(self, 'w:tblPr');
		TblGrid := new TwTblGrid(self, 'w:tblGrid');
		TR := array();
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		TblPr.InitRootNode(node);
		TblGrid.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"TblPr","name":TblPr.NodeName,"obj":TblPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TwTblPr")
			,("field":"TblGrid","name":TblGrid.NodeName,"obj":TblGrid,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TwTblGrid")
			,("field":"TR","name":"w:tr","obj":TR,"attrEx":"","nodeType":"","attrName":"","arrObj":"array", "desc":"", "class":"TwTr")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	TblPr;
	TblGrid;
	TR;
End;

///////////////////////////////////////////////////////////////
/// TCorePropertiesImpl
///////////////////////////////////////////////////////////////
type TCorePropertiesImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:p');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TPictureImpl
///////////////////////////////////////////////////////////////
type TPictureImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:p');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		pPr := new TwpPr(self, 'w:pPr');
		Run := new TRunImpl(self, 'w:r');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		pPr.InitRootNode(node);
		Run.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"pPr","name":pPr.NodeName,"obj":pPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TwpPr")
			,("field":"Run","name":Run.NodeName,"obj":Run,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TRunImpl")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	pPr;
	Run;
End;

///////////////////////////////////////////////////////////////
/// TpBdr
///////////////////////////////////////////////////////////////
type TpBdr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:pBdr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		top := new TwBorder(self, 'w:top');
		left := new TwBorder(self, 'w:left');
		bottom := new TwBorder(self, 'w:bottom');
		right := new TwBorder(self, 'w:right');
		bar := new TwBorder(self, 'w:bar');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		top.InitRootNode(node);
		left.InitRootNode(node);
		bottom.InitRootNode(node);
		right.InitRootNode(node);
		bar.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"top","name":top.NodeName,"obj":top,"attrEx":"","nodeType":"","attrName":"", "desc":"边框属性", "class":"TwBorder")
			,("field":"left","name":left.NodeName,"obj":left,"attrEx":"","nodeType":"","attrName":"", "desc":"边框属性", "class":"TwBorder")
			,("field":"bottom","name":bottom.NodeName,"obj":bottom,"attrEx":"","nodeType":"","attrName":"", "desc":"边框属性", "class":"TwBorder")
			,("field":"right","name":right.NodeName,"obj":right,"attrEx":"","nodeType":"","attrName":"", "desc":"边框属性", "class":"TwBorder")
			,("field":"bar","name":bar.NodeName,"obj":bar,"attrEx":"","nodeType":"","attrName":"", "desc":"边框属性", "class":"TwBorder")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	top;
	left;
	bottom;
	right;
	bar;
End;

///////////////////////////////////////////////////////////////
/// TLatentStyle
///////////////////////////////////////////////////////////////
type TLatentStyle=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:lsdException');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Name", "w:name", Name, ""),("Count", "w:count", Count, ""),("defLockedState", "w:defLockedState", defLockedState, ""),("defQFormat", "w:defQFormat", defQFormat, ""),("defSemiHidden", "w:defSemiHidden", defSemiHidden, ""),("defUIPriority", "w:defUIPriority", defUIPriority, ""),("defUnhideWhenUsed", "w:defUnhideWhenUsed", defUnhideWhenUsed, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Name;
	Count;
	defLockedState;
	defQFormat;
	defSemiHidden;
	defUIPriority;
	defUnhideWhenUsed;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TtblStylePr
///////////////////////////////////////////////////////////////
type TtblStylePr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tblStylePr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		pPr := new TwpPr(self, 'w:pPr');
		rPr := new TwrPr(self, 'w:rPr');
		TrPr := new TwTrPr(self, 'w:trPr');
		TblPr := new TwTblPr(self, 'w:tblPr');
		TcPr := new TwTcPr(self, 'w:tcPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		pPr.InitRootNode(node);
		rPr.InitRootNode(node);
		TrPr.InitRootNode(node);
		TblPr.InitRootNode(node);
		TcPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"pPr","name":pPr.NodeName,"obj":pPr,"attrEx":"","nodeType":"","attrName":"", "desc":"段落格式", "class":"TwpPr")
			,("field":"rPr","name":rPr.NodeName,"obj":rPr,"attrEx":"","nodeType":"","attrName":"", "desc":"字体属性", "class":"TwrPr")
			,("field":"TrPr","name":TrPr.NodeName,"obj":TrPr,"attrEx":"","nodeType":"","attrName":"", "desc":"表格行属性", "class":"TwTrPr")
			,("field":"TblPr","name":TblPr.NodeName,"obj":TblPr,"attrEx":"","nodeType":"","attrName":"", "desc":"表格样式", "class":"TwTblPr")
			,("field":"TcPr","name":TcPr.NodeName,"obj":TcPr,"attrEx":"","nodeType":"","attrName":"", "desc":"单元格属性", "class":"TwTcPr")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	pPr;
	rPr;
	TrPr;
	TblPr;
	TcPr;
End;

///////////////////////////////////////////////////////////////
/// TDocxStyleImpl
///////////////////////////////////////////////////////////////
type TDocxStyleImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:style');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		TblStyle := new TtblStylePr(self, 'w:tblStylePr');
		pPr := new TwpPr(self, 'w:pPr');
		rPr := new TwrPr(self, 'w:rPr');
		TrPr := new TwTrPr(self, 'w:trPr');
		TblPr := new TwTblPr(self, 'w:tblPr');
		TcPr := new TwTcPr(self, 'w:tcPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		TblStyle.InitRootNode(node);
		pPr.InitRootNode(node);
		rPr.InitRootNode(node);
		TrPr.InitRootNode(node);
		TblPr.InitRootNode(node);
		TcPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("StyleID", "w:styleId", StyleID, "样式ID（数字或字符串）。"),("Default", "w:default", Default, "是否缺省样式，如缺省段落、缺省表格样式"),("wType", "w:type", wType, "样式类型（paragraph、chartacter、table）"),("CustomStyle ", "w:customStyle ", CustomStyle , "disable")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Name","name":"w:name","obj":Name,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"样式名称", "class":"")
			,("field":"Aliases","name":"w:aliases","obj":Aliases,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"样式别名.", "class":"")
			,("field":"AutoRedefine","name":"w:autoRedefine","obj":AutoRedefine,"attrEx":"","nodeType":"empty","attrName":"", "desc":"文本变动时，是否自动修改样式.", "class":"")
			,("field":"BasedOn","name":"w:basedOn","obj":BasedOn,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"样式继承.", "class":"")
			,("field":"Hidden","name":"w:hidden","obj":Hidden,"attrEx":"","nodeType":"empty","attrName":"", "desc":"隐藏样式", "class":"")
			,("field":"Link","name":"w:link","obj":Link,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"链接样式", "class":"")
			,("field":"Locked","name":"w:locked","obj":Locked,"attrEx":"","nodeType":"empty","attrName":"", "desc":"是否阻止使用此样式.", "class":"")
			,("field":"Next","name":"w:b","obj":Next,"attrEx":"","nodeType":"empty","attrName":"", "desc":"下一段落样式", "class":"")
			,("field":"Personal","name":"w:personal","obj":Personal,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"指定在电子邮件上下文中使用父样式时，默认情况下使用父样式来格式化来自一个或多个用户的所有邮件文本", "class":"")
			,("field":"PersonalCompose","name":"w:personalCompose","obj":PersonalCompose,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"指定在电子邮件上下文中使用父样式时，默认情况下可以使用父样式来格式化电子邮件中的新邮件文本", "class":"")
			,("field":"PersonalReply","name":"w:personalReply","obj":PersonalReply,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"生成新答复时，默认情况下可以使用父样式来格式化电子邮件中的现有邮件文本", "class":"")
			,("field":"QFormat","name":"w:qFormat","obj":QFormat,"attrEx":"","nodeType":"empty","attrName":"", "desc":"是否将此样式视为主要样式", "class":"")
			,("field":"TblStyle","name":TblStyle.NodeName,"obj":TblStyle,"attrEx":"","nodeType":"","attrName":"", "desc":"表格样式", "class":"TtblStylePr")
			,("field":"pPr","name":pPr.NodeName,"obj":pPr,"attrEx":"","nodeType":"","attrName":"", "desc":"段落格式", "class":"TwpPr")
			,("field":"rPr","name":rPr.NodeName,"obj":rPr,"attrEx":"","nodeType":"","attrName":"", "desc":"字体属性", "class":"TwrPr")
			,("field":"TrPr","name":TrPr.NodeName,"obj":TrPr,"attrEx":"","nodeType":"","attrName":"", "desc":"表格行属性", "class":"TwTrPr")
			,("field":"TblPr","name":TblPr.NodeName,"obj":TblPr,"attrEx":"","nodeType":"","attrName":"", "desc":"表格样式", "class":"TwTblPr")
			,("field":"TcPr","name":TcPr.NodeName,"obj":TcPr,"attrEx":"","nodeType":"","attrName":"", "desc":"单元格样式", "class":"TwTcPr")
			,("field":"Rsid","name":"w:rsid","obj":Rsid,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"SemiHidden","name":"w:semiHidden","obj":SemiHidden,"attrEx":"","nodeType":"empty","attrName":"", "desc":"是否在主用户界面中隐藏此样式.", "class":"")
			,("field":"UiPriority","name":"w:uiPriority","obj":UiPriority,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"使用该优先级以升序对所有可用样式进行排序.", "class":"")
			,("field":"UnhideWhenUsed","name":"w:unhideWhenUsed","obj":UnhideWhenUsed,"attrEx":"","nodeType":"empty","attrName":"", "desc":"当文档内容使用此样式时，是否应删除半隐藏属性.", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	StyleID;
	Default;
	wType;
	CustomStyle ;

	//Nodes
	Name;
	Aliases;
	AutoRedefine;
	BasedOn;
	Hidden;
	Link;
	Locked;
	Next;
	Personal;
	PersonalCompose;
	PersonalReply;
	QFormat;
	TblStyle;
	pPr;
	rPr;
	TrPr;
	TblPr;
	TcPr;
	Rsid;
	SemiHidden;
	UiPriority;
	UnhideWhenUsed;
End;

///////////////////////////////////////////////////////////////
/// TDocPartObj
///////////////////////////////////////////////////////////////
type TDocPartObj=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:docPartObj');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"docPartGallery","name":"w:docPartGallery","obj":docPartGallery,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"docPartUnique","name":"w:docPartUnique","obj":docPartUnique,"attrEx":"","nodeType":"empty","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	docPartGallery;
	docPartUnique;
End;

///////////////////////////////////////////////////////////////
/// TSdtPr
///////////////////////////////////////////////////////////////
type TSdtPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:sdtPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		rPr := new TwrPr(self, 'w:rPr');
		docPartObj := new TDocPartObj(self, 'w:docPartObj');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		rPr.InitRootNode(node);
		docPartObj.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"rPr","name":rPr.NodeName,"obj":rPr,"attrEx":"","nodeType":"","attrName":"", "desc":"字体属性", "class":"TwrPr")
			,("field":"ID","name":"w:id","obj":ID,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"docPartObj","name":docPartObj.NodeName,"obj":docPartObj,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TDocPartObj")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	rPr;
	ID;
	docPartObj;
End;

///////////////////////////////////////////////////////////////
/// TSdtEndPr
///////////////////////////////////////////////////////////////
type TSdtEndPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:sdtEndPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		rPr := new TwrPr(self, 'w:rPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		rPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"rPr","name":rPr.NodeName,"obj":rPr,"attrEx":"","nodeType":"","attrName":"", "desc":"字体属性", "class":"TwrPr")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	rPr;
End;

///////////////////////////////////////////////////////////////
/// TSdtContent
///////////////////////////////////////////////////////////////
type TSdtContent=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:sdtContent');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TTableContentImpl
///////////////////////////////////////////////////////////////
type TTableContentImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:sdt');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		sdtPr := new TSdtPr(self, 'w:sdtPr');
		sdtEndPr := new TSdtEndPr(self, 'w:sdtEndPr');
		sdtContent := new TSdtContent(self, 'w:sdtContent');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		sdtPr.InitRootNode(node);
		sdtEndPr.InitRootNode(node);
		sdtContent.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"sdtPr","name":sdtPr.NodeName,"obj":sdtPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TSdtPr")
			,("field":"sdtEndPr","name":sdtEndPr.NodeName,"obj":sdtEndPr,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TSdtEndPr")
			,("field":"sdtContent","name":sdtContent.NodeName,"obj":sdtContent,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"TSdtContent")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	sdtPr;
	sdtEndPr;
	sdtContent;
End;

///////////////////////////////////////////////////////////////
/// TTabStopsImpl
///////////////////////////////////////////////////////////////
type TTabStopsImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tabs');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Tabs := array();
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"Tabs","name":"w:tab","obj":Tabs,"attrEx":"","nodeType":"","attrName":"","arrObj":"array", "desc":"", "class":"TTabStop")
			) union ExtNodes;
	End;

	//Attributes

	//Nodes
	Tabs;
End;

///////////////////////////////////////////////////////////////
/// TTabStop
///////////////////////////////////////////////////////////////
type TTabStop=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:tab');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Val", "w:val", Val, "Specifies the type of custom tab stop, which determines the behavior of the tab stop and the alignment which shall be applied to text entered at the current custom tab stop."),("leader", "w:leader", leader, "Specifies the character which shall be used to fill in the space created by a tab which ends at this custom tab stop. This character shall be repeated as required to completely fill the tab spacing generated by the tab character."),("Position", "w:pos", Position, "Specifies the position of the current custom tab stop with respect to the current page margins. ")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Val;
	leader;
	Position;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TNumber
///////////////////////////////////////////////////////////////
type TNumber=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:num');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("numId", "w:numId", numId, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"abstractNumId","name":"w:abstractNumId","obj":abstractNumId,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	numId;

	//Nodes
	abstractNumId;
End;

///////////////////////////////////////////////////////////////
/// TLevel
///////////////////////////////////////////////////////////////
type TLevel=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:lvl');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		pPr := new TwpPr(self, 'w:pPr');
		rPr := new TwrPr(self, 'w:rPr');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		pPr.InitRootNode(node);
		rPr.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("ilvl", "w:ilvl", ilvl, "内容是否包含小数。"),("tentative", "w:tentative", tentative, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"start","name":"w:start","obj":start,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"给定编号级别定义中父编号级别使用的编号的起始值。", "class":"")
			,("field":"numFmt","name":"w:numFmt","obj":numFmt,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"编号类型（单极、多级、项目编号等）。", "class":"")
			,("field":"lvlText","name":"w:lvlText","obj":lvlText,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"编号文本内容格式，如（%1.%2.%3.%4）。", "class":"")
			,("field":"lvlJc","name":"w:lvlJc","obj":lvlJc,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"", "class":"")
			,("field":"pPr","name":pPr.NodeName,"obj":pPr,"attrEx":"","nodeType":"","attrName":"", "desc":"段落格式", "class":"TwpPr")
			,("field":"rPr","name":rPr.NodeName,"obj":rPr,"attrEx":"","nodeType":"","attrName":"", "desc":"字体属性", "class":"TwrPr")
			) union ExtNodes;
	End;

	//Attributes
	ilvl;
	tentative;

	//Nodes
	start;
	numFmt;
	lvlText;
	lvlJc;
	pPr;
	rPr;
End;

///////////////////////////////////////////////////////////////
/// TNumStyleImpl
///////////////////////////////////////////////////////////////
type TNumStyleImpl=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'w:abstractNum');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		lvl := new TLevel(self, 'w:lvl');
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
		lvl.InitRootNode(node);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("abstractNumId", "w:abstractNumId", abstractNumId, "latentStyles编号ID(编号段落的外观和行为)")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"nsid","name":"w:nsid","obj":nsid,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"disable", "class":"")
			,("field":"multiLevelType","name":"w:multiLevelType","obj":multiLevelType,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"编号类型", "class":"")
			,("field":"tmpl","name":"w:tmpl","obj":tmpl,"attrEx":"w:val","nodeType":"","attrName":"", "desc":"该元素指定了一个唯一的十六进制代码，该代码可用于确定应用程序用户界面中显示该抽象编号定义的位置。", "class":"")
			,("field":"lvl","name":lvl.NodeName,"obj":lvl,"attrEx":"","nodeType":"","attrName":"", "desc":"编号级别的外观和行为", "class":"TLevel")
			) union ExtNodes;
	End;

	//Attributes
	abstractNumId;

	//Nodes
	nsid;
	multiLevelType;
	tmpl;
	lvl;
End;

///////////////////////////////////////////////////////////////
/// TExcelTable
///////////////////////////////////////////////////////////////
type TExcelTable=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'table');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Xmlns", "xmlns", Xmlns, ""),("Mc", "xmlns:mc", Mc, ""),("Ignorable", "mc:Ignorable", Ignorable, ""),("Xr", "xmlns:xr", Xr, ""),("Xr3", "xmlns:xr3", Xr3, ""),("Id", "id", Id, ""),("Name", "name", Name, ""),("DisplayName", "displayName", DisplayName, ""),("Ref", "ref", Ref, ""),("HeaderRowCount", "HeaderRowCount", HeaderRowCount, ""),("TotalsRowShown", "totalsRowShown", TotalsRowShown, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return array(("field":"AutoFilter","name":"autoFilter","obj":AutoFilter,"attrEx":"ref","nodeType":"","attrName":"", "desc":"", "class":"")
			) union ExtNodes;
	End;

	//Attributes
	Xmlns;
	Mc;
	Ignorable;
	Xr;
	Xr3;
	Id;
	Name;
	DisplayName;
	Ref;
	HeaderRowCount;
	TotalsRowShown;

	//Nodes
	AutoFilter;
End;

///////////////////////////////////////////////////////////////
/// TTableStyle
///////////////////////////////////////////////////////////////
type TTableStyle=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'tableStyleInfo');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Name", "tableName", Name, ""),("TableStyle", "name", TableStyle, ""),("ShowFirstColumn", "showFirstColumn", ShowFirstColumn, ""),("ShowLastColumn", "showLastColumn", ShowLastColumn, ""),("ShowRowStripes", "showRowStripes", ShowRowStripes, ""),("ShowColumnStripes", "showColumnStripes", ShowColumnStripes, ""),("HeaderRowCount", "HeaderRowCount", HeaderRowCount, ""),("TotalsRowShown", "totalsRowShown", TotalsRowShown, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	Property TableName read Name write writeName;
	Function writeName(n);
	Begin
		Name := class(TSXml).CurCodePageToUtf8(n);
	End;

	//Attributes
	Name;
	TableStyle;
	ShowFirstColumn;
	ShowLastColumn;
	ShowRowStripes;
	ShowColumnStripes;
	HeaderRowCount;
	TotalsRowShown;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TBreak
///////////////////////////////////////////////////////////////
type TBreak=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'brk');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		Max := 16383;
		Man := 1;
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Id", "id", Id, ""),("Max", "max", Max, ""),("Man", "man", Man, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Id;
	Max;
	Man;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TProtect
///////////////////////////////////////////////////////////////
type TProtect=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'sheetProtection');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("Password", "password", Password, ""),("AlgorithmName", "algorithmName", AlgorithmName, ""),("HashValue", "hashValue", HashValue, ""),("SaltValue", "saltValue", SaltValue, ""),("SpinCount", "spinCount", SpinCount, ""),("Sheet", "sheet", Sheet, ""),("EditObjects", "objects", EditObjects, ""),("EditScenarios", "scenarios", EditScenarios, ""),("FormatCells", "formatCells", FormatCells, ""),("FormatColumns", "formatColumns", FormatColumns, ""),("FormatRows", "formatRows", FormatRows, ""),("InsertColumns", "insertColumns", InsertColumns, ""),("InsertRows", "insertRows", InsertRows, ""),("InsertHyperlinks", "insertHyperlinks", InsertHyperlinks, ""),("DeleteColumns", "deleteColumns", DeleteColumns, ""),("DeleteRows", "deleteRows", DeleteRows, ""),("SelectLockedCells", "selectLockedCells", SelectLockedCells, ""),("Sort", "sort", Sort, ""),("AutoFilter", "autoFilter", AutoFilter, ""),("PivotTables", "pivotTables", PivotTables, ""),("SelectUnLockedCells", "selectUnlockedCells", SelectUnLockedCells, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	Password;
	AlgorithmName;
	HashValue;
	SaltValue;
	SpinCount;
	Sheet;
	EditObjects;
	EditScenarios;
	FormatCells;
	FormatColumns;
	FormatRows;
	InsertColumns;
	InsertRows;
	InsertHyperlinks;
	DeleteColumns;
	DeleteRows;
	SelectLockedCells;
	Sort;
	AutoFilter;
	PivotTables;
	SelectUnLockedCells;

	//Nodes
End;

///////////////////////////////////////////////////////////////
/// TCalcPr
///////////////////////////////////////////////////////////////
type TCalcPr=class(NodeInfo)
	Function Create(); overload;
	Begin
		Create(nil, 'calcPr');
	End;

	Function Create(p, name); overload;
	Begin
		Class(NodeInfo).Create(p, name);
		Init();
	End;

	Function Init();
	Begin
		//TODO...
	End;

	Function InitRootNode(node);
	Begin
		RootObj := node;
	End;

	Property CalCId read readXMLCalCId write writeXMLCalCId;
	Function readXMLCalCId();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('CalCId'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLCalCId);
	End;

	Function writeXMLCalCId(str);
	Begin
		XMLCalCId := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property CalcMode read readXMLCalcMode write writeXMLCalcMode;
	Function readXMLCalcMode();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('CalcMode'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLCalcMode);
	End;

	Function writeXMLCalcMode(str);
	Begin
		XMLCalcMode := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property RefMode read readXMLRefMode write writeXMLRefMode;
	Function readXMLRefMode();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('RefMode'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLRefMode);
	End;

	Function writeXMLRefMode(str);
	Begin
		XMLRefMode := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property Iterate read readXMLIterate write writeXMLIterate;
	Function readXMLIterate();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('Iterate'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLIterate);
	End;

	Function writeXMLIterate(str);
	Begin
		XMLIterate := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property IterateCount read readXMLIterateCount write writeXMLIterateCount;
	Function readXMLIterateCount();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('IterateCount'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLIterateCount);
	End;

	Function writeXMLIterateCount(str);
	Begin
		XMLIterateCount := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property IterateDelta read readXMLIterateDelta write writeXMLIterateDelta;
	Function readXMLIterateDelta();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('IterateDelta'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLIterateDelta);
	End;

	Function writeXMLIterateDelta(str);
	Begin
		XMLIterateDelta := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property CalcOnSave read readXMLCalcOnSave write writeXMLCalcOnSave;
	Function readXMLCalcOnSave();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('CalcOnSave'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLCalcOnSave);
	End;

	Function writeXMLCalcOnSave(str);
	Begin
		XMLCalcOnSave := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property FullPrecision read readXMLFullPrecision write writeXMLFullPrecision;
	Function readXMLFullPrecision();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('FullPrecision'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLFullPrecision);
	End;

	Function writeXMLFullPrecision(str);
	Begin
		XMLFullPrecision := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ConCurrentCalc read readXMLConCurrentCalc write writeXMLConCurrentCalc;
	Function readXMLConCurrentCalc();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ConCurrentCalc'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLConCurrentCalc);
	End;

	Function writeXMLConCurrentCalc(str);
	Begin
		XMLConCurrentCalc := class(TSXml).CurCodePageToUtf8(str);
	End;

	Property ConCurrentManualCount read readXMLConCurrentManualCount write writeXMLConCurrentManualCount;
	Function readXMLConCurrentManualCount();
	Begin
		tmpVal := class(TSXml).Utf8ToCurCodePage(Value('ConCurrentManualCount'));
		if not ifNil(tmpVal) then return tmpVal;
		return class(TSXml).Utf8ToCurCodePage(XMLConCurrentManualCount);
	End;

	Function writeXMLConCurrentManualCount(str);
	Begin
		XMLConCurrentManualCount := class(TSXml).CurCodePageToUtf8(str);
	End;

	Function GetAttrs(); override;
	Begin
		HandleAttrs();
		return array(("CalCId", "calcId", XMLCalCId, ""),("CalcMode", "calcMode", XMLCalcMode, ""),("RefMode", "refMode", XMLRefMode, ""),("Iterate", "iterate", XMLIterate, ""),("IterateCount", "iterateCount", XMLIterateCount, ""),("IterateDelta", "iterateDelta", XMLIterateDelta, ""),("CalcOnSave", "calcOnSave", XMLCalcOnSave, ""),("FullPrecision", "fullPrecision", XMLFullPrecision, ""),("ConCurrentCalc", "conCurrentCalc", XMLConCurrentCalc, ""),("ConCurrentManualCount", "conCurrentManualCount", XMLConCurrentManualCount, "")) union ExtAttr;
	End;

	Function GetChildren(); override;
	Begin
		HandleChildren();
		return ExtNodes;
	End;

	//Attributes
	XMLCalCId;
	XMLCalcMode;
	XMLRefMode;
	XMLIterate;
	XMLIterateCount;
	XMLIterateDelta;
	XMLCalcOnSave;
	XMLFullPrecision;
	XMLConCurrentCalc;
	XMLConCurrentManualCount;

	//Nodes
End;

///////////////////////////////////////////////////////////////////////////////////////////
///DOCX文档实现

Type TRange = Class
	Function Create();overload;
	Begin
		Create(nil);
	End;
	
	Function Create(t);overload;
	Begin
		//array(("pNode":nodeObj, "pIndex":p, "rNode":nodeObj, "rIndex":r))
		Init(t);
	End;
	
	Function Init(t);
	Begin
		RunArr_ := t;
	End;
	
	///清除全部选中内容
	Function Clear();
	Begin
		_clear(0);//清除全部w:r
	End;
	
	Property Font read readFont;
	Function readFont();
	Begin
		if ifNil(rPr_) then
			rPr_ := new TwrPr();
		return rPr_;
	End;
	
	Property Text read readText write writeText;
	Function readText();
	Begin
		return _text(RunArr_);
	End;
	
	Function writeText(txt);
	Begin
		r := RunArr_[0:0,:];
		_clear(1);//只保留第1段
		run := new TRun(r[0]['rNode']);
		run.SetText(txt);
		return r;
	End;
	
	///应用字体样式
	Function Apply();
	Begin
		if not ifObj(rPr_) then return;
		arr := rPr_.Marshal();
		if length(arr['attributes']) or length(arr['children']) then Begin
			for i:=0 to length(RunArr_)-1 do Begin
				rPr := class(TSXml).GetNode(RunArr_[i]['rNode'], 'w:rPr', 'first');
				class(TSXml).UpdateNode(rPr, arr['attributes'], arr['children']);
			End;
		End;
	End;
	
	Function _clear(first);
	Begin
		for i:=first to length(RunArr_)-1 do Begin
			pNode := RunArr_[i]['pNode'];
			pNode.DeleteChild(RunArr_[i]['rNode']);
			rNode := pNode.FirstChildElement('w:r');
			if not ifObj(rNode) then
				pNode.Parent().DeleteChild(pNode);
		End;
	End;
	
	rPr_;//字体格式
	RunArr_;
End;

Type DocObject = Class
	Function Create();
	Begin
		pageNo_ := 0;
		linePos_ := 0.;
	End;
	
	Function Name();
	Begin
		return name_;
	End;
	
	///修改属性，包括样式、边框、底纹、字体等
	Function Apply();virtual;
	Begin
	End;
	
	///前一个对象
	Function Prev();virtual;
	Begin
		return _next_prev_Impl(node_.PrevElement(name_));
	End;
	
	///下一个对象
	Function Next();virtual;
	Begin
		return _next_prev_Impl(node_.NextElement(name_));
	End;
	
	///添加批注
	///obj：TDocComment对象
	///返回：成功 true
	Function AddComment(obj);
	Begin
		id := obj.ID;
		r := _split_range(obj.sPos, obj.SelectLength);
		cnt := length(r);
		if cnt then Begin
			rNode := r[0]['rNode'];
			beg := rNode.Parent().InsertBeforeChild(rNode, 'element', 'w:commentRangeStart');
			beg.SetAttribute('w:id', id);
			
			rNode := r[cnt-1]['rNode'];
			eNode := rNode.Parent().InsertAfterChild(rNode, 'element', 'w:commentRangeEnd');
			eNode.SetAttribute('w:id', id);
			
			r := rNode.Parent().InsertAfterChild(eNode, 'element', 'w:r');
			cr := r.InsertFirstChild('element', 'w:commentReference');
			cr.SetAttribute('w:id', id);
			return true;
		End;
		return false;
	End;
	
	///修订插入
	///obj：TRevision对象
	///返回：成功 true
	Function AddRevision(obj);
	Begin
		obj.NodeName := 'w:ins';
		obj.name_ := obj.NodeName;
		r := _split_range(obj.sPos, 0);
		if length(r) then Begin
			rNode := r[length(r)-1]['rNode'];
			node := rNode.Parent().InsertAfterChild(rNode, obj.Marshal());
		End
		else Begin
			pPr := node_.FirstChildElement('w:pPr');
			if ifObj(pPr) then
				node := node_.InsertAfterChild(pPr, obj.Marshal());
			else
				node := node_.InsertFirstChild(obj.Marshal());
			rNode := node.NextElement('w:r');
		End;
		if ifObj(rNode) then Begin
			data := rNode.Marshal();
			node2 := node.InsertFirstChild(data[0]);
		End
		else Begin
			node2 := node.InsertEndChild('element', 'w:r');
		End;
		run := new TRun(node2);
		run.SetText(obj.InsText_, true);
		obj.Init(node);
		return true;
	End;

	///修订删除
	///obj：TRevision对象
	///返回：成功 true，失败 false
	Function DelRevision(obj);
	Begin
		r := _split_range(obj.sPos, obj.SelectLength);
		for i:=0 to length(r)-1 do Begin
			rNode := r[i]['rNode'];
			delNode := rNode.Parent().InsertAfterChild(rNode, obj.Marshal());
			rXml := string(rNode.Data());
			rXml := ReplaceStr(rXml, '<w:t>', '<w:delText>');
			delNode.InsertFirstChild(rXml);
			rNode.Parent().DeleteChild(rNode);
		End;
		return length(r);
	End;
	
	Function _next_prev_Impl(n);
	Begin
		if ifObj(n) then Begin
			case name_ of
			'w:p':
				p := new TParagraph(p);
			'w:tbl':
				p := new TTable(n);
			'w:r':
				p := new TRun(n);
			'w:del','w:ins':
				p := new TRevision(n);
			End;
			if ifObj(p) then Begin
				p.name_ := name;
				p.node_ := n;
			End;
		End;
		return p;
	End;
	
	///文本内容
	Function Text();virtual;
	Begin
		r := TextArray();
		return _text(r);
	End;
	
	//所有文字信息（包括位置信息）
	//返回：table(包括w:r节点)
	Function TextArray();virtual;
	Begin
		r := array();
		node := node_.FirstChildElement('w:r');
		while ifObj(node) do Begin
			r[ind]['pNode'] := node_;
			r[ind]['pIndex'] := -1;
			r[ind]['rNode'] := node;
			r[ind]['rIndex'] := ind;
			ind++;
			node := node.NextElement('w:r');
		End;
		return r;
	End;
	
	///段落中插入文字
	Function AddText(sPos, txt);
	Begin
		if sPos < 0 then Begin	//段落后追加
			lastNode := node_.LastChild('w:r');
			if ifObj(lastNode) then Begin
				rNode := _duplicate_r(lastNode);
			End
			else Begin
				rNode := node_.InsertEndChild('element','w:r');
				p := new TParagraph(node_);
				p.CopyRunFormat(false, rNode);
			End;
			run := new TRun(rNode);
			run.SetText(txt);
			t := array(('pNode':node_, 'pIndex':-1, 'rNode':rNode, 'rIndex':-1));
			return new TRange(t);
		End;
		obj := new TRevision();
		obj.sPos := sPos;
		obj.InsText := txt;
		AddRevision(obj);//插入文字
		t := obj.Accept();
		return new TRange(t);
	End;
	
	///返回：TRange对象,（TBody、TParagraph、TCell）全部内容
	Function Range();overload;
	Begin
		t := TextArray();
		if not istable(t) then
			return nil;
		return new TRange(t);
	End;
	
	///sPos：起始位置
	///rangeLength：内容长度
	///返回：TRange对象，此函数非只读，执行此函数会重新调整段落中TRun结构
	Function Range(sPos, rangeLength);overload;
	Begin
		t :=  _split_range(sPos, rangeLength);
		if not istable(t) then
			return nil;
		return new TRange(t);
	End;
	
	///返回文档中的位置
	Function Node();
	Begin
		return node_;
	End;
	
	Function _split_range(sPos, rangeLength);
	Begin
		t := array();
		if not ifInt(sPos) or not ifInt(rangeLength) or sPos < 0 then 
			return t;
		r := TextArray();
		rSize := 0;
		for i:=0 to length(r)-1 do Begin
			run := new TRun(r[i]['rNode']);
			txt := run.Text();
			if class(TSXml).IsUtf8() then
				txt := UTF8ToAnsi(txt);
			txtLen := lengthW(txt);
			if rangeLength >= 0 and sPos + rangeLength <= rSize then Begin
				return t;
			End;
			if rangeLength = 0 then Begin	//w:ins情况
				if sPos >= txtLen + rSize then Begin	//前
					rSize += txtLen;
					t[0] := r[i];
				End
				else Begin //一分为二，取头部
					if sPos = rSize then 
						return t;//正好文档开头
					t[0] := r[i];
					r2 := _duplicate_r(r[i]['rNode']);
					_adjust_r(r[i]['rNode'], 0, sPos - rSize);
					_adjust_r(r2, sPos - rSize, txtLen);
					return t;
				End;
			End
			else Begin	//w:del情况
				if rangeLength < 0 or (sPos <= rSize and sPos + rangeLength >= rSize + txtLen) then Begin //包含全部w:r
					t[ length(t) ] := r[i];
					rSize += txtLen;
				End
				else if sPos >= txtLen + rSize then Begin	//前
					rSize += txtLen;
				End
				else if sPos >= rSize and sPos < rSize + txtLen and sPos + rangeLength >= rSize + txtLen then Begin //一分为二，取尾部
					if sPos = rSize then Begin	//正好整个run
						t[ length(t) ] := r[i];
					End
					else Begin //一分为二，取尾部
						r2 := _duplicate_r(r[i]['rNode']);
						_adjust_r(r[i]['rNode'], 0, sPos - rSize);
						_adjust_r(r2, sPos - rSize, txtLen);
						tmp := r[i];
						tmp['rNode'] := r2;
						tmp['rIndex'] := r[i]['rIndex'] + 1;
						t[ length(t) ] := tmp;
					End;
					rSize += txtLen;
				End
				else if sPos + rangeLength <= rSize + txtLen then Begin
					if sPos + rangeLength = rSize + txtLen then Begin //正好整个run
						t[ length(t) ] := r[i];
					End
					else if sPos <= rSize then Begin //一分为二，取头部
						t[ length(t) ] := r[i];
						r2 := _duplicate_r(r[i]['rNode']);
						_adjust_r(r[i]['rNode'], 0, rangeLength - (rSize - sPos));
						_adjust_r(r2, rangeLength - (rSize - sPos), txtLen);
					End
					else Begin //一分为三，取中间
						r2 := _duplicate_r(r[i]['rNode']);
						r3 := _duplicate_r(r2);
						_adjust_r(r[i]['rNode'], 0, sPos - rSize);
						_adjust_r(r2, sPos - rSize, rangeLength);
						_adjust_r(r3, sPos - rSize + rangeLength, txtLen);
						tmp := r[i];
						tmp['rNode'] := r2;
						tmp['rIndex'] := r[i]['rIndex'] + 1;
						t[0] := tmp;
					End;
					rSize += txtLen;
					return t;
				End
			End;
		End;
		return t;
	End;
	
	//复制w:r节点
	Function _duplicate_r(node);
	Begin
		data := node.Marshal();
		return node.Parent().InsertAfterChild(node, data[0]);
	End;
	
	//调整w:r节点
	Function _adjust_r(node, sPos, rangeLength);
	Begin
		rSize := 0;
		ePos := sPos + rangeLength;
		delT := array();
		tNode := node.FirstChildElement('w:t');
		while ifObj(tNode) do Begin
			txt := UTF8ToAnsi(tNode.GetText());
			txtLen := lengthW(txt);
			if sPos >= rSize + txtLen then Begin //删除头部文字
				delT[cnt++] := tNode;
				rSize += txtLen;
			End
			else if sPos >= rSize and sPos < rSize + txtLen and ePos <= rSize + txtLen then Begin //只取中间文字
				if sPos <> rSize or ePos <> rSize + txtLen then Begin //文字内容有变化
					mCnt := ePos - sPos;
					if sPos = rSize then
						nStr := leftstr(txt, mCnt);
					else if ePos = rSize + txtLen then 
						nStr := rightstr(txt, mCnt);
					else
						nStr := midstr(txt, sPos - rSize + 1, mCnt);
					tNode.SetValue(AnsiToUTF8(nStr));
				End;
				rSize += txtLen;
			End
			else if sPos >= rSize and sPos < rSize + txtLen and ePos > rSize + txtLen then Begin //只取尾巴文字
				if sPos <> rSize then Begin //文字内容有变化
					mCnt := txtLen - (sPos - rSize);
					nStr := rightstr(txt, mCnt);
					tNode.SetValue(AnsiToUTF8(nStr));
				End;
			End
			else if sPos < rSize and ePos >= rSize + txtLen then Begin //取值范围
				rSize += txtLen;
			End
			else Begin //删除尾部文字
				delT[cnt++] := tNode;
			End
			rSize += txtLen;
			tNode := tNode.NextElement('w:t');
		End;
		
		for i:=0 to length(delT)-1 do 
			node.DeleteChild(delT[i]);
	End;
	
	node_;
	name_:string;
	pageNo_;	//页码
	linePos_;	//行位置
End;

Type TRevision = Class(DocObject, TRevisionImpl)
	Function Create();overload;
	Begin
		Create(nil);
	End;
	
	Function Create(node);overload;
	Begin
		Init(node);
	End;
	
	Function Init(node);
	Begin
		node_ := node;
		name_ := 'w:del';
		if ifObj(node_) then Begin
			name_ := node_.GetName();
			paragraph_ := new TParagraph(node_);
		End;
		Date := class(TSXml).GetDatetimeStr(now());
		Class(TRevisionImpl).Create(nil, name_);
		InitRootNode(node);
	End;
	
	Property InsText read readInsText write writeInsText;
	Function readInsText();
	Begin
		return class(TSXml).Utf8ToCurCodePage(InsText_);
	End;
	
	Function writeInsText(txt);
	Begin
		InsText_ := class(TSXml).CurCodePageToUtf8(txt);
	End;
	
	///修订类型
	///返回：string, 删除:'del'、添加:'ins'
	Function Act();
	Begin
		return name_ = 'w:del' ? 'del' : 'ins';
	End;
	
	///文字内容
	Function Text();override;
	Begin
		return paragraph_.Text();
	End;
	
	///接受修订
	Function Accept();
	Begin
		if name_ = 'w:del' then Begin
			node_.Parent().DeleteChild(node_);
			return nil;
		End;
		r := array();
		//w:ins
		runs := paragraph_.GetRuns();
		node := node_;
		for i:=0 to length(runs)-1 do Begin
			rData := runs[i].node_.Marshal();
			node := node.Parent().InsertAfterChild(node, rData[0]);//接受修订，复制<w:r>...</w:r>
			r[length(r)] := array('pNode':node.Parent(), 'pIndex':-1, 'rNode':node, 'rInde':-1);
		End;
		node_.Parent().DeleteChild(node_);
		return r;
	End;
	
	///拒绝修订
	Function Reject();
	Begin
		if name_ = 'w:ins' then Begin
			node_.Parent().DeleteChild(node_);
			return;
		End;
		//w:del
		runs := paragraph_.GetRuns();
		node := node_;
		for i:=0 to length(runs)-1 do Begin
			rXml := string(runs[i].node_.Data());
			rXml := ReplaceStr(rXml, '<w:delText>', '<w:t>');
			node := node.Parent().InsertAfterChild(node, rXml);//接受修订，复制<w:r>...</w:r>
		End;
		node_.Parent().DeleteChild(node_);
	End;
	
	paragraph_;
	CommentID:integer;
	sPos:integer;
	SelectLength:integer;
	InsText_:string;
End;

Type TDocComment = Class(TDocCommentImpl)
	Function Create();overload;
	Begin
		Create(nil);
	End;
	
	Function Create(node);overload;
	Begin
		node_ := node;
		name_ := 'w:comment';
		Date := class(TSXml).GetDatetimeStr(now());
		Class(TDocCommentImpl).Create(nil, name_);
		InitRootNode(node);
	End;
	
	///批注文字内容
	Function Text();
	Begin
		txt := '';
		rCnt := 0;
		for i:= 0 to length(commentsArray_)-1 do Begin
			if commentsArray_[i]['Name'] := 'w:r' then Begin
				if rCnt and commentsArray_[i]['pIndex'] <> commentsArray_[i-1]['pIndex'] then 
					txt += '\n';
				run := new TRun(commentsArray_[i]['rNode']);
				txt += run.Text();
				rCnt ++;
			End;
		End;
		return txt;
	End;
	
	///删除批注
	Function Delete();
	Begin
		commentsArray_[0]['pNode'].DeleteChild( commentsArray_[0]['rNode'] );
		cnt := length(commentsArray_) - 1;
		r := commentsArray_[cnt]['rNode'].Next('w:r');
		if ifObj(r) then Begin
			commentReference := r.FirstChildElement('w:commentReference');
			if ifObj(commentReference) then Begin
				r.DeleteChild( commentReference );
			End;
		End;
		commentsArray_[cnt]['pNode'].DeleteChild( commentsArray_[cnt]['rNode'] );
		if not ifObj(r.FirstChildElement()) then Begin
			r.Parent().DeleteChild( r );
		End;
	End;

	CommentID:integer;
	sPos:integer;
	SelectLength:integer;
	commentsArray_;
End;

Type TDocComments = Class
	Function Create(t);
	Begin
		commentsArray_ := t;
		hash_ := sselect distinct ['ID'] from commentsArray_ where ['ID'] >= 0 end;
	End;

	///文档中全部的批注信息个数
	Function Count();
	Begin
		return length(hash_);
	End;
	
	///文档中指定批注信息
	///index：第index个批注信息
	///返回：TDocComment对象
	Function Comment(index);overload;
	Begin
		if index < 0 or index >= length(hash_) then 
			return nil;
		id := hash_[index];
		r := select thisrowindex as 'Index' from commentsArray_ where ['ID'] = id end;
		if not istable(r) or length(r) <> 2 then 
			return nil;
		t := select * from commentsArray_ where thisrowindex <= r[1]['Index'] and thisrowindex >= r[0]['Index'] end;
		o := new TDocComment();
		o.commentsArray_ := t;
		o.CommentID := t[0]['ID'];
		return o;
	End;

	hash_;
	commentsArray_;
End;

//w:pPr
//        'w:pStyle', 'w:keepNext', 'w:keepLines', 'w:pageBreakBefore',
//        'w:framePr', 'w:widowControl', 'w:numPr', 'w:suppressLineNumbers',
//        'w:pBdr', 'w:shd', 'w:tabs', 'w:suppressAutoHyphens', 'w:kinsoku',
//        'w:wordWrap', 'w:overflowPunct', 'w:topLinePunct', 'w:autoSpaceDE',
//        'w:autoSpaceDN', 'w:bidi', 'w:adjustRightInd', 'w:snapToGrid',
//        'w:spacing', 'w:ind', 'w:contextualSpacing', 'w:mirrorIndents',
//        'w:suppressOverlap', 'w:jc', 'w:textDirection', 'w:textAlignment',
//        'w:textboxTightWrap', 'w:outlineLvl', 'w:divId', 'w:cnfStyle',
//        'w:rPr', 'w:sectPr', 'w:pPrChange'

//w:p
Type TWHyperLink = Class(TWHyperLinkImpl)
	Function AddRun(txt, newLine);
	Begin
		o := new TRun();
		//o.Parent := self;
		NewChildNode( array("field":"", "name":"w:r", "obj":o, "attrEx":"", "nodeType":"") );
		if txt then
			o.SetText(txt);
		if newLine then
			o.Br.Type := '';
		return o;
	End;
End;

Type TParagraph = Class(DocObject, TParagraphImpl)
	Function Create();overload;
	Begin
		Create(nil);
	End;
	
	Function Create(node);overload;
	Begin
		Init(node);
	End;
	
	Function Init(node);
	Begin
		node_ := node;
		name_ := 'w:p';
		Class(TParagraphImpl).Create(nil, 'w:p');
		InitRootNode(node);
	End;

	Function Root(); override;
	Begin
		return node_;
	End;
	
	Property Format read readFormat;
	Function readFormat();
	Begin
		return pPr;
	End;
	
	Property Font read readFont;
	Function readFont();
	Begin
		return pPr.rPr;
	End;
	
	///修改段落
	Function Apply(); override;
	Begin
		arr := Marshal();
		class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']);
		CopyRunFormat(false, nil);
	End;
	
	///修改段落内容
	///返回：TRun对象
	Function SetText(str);
	Begin
		t := GetRuns();
		for i:=1 to length(t)-1 do Begin
			node_.DeleteChild(t[i].node_);
		End;
		if length(t) then 
			rNode := t[0].node_;
		else
			rNode := node_.InsertEndChild('element', 'w:r');
		run := new TRun(rNode);
		run.SetText(str);
		return rNode;
	End;
	
	///制表位TTabStops对象
	///返回：TTabStops对象
	//<w:tabs>
    //  <w:tab w:val="left" w:pos="2160" /> 
    //  <w:tab w:val="left" w:pos="5040" /> 
	//</w:tabs>
	Function TabStops();
	Begin
		node := class(TSXml).GetNode(node_, 'w:pPr/w:tabs');
		if not ifObj(node) then 
			return nil;
		return new TTabStops(node);
	End;
	
	Function setParagraphText(rNode, tNode, txt);
	Begin
		if not ifObj(tNode) then Begin
			tNode := rNode.FirstChildElement('w:t');
			if not ifObj(tNode) then
				tNode := rNode.InsertFirstChild('element', 'w:t', txt);
		End
		else
			tNode.SetValue(txt);
	End;
	
	///所有TRun对象列表
	///返回：TRun对象列表
	Function GetRuns();
	Begin
		t := array();//TRun Array
		node := node_.FirstChildElement('w:r');
		while ifObj(node) do Begin
			n := node;
			name := node.GetName();
			node := node.NextElement('w:r');
			if name = 'w:r' then Begin
				run := new TRun(n);
			End
			else if name = 'w:ins' then Begin
				r := n.FirstChildElement('w:r');
				if not ifObj(r) then continue;
				run := new TRun(r);
			End
			else 
				continue;
			t[ length(t) ] := run;
		End;
		return t;
	End;
	
	///TRun对象
	///返回：TRun对象
	Function GetRun(i);
	Begin
		runs := GetRuns();
		if i < 0 or i >= length(runs) then
			return nil;
		return runs[i];
	End;
	
	///段落中添加内容
	///返回：TRun对象
	Function AddRun(txt, newLine);
	Begin
		o := new TRun();
		//o.Parent := self;
		NewChildNode( array("field":"", "name":"w:r", "obj":o, "attrEx":"", "nodeType":"") );
		if txt then
			o.SetText(txt);
		if newLine then
			o.Br.Type := '';
		return o;
	End;

	///段落添加<w:hyperlink>
	///返回：TWHyperLink
	Function AddHyperLink();
	Begin
		o := new TWHyperLink();
		NewChildNode( array("field":"", "name":"w:r", "obj":o, "attrEx":"", "nodeType":"") );
		return o;
	End;
	
	///在段落对象后面追加TRun对象
	///返回TRun对象
	Function AppendRun();
	Begin
		node := node_.InsertEndChild('element','w:r');
		return new TRun(node);
	End;
	
	///段落中全部的修改标记(修订删除、修订插入)
	///返回：TRevision对象列表，array(TRevision...);
	Function Revisions();overload;
	Begin
		return getDocumentObjects(node_, array('w:del', 'w:ins'));
	End;
	
	///段落指定修改标记(修订删除、修订插入)
	///index：第index个修改标记
	///返回：TRevision对象
	Function Revisions(index);overload;
	Begin
		return getDocumentObject(node_, array('w:del', 'w:ins'), index);
	End;
	
	///段落中所有文本框
	///返回：TTextBox对象数组
	Function TextBoxs();overload;
	Begin
		r := array();
		runs := GetRuns();
		for i:=0 to length(runs)-1 do Begin
			node := class(TSXml).GetNode(runs[i].node_, 'mc:AlternateContent/mc:Fallback/w:pict/v:shape/v:textbox/w:txbxContent');
			if ifObj(node) then Begin
				nodeEx := class(TSXml).GetNode(runs[i].node_, 'mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:txbx/w:txbxContent');
				box := new TTextBox(node);
				box.Init(node_, nodeEx);
				r[length(r)] := box;
			End
			else Begin
				node := class(TSXml).GetNode(runs[i].node_, 'w:pict/v:shape/v:textbox/w:txbxContent');
				if ifObj(node) then Begin
					box := new TTextBox(node);
					box.Init(node_, nil);
					r[length(r)] := box;
				End;
			End;
		End;
		return r;
	End;
	
	///段落中指定文本框
	///index：第index个文本框
	///返回：TTextBox对象
	Function TextBoxs(index);overload;
	Begin
		r := TextBoxs();
		if index >= 0 and index < length(r) then
			return r[index];
		return nil;
	End;
	
	///清除段落格式、字体格式
	Function ClearFormat();
	Begin
		pPr := node_.FirstChildElement('w:pPr');
		//清除段落格式
		if ifObj(pPr) then 
			node_.DeleteChild(pPr);
		//清除字体格式
		runs := GetRuns();
		for i:=0 to length(runs)-1 do Begin
			runs[i].ClearFormat();
		End;
	End;
	
	///添加BookMark
	///返回：BookMark的名称，string
	Function AddBookMark(bookMarkID);
	Begin
		pPr := node_.FirstChildElement('w:pPr');
		if ifObj(pPr) then 
			markStart := node_.InsertAfterChild(pPr, 'element', 'w:bookmarkStart');
		else
			markStart := node_.InsertFirstChild('element', 'w:bookmarkStart');
		name := '_Toc' $ bookMarkID;
		markStart.SetAttribute('w:name', name);
		markStart.SetAttribute('w:id', bookMarkID);
		markEnd := node_.InsertEndChild('element', 'w:bookmarkEnd');
		markEnd.SetAttribute('w:id', bookMarkID);
		return name;
	End;
	
	Function CopyRunFormat(del, toRunNode);
	Begin
		rPr := class(TSXml).GetNode(node_, 'w:pPr/w:rPr');
		dom := ifObj(rPr) ? rPr.Marshal() : array();
		if ifObj(toRunNode) then Begin
			_copyRunFormat(toRunNode, dom, del);
			return;
		End;
		
		//复制到所有run
		runs := GetRuns();
		for i:=0 to length(runs)-1 do 
			_copyRunFormat(runs[i].node_, dom, del);
	End;
	
	//不能复用TRun::CopyFontFormat(),该函数是完全替换字体属性
	//本函数是追加、修改字体属性
	Function _copyRunFormat(toRunNode, dom, del);
	Begin
		tNode := toRunNode.FirstChildElement('w:t');
		rPr2 := toRunNode.FirstChildElement('w:rPr');
		if del and ifObj(rPr2) then
			rPr2.node_.DeleteChildren();
		else if ifObj(tNode) and not ifObj(rPr2) then
			rPr2 := class(TSXml).GetNode(toRunNode, 'w:rPr', 'first');
		if istable(dom) and ifObj(rPr2) then
			class(TSXml).UpdateNode(rPr2, dom[0]['attributes'], dom[0]['children']);
	End;
End;

//w:tabs
Type TTabStops = Class(DocObject, TTabStopsImpl)
	Function Create();overload;
	Begin
		Create(nil);
	End;
	
	Function Create(node);overload;
	Begin
		Class(TTabStopsImpl).Create(nil, 'w:tabs');
		tabArr := array();
		if ifObj(node) then Begin
			parent_ := node.Parent();
			node_ := node;
			n := node_.FirstChildElement('w:tab');
			while ifObj(n) do Begin
				tab := new TTabStop();
				tabArr[ length(tabArr) ] := array("field":"TTabStop", "name":"w:tab", "obj":tab, "attrEx":"", "nodeType":"", "node":n);
				n := n.NextElement();
			End;
			Tabs := tabArr;
			InitRootNode(node);
		End;
	End;
	
	Function Create(parentObj, name);overload;
	Begin
		Class(TTabStopsImpl).Create(parentObj, name);
		tabArr := array();
	End;
	
	///删除制表符
	///ind：integer，索引
	Function Clear(ind);
	Begin
		if ind>=0 and ind < length(Tabs) then Begin
			if ifObj(Tabs[i]['node']) then
				node_.DeleteChild(Tabs[i]['node']);
			Tabs := select * from Tabs where thisrowindex <> ind end;
		End;
	End;
	
	///添加制表符
	///ind：integer，索引
	///tab：TTabStop对象
	Function Add(ind, tab);
	Begin
		a := array("field":"TTabStop", "name":"w:tab", "obj":tab, "attrEx":"", "nodeType":"", "node":nil);
		if ind = 0 then Begin
			if ifObj(node_) then
			a['node'] := node_.InsertFirstChild('element', 'w:tab');
			Tabs := array(a) union Tabs;
		End
		else if ind < 0 or ind >= length(Tabs) then Begin
			if ifObj(node_) then 
				a['node'] := node_.InsertEndChild('element', 'w:tab');
			Tabs union= array(a);
		End
		else Begin
			node := Tabs[length(Tabs)-1]['node'];
			if length(Tabs) and ifObj(node) then 
				a['node'] := node_.InsertAfterChild(node, 'element', 'w:tab');
			arr := Tabs[:ind-1,:];
			arr[ length(arr) ] := a;
			b := Tabs[ind:,:];
			Tabs := arr union b;
		End;
		if ifObj(a['node']) then Begin
			arr := tab.Marshal();
			class(TSXml).UpdateNode(a['node'], arr['attributes'], arr['children']);
		End;
		return tab;
	End;
	
	///获取制表符
	///返回：TTabStop对象
	Function Get(ind);
	Begin
		if ind >= 0 or ind < length(Tabs) then 
			return Tabs[ind]['obj'];
		return nil;
	End;
	
	///获取全部制表符列表
	///返回：TTabStop对象列表，array(TTab...)
	Function TabStops();
	Begin
		return sselect ['obj'] from Tabs end;
	End;
	
	///刷新制表符
	Function Flush();
	Begin
		if ifObj(node_) then Begin
			for i:=0 to length(Tabs)-1 do Begin
				arr := Tabs[i]['obj'].Marshal();
				class(TSXml).UpdateNode(Tabs[i]['node'], arr['attributes'], arr['children']);
			End;
		End;
	End;
End;

//w:r
Type TRun = Class(DocObject, TRunImpl)
	Function Create();overload;
	Begin
		Create(nil);
	End;
	
	Function Create(node);overload;
	Begin
		Init(node);
	End;
	
	Function Create(pNode, name);overload;
	Begin
		Class(TRunImpl).Create(nil, 'w:r');
	End;
	
	Function Init(node);
	Begin
		node_ := node;
		name_ := 'w:r';
		Class(TRunImpl).Create(nil, 'w:r');
		InitRootNode(node);
	End;
	
	Property Font read readFont;
	Function readFont();
	Begin
		return rPr;
	End;
	
	///应用格式
	Function Apply(); override;
	Begin
		arr := Marshal();
		class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']);
	End;
	
	///添加tab
	Function AddTab();
	Begin
		n := node_.InsertFirstChild('element', 'w:tab');
	End;
	
	///添加文字
	///[isUtf8]：可选参数，当前字符集是否utf8，缺省false
	Function AddText(txt, isUtf8);
	Begin
		str := txt;
		if not isUtf8 and not class(TSXml).IsUtf8() then 
			str := class(TSXml).CurCodePageToUtf8(txt);
		if ifObj(node_) then Begin
			_insertText(str, false);
			return;
		End;
		lines := str2array(str,'\n');
		T := lines[0];
		if _preserve(T) then
			Space := 'preserve';
		for i:=1 to length(lines)-1 do Begin
			NewChildNode( array("field":"", "name":"w:br", "obj":1, "attrEx":"", "nodeType":"empty") );
			NewChildNode( array("field":"", "name":"w:t", "obj":lines[i], "attrEx":"", "nodeType":"pcdata") );
			if _preserve(lines[i]) then
				NewChildNode( array("field":"", "name":"w:t", "obj":'preserve', "attrEx":"xml:space", "nodeType":"") );
		End;
	End;
	
	///修改文字
	///[isUtf8]：可选参数，当前字符集是否utf8，缺省false
	Function SetText(txt, isUtf8);
	Begin
		str := txt;
		if not isUtf8 and not class(TSXml).IsUtf8() then 
			str := class(TSXml).CurCodePageToUtf8(txt);
		if ifObj(node_) then Begin
			ClearText();//删除原来文字
			_insertText(str, false);//添加文字
			return;
		End;
		ExtNodes := array();
		T := nil;
		AddText(str, true);
	End;
	
	Function _insertText(txt, first);
	Begin
		lines := str2array(txt,'\n');
		for i:=0 to length(lines)-1 do Begin
			t := TrimRight(lines[i]);
			if i=0 then Begin
				if first then
					tNode := node_.InsertFirstChild('element', 'w:t', t);
				else
					tNode := node_.InsertEndChild('element', 'w:t', t);
			End
			else Begin
				tNode := node_.InsertAfterChild(tNode, 'element', 'w:br');//换行符号
				tNode := node_.InsertAfterChild(tNode, 'element', 'w:t', t);
			End;
		End;
	End;
	
	///文字内容
	Function Text();override;
	Begin
		txt := '';
		tNode := node_.FirstChildElement();
		while ifObj(tNode) do Begin
			name := tNode.GetName();
			if name = 'w:t' or name = 'w:delText' then 
				txt += tNode.GetText();
			//if name = 'w:br' then
			//	txt += '\n';
			tNode := tNode.NextElement();
		End;
		if not class(TSXml).IsUtf8() then
			return class(TSXml).Utf8ToCurCodePage(txt);
		return txt;
	End;
	
	///清除字体格式
	Function ClearFormat();
	Begin
		rPr := node_.FirstChildElement('w:rPr');
		if ifObj(rPr) then 
			node_.DeleteChild(rPr);
	End;
	
	Function CopyFontFormat(fromRun);
	Begin
		ClearFormat();
		rPr := fromRun.node_.FirstChildElement('w:rPr');
		if not ifObj(rPr) then 
			return;
		
		data := rPr.Marshal();
		node_.InsertFirstChild(data[0]);
	End;

	///清除全部文字内容
	Function ClearText();
	Begin
		if ifObj(node_) then Begin
			n := node_.FirstChildElement('w:t');
			while ifObj(n) do Begin
				next := n.NextElement('w:t');
				node_.DeleteChild(n);
				n := next;
			End;
		End;
	End;

End;

Type TPicture = Class(DocObject, TPictureImpl)
	Function Create();overload;
	Begin
		Create(nil);
	End;
	
	Function Create(node);overload;
	Begin
		Init(node);
	End;
	
	Function Init(node);
	Begin
		node_ := node;
		name_ := 'w:p';
		Width := 0.;
		Height := Width;
		Class(TPictureImpl).Create(nil, 'w:p');
		InitRootNode(node);
	End;
	
	Property Format read readFormat;
	Function readFormat();
	Begin
		return Run.Drawing.WInline.Graphic.GraphicData.Pic.spPr;
	End;
	
	///修改图片格式
	///[docx]：当前文档对象，为空指当前文档
	Function Apply(docx); override;
	Begin
		document := docx;
		if not ifObj(document) then Begin
			document := TOfficeApi().GetDocument();
			if not ifObj(document) then
				return;
		End;
		arr := Marshal();
		class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']);
		if ifBinary(Image) then Begin	//修改图片内容
			node := class(TSXml).GetNode(node_,'w:r/w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip');
			if ifObj(node) then
				rid := node.GetAttribute('r:embed');
			xml := document.Zip().Get('word/_rels/document.xml.rels');
			picFileName := class(TSXml).FindRelationshipTarget(xml, rid);
			if ifstring(picFileName) then Begin
				pic := document.Zip().Get('word/' + picFileName);
				if ifObj(pic) then
					pic.Data := Image;
			End;
		End;
	End;
	
	Function ScaledDimensions(image);
	Begin
		ETU := 360045;//1cm单位
		maxX := 17.0;//水平方向17cm
		maxY := 23.0;//垂直方向23cm
		imageW := image.Width() / 28.346 * ETU;
		imageH := image.Height() / 28.346 * ETU;
        if Width <= 0 and Height <= 0 then Begin	//图像缺省大小
            widthVal := imageW;
			heightVal := imageH;
		End
		else Begin	//用户设置了图片尺寸
			widthVal := ETU * Width;
			heightVal := ETU * Height;
			if Width <= 0 and imageH and imageW then Begin	//按照图片比例自动缩放
				scaling_factor := imageW / imageH;
				widthVal := round(heightVal * scaling_factor);
			End;

			if Height <= 0 and imageH and imageW then Begin	//按照图片比例自动缩放
				scaling_factor := imageW / imageH;
				heightVal := round(widthVal / scaling_factor);
			End;
		End;
		//缺省大小（用户没有设置尺寸，同时TSImage也没有识别图片尺寸）
		if widthVal = 0 and heightVal = 0 then
			widthVal := 15 * ETU;
		if widthVal = 0 then
			widthVal := heightVal * 2;
		if heightVal = 0 then 
			heightVal := widthVal / 3;

		//缩放
		ratio := 1;
		if widthVal > maxX * ETU then 
			ratio := maxX * ETU / widthVal;
		if heightVal > maxY * ETU then Begin
			r2 :=  maxY * ETU / heightVal;
			if r2 < ratio then 
				ratio := r2;
		End;
		if ratio < 1 then Begin
			heightVal *= ratio;
			widthVal *= ratio;
		End;
		//println('w={}-{},maxx={},   h={}-{},maxh={},ratio={}',integer(imageW),integer(widthVal),15 * ETU, integer(imageH),integer(heightVal),23 * ETU,ratio);
        return array(integer(widthVal), integer(heightVal));
	End;
	
	Image;//图片内容（Binary）
	Descr;
	Width;//厘米
	Height;//厘米
End;

Type TChart = Class(TChartImpl)
	Function Create();overload;
	Begin
		Create(nil);
	End;

	Function Create(node);overload;
	Begin
		Class(TChartImpl).Create(nil, 'w:p');
		pNode := node;
		self.C := true;
		InitRootNode(node);
	End;
	
	Function Init(docx, node, cNode);
	Begin
		pNode := node;
		if not ifObj(cNode) then
			return;
		IsWord_ := docx.IsWord();
		rId := cNode.GetAttribute('r:id');
		relsObj := docx.Zip().Get('word/_rels/document.xml.rels');
		Target := class(TSXml).FindRelationshipTarget(relsObj, rId);
		if ifNil(Target) then
			return;
		chartFileName := getChartFileName(Target);
		xmlObj := docx.Zip().Get(chartFileName);
		if not ifObj(xmlObj) then 
			return;
		plotAreaNode := class(TSXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:plotArea');
		if ifObj(plotAreaNode) then Begin
			child := plotAreaNode.FirstChildElement();
			while ifObj(child) do Begin
				nodename := child.GetName();
				if rightstr(nodename,5) = 'Chart' then Begin
					if leftstr(nodename,2) = 'c:' then
						self.C := true;
					ChartNode := child;
					break;
				End;
				child := child.NextElement();
			End;
		End;
	End;

	Function Serialize(isWord);
	Begin
		Plotarea := TOfficeObj('TPlotarea');
		Plotarea.Layout := true;
		isWord_ := isWord;
		Type := lowercase(Type);
		case Type of
		'area','areastacked','areapercentstacked','area3d','area3dstacked','area3dpercentstacked','bar','barstacked','barpercentstacked',
		'bar3dclustered','bar3dstacked','bar3dpercentstacked','bar3dconeclustered','bar3dconestacked','bar3dconepercentstacked',
		'bar3dpyramidclustered','bar3dpyramidstacked','bar3dpyramidpercentstacked','bar3dcylinderclustered','bar3dcylinderstacked',
		'bar3dcylinderpercentstacked','col','colstacked','colpercentstacked','col3d','col3dclustered','col3dstacked','col3dpercentstacked',
		'col3dcone','col3dconeclustered','col3dconestacked','col3dconepercentstacked','col3dpyramid','col3dpyramidclustered',
		'col3dpyramidstacked','col3dpyramidpercentstacked','col3dcylinder','col3dcylinderclustered','col3dcylinderstacked',
		'col3dcylinderpercentstacked','bubble','bubble3d':
			drawBaseChart(Plotarea);
		'doughnut':
		Begin
			drawExtChart(Plotarea, 'c:doughnutChart');
			Plotarea.chart.HoleSize := 75;
		End
		'line':
			drawLineChart(Plotarea);
		'pie3d':
			drawExtChart(Plotarea, 'c:pie3DChart');
		'pie':
			drawExtChart(Plotarea, 'c:pieChart');
		'pieofpiechart':
		Begin
			drawExtChart(Plotarea, 'ofPieChart');
			Plotarea.chart.OfPieType := 'pie';
		End
		'barofpiechart':
		Begin
			drawExtChart(Plotarea, 'c:ofPieChart');
			Plotarea.chart.OfPieType := 'bar';
		End
		'radar':
			drawRadarChart(Plotarea);
		'scatter':
			drawScatterChart(Plotarea);
		'surface3d','wireframesurface3d':
			drawSurface3DChart(Plotarea, 'c:surface3DChart');
		'contour','wireframecontour':
			drawSurface3DChart(Plotarea, 'c:surfaceChart');
		End;
		Plotarea.SpPr.noFill := true;
		Plotarea.SpPr.Ln.noFill := true;
		Plotarea.SpPr.EffectLst := true;
	End;

	///添加图表Series数据
	Function AddSeries(Name, Categories, Value);
	Begin
		SerName := name;
		catArr := Categories;
		if not class(TSXml).IsUtf8() then Begin
			if name and ifstring(name) then
				SerName := class(TSXml).CurCodePageToUtf8(name);
			if ifstring(catArr) then
				catArr := class(TSXml).CurCodePageToUtf8(catArr);
			else if istable(catArr) then Begin
				for i:=0 to length(catArr)-1 do Begin
					if ifstring(catArr[i]) then
						catArr[i] := class(TSXml).CurCodePageToUtf8(catArr[i]);
				End;
			End;
		End;
			
		Series union= array(("Name":SerName,"Categories":catArr,"Values":Value));
		return length(Series);
	End;
	
	///清除图表Series数据
	Function ClearSeries();
	Begin
		Series := array();
	End;
	
	///删除图表Series数据
	Function RemoveSeries(i);
	Begin
		cnt := length(Series);
		if i < 0 or i >= cnt then 
			return length(Series);

		tmp := Series[:i-1,:];
		tmp union= Series[i+1:,:];
		Series := tmp;
		return length(Series);
	End;
	
	Function NewExcelFile();
	Begin
		Excel := new TSExcelFile();
		[err, errmsg] := Excel.NewFile();
		if err then 
			Excel := nil;
	End;
	
	///更新图表
	Function Apply(docx);
	Begin
		if not ifObj(ChartNode) then 
			return;
		if ifstring(Title) and Title <> '' then
			UpdateTitle(class(TSXml).CurCodePageToUtf8(Title));
		//不同的图表，数据区较复杂
		if not istable(Series) then return;
		ser := self.C ? 'c:ser' : 'ser';
		serNode := ChartNode.FirstChildElement(ser);
		if not ifObj(serNode) then return;//没有缺省数据
		//存在Excel扩展数据文件
		node := xmlObj.FirstChildElement('c:chartSpace').FirstChildElement('c:externalData');
		if ifObj(node) then Begin
			rId := node.GetAttribute('r:id');
			fName := ExtractFileName(chartFileName);
			rels := 'word/charts/_rels/' + fName + '.rels';
			chartId := leftstr(fName, length(fName) - 4);
			chartId := rightstr(chartId, length(chartId) - 5);
			relsObj := docx.Zip().Get(rels);
			if ifObj(relsObj) then Begin
				target := class(TSXml).FindRelationshipTarget(relsObj, rId);//../embeddings/Workbook2.xlsx
				excelFileName := ReplaceStr(target, '..','word');
				excelObj := docx.Zip().Get(excelFileName);
				if ifObj(excelObj) then
					NewExcelFile();
			End;
		End;
		
		//更新数据区
		dom := serNode.Marshal();
		for i:=0 to length(Series)-1 do Begin
			if i then
				serNode := serNode.InsertAfterChild(serNode, dom[0]);
			removeOldSer(serNode);
			ser := TOfficeObj('TSer');
			ser.IDx := i;
			ser.Ord := i;
			setTx(ser.Tx.StrRef, Series[i]['Name'], i);
			n := serNode.FirstChildElement('c:cat');
			if ifObj(n) then Begin
				_setCat(ser.Cat, i);
				_setVal(ser.Val, i);
			End;
			
			n := serNode.FirstChildElement('c:xVal');
			if ifObj(n) then Begin
				_setCat(ser.XVal, i);
				_setVal(ser.YVal, i);
			End;
			updData := ser.Marshal();
			class(TSXml).UpdateNode(serNode, updData['attributes'], updData['children']);
		End;
		
		//删除多余的<c:ser>
		node := serNode.NextElement(ser);
		while ifObj(node) do Begin
			ChartNode.DeleteChild(node);
			node := serNode.NextElement(ser);
		End;
		
		//修改内嵌的excel文件
		AddExcelFile(docx, xmlObj, chartId);
	End;
	
	Function removeOldSer(node);
	Begin
		task := array('c:tx','c:cat','c:val','c:xVal','c:xYal');
		for i:=0 to length(task)-1 do begin
			n := node.FirstChildElement(task[i]);
			if ifObj(n) then
				n.DeleteChildren();
		End;
	End;
	
	Function AddExcelFile(docx, chartXml, chartId);
	Begin
		//内嵌excel数据文件
		if not ifObj(Excel) then 
			return;
		[err, data] := Excel.Zip().Save2Mem();
		if err then 
			return;
		rId := 'rId1';
		workBook := 'embeddings/Workbook1.xlsx';
		fileCnt := 1 + vselect countof( ['FileName'] ) from docx.Zip().Files() where AnsiStartsText('word/embeddings/Workbook', ['FileName']) end;
		ctXml := docx.Zip().Get('[Content_Types].xml');
		class(TSXml).AddDefaultContentType(ctXml, 'xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
		externalDataNode := chartXml.FirstChildElement('c:chartSpace').FirstChildElement('c:externalData');
		if not ifObj(externalDataNode) then
			chartXml.FirstChildElement('c:chartSpace').InsertEndChild('<c:externalData r:id="rId1"><c:autoUpdate val="0"/></c:externalData>');
		else Begin
			rId := externalDataNode.GetAttribute('r:id');
		End;
		rels := 'word/charts/_rels/chart' $ chartId $ '.xml.rels';
		relsObj := docx.Zip().Get(rels);
		if not ifObj(relsObj) then Begin
			rId := 'rId1';
			xmlStr := '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Target="../embeddings/Workbook1.xlsx" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/package" Id="rId1"/>
</Relationships>';
			docx.Zip().Add(rels, xmlStr);
			if fileCnt > 1 then Begin
				workBook := 'embeddings/Workbook' $ fileCnt $ '.xlsx';
				relsObj := docx.Zip().Get(rels);
				node := relsObj.FirstChildElement('Relationships').FirstChildElement('Relationship');
				node.SetAttribute('Target', '../' + workBook);
			End;
		End
		else Begin
			target := class(TSXml).FindRelationshipTarget(relsObj, rId);
			if ifNil(target) then Begin
				[maxRid, tg, id] := class(TSXml).FindRelationshipRid(relsObj,'');
				if fileCnt > 1 then
					workBook := 'embeddings/Workbook' $ fileCnt $ '.xlsx';
				maxRid ++;
				class(TSXml).AddRelationshipRid(relsObj, '../' + workBook, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/package', 'rId' $ maxRid, nil);
			End
			else 
				workBook := ReplaceStr(target, '../', '');
		End;
		xlsx := docx.Zip().Get('word/' + workBook);
		if ifObj(xlsx) then 
			xlsx.Data := data;	//更新xlsx文件
		else
			docx.Zip().Add('word/' + workBook, data);	//添加xlsx文件
	End;

	///修改图表标题
	Function UpdateTitle(t);
	Begin
		task := array('c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:t', 'pcdata', t);
		class(TSXml).SetNodeValue(ChartNode.Root(), task);
	End;
	
	///显示数据表
	///b：bool型，是否显示数据表
	Function ShowDataTable(b);
	Begin
		if not ifObj(plotAreaNode) then 
			return;
		node := plotAreaNode.FirstChildElement('c:dTable');
		if ifObj(node) then 
			plotAreaNode.DeleteChild(node);
		if not b then 
			return;
		xmlStr := '<c:dTable>
				<c:showHorzBorder val="1" />
				<c:showVertBorder val="1" />
				<c:showOutline val="1" />
				<c:showKeys val="1" />
				<c:txPr>
					<a:bodyPr rot="0" spcFirstLastPara="0" vertOverflow="ellipsis" vert="horz" wrap="square" anchor="ctr" anchorCtr="1" />
					<a:lstStyle />
					<a:p>
						<a:pPr>
							<a:defRPr lang="zh-CN" sz="1000" b="0" i="0" u="none" strike="noStrike" kern="1200" baseline="0">
								<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:pPr>
					</a:p>
				</c:txPr>
			</c:dTable>';
		plotAreaNode.InsertEndChild(xmlStr);
	End;
private	
	Function getChartFileName(f);
	Begin
		if leftstr(f,5) = 'word/' then 
			return f;
		if leftstr(f,3) = '../' then 
			return 'word/' + f[4:];
		if f[1] = '/' then
			return f[2:];
		if leftstr(f,7) = 'charts/' then
			return 'word/' + f;
		return f;
	End;
	
	Function updateValue(task);
	Begin
		for i:=0 to length(task)-1 do Begin
			if not C then 
				task[i][0] := ReplaceStr(task[i][0], 'c:', '');
			class(TSXml).SetNodeValue(xmlObj_, task[i]);
		End;
	End;
	
	Function getLegendPosition(t);
	Begin
		m := array("bottom":    "b",
			"left":      "l",
			"right":     "r",
			"top":       "t",
			"top_right": "tr");
		return m[t];
	End;
	
	Function drawSurface3DChart(o, name);
	Begin
		o.chart.NodeName := name;
		setChartSer(o);
		o.chart.Axid := 754001152;
		o.chart.Axid2 := 753999904;
		o.chart.Axid3 := 832256642;
		setCatAx(o.CatAx);
		setValAx(o.ValAx);
		setSerAx(o.SerAx);
		if Type in array( 'wireframesurface3d', 'wireframecontour' ) then 
			o.chart.Wireframe := true;
	End;

	Function drawScatterChart(o);
	Begin
		o.chart.NodeName := 'c:scatterChart';
		o.chart.ScatterStyle := 'smoothMarker';
		o.chart.VaryColors := false;
		setChartSer(o);
		setDLbls(o.chart.DLbls);
		o.chart.Axid := 754001152;
		o.chart.Axid2 := 753999904;
		setCatAx(o.CatAx);
		setValAx(o.ValAx);
	End;

	Function drawRadarChart(o);
	Begin
		o.chart.NodeName := 'c:radarChart';
		o.chart.RadarStyle := 'marker';
		o.chart.VaryColors := false;
		setChartSer(o);
		setDLbls(o.chart.DLbls);
		o.chart.Axid := 754001152;
		o.chart.Axid2 := 753999904;
		setCatAx(o.CatAx);
		setValAx(o.ValAx);
	End;
	
	Function drawExtChart(o, name);
	Begin
		o.chart.NodeName := name;
		o.chart.VaryColors := VaryColors;
		setChartSer(o);
		setDLbls(o.chart.DLbls);
	End;

	Function drawLineChart(o);
	Begin
		o.chart.NodeName := 'c:lineChart';
		o.chart.Grouping := getGrouping(Type);
		o.chart.VaryColors := false;
		setChartSer(o);
		setDLbls(o.chart.DLbls);
		o.chart.Smooth := false;
		o.chart.Axid := 754001152;
		o.chart.Axid2 := 753999904;
		setCatAx(o.CatAx);
		setValAx(o.ValAx);
	End;
	
	Function drawBaseChart(o);
	Begin
		o.chart.BarDir := getBarDir(Type);
		o.chart.Grouping := getGrouping(Type);
		o.chart.VaryColors := VaryColors;
		o.chart.Overlap := getVaryColors(Type);
		o.chart.Axid := 754001152;
		o.chart.Axid2 := 753999904;
		o.chart.NodeName := getChartName(Type);
		setChartSer(o);
		o.chart.Shape := getSharp(Type);
		setDLbls(o.chart.DLbls);
		setCatAx(o.CatAx);
		setValAx(o.ValAx);
	End;
	
	Function setSerAx(SerAx);
	Begin
		SerAx.AxID := 832256642;
		SerAx.Scaling.Max := YAxis.Max;
		SerAx.Scaling.Min := YAxis.Min;
		SerAx.Scaling.Orientation := YAxis.ReverseOrder ? 'maxMin' : 'minMax';
		SerAx.Del := YAxis.None;
		SerAx.AxPos := XAxis.ReverseOrder ? 't' : 'b';
		SerAx.TickLblPos := 'nextTo';
		drawPlotAreaSpPr(SerAx.SpPr);
		drawPlotAreaTxPr(SerAx.TxPr);
		SerAx.CrossAx := 753999904;
	End;
	
	Function setCatAx(CatAx);
	Begin
		CatAx.AxID := 754001152;
		CatAx.Scaling.Max := XAxis.Max;
		CatAx.Scaling.Min := XAxis.Min;
		CatAx.Scaling.Orientation := XAxis.ReverseOrder ? 'maxMin' : 'minMax';
		CatAx.Del := 0;//XAxis.None;
		CatAx.AxPos := XAxis.ReverseOrder ? 't' : 'b';
		CatAx.NumFmt.FormatCode := 'General';
		CatAx.NumFmt.SourceLinked := true;
		CatAx.MajorTickMark := 'none';
		CatAx.MinorTickMark := 'none';
		CatAx.TickLblPos := 'nextTo';
		drawPlotAreaSpPr(CatAx.SpPr);
		drawPlotAreaTxPr(CatAx.TxPr);
		CatAx.CrossAx := 753999904;
		CatAx.Crosses := 'autoZero';
		CatAx.Auto := true;
		CatAx.LblAlgn := 'ctr';
		CatAx.LblOffset := 100;
		CatAx.NoMultiLvlLbl := false;
		if XAxis.MajorGridlines then
			drawPlotAreaSpPr(CatAx.MajorGridlines.SpPr);
		if XAxis.MinorGridlines then
			drawPlotAreaSpPr(CatAx.MinorGridlines.SpPr);
		if XAxis.TickLabelSkip then
			CatAx.TickLabelSkip := XAxis.TickLabelSkip;
	End;
	
	Function setValAx(ValAx);
	Begin
		ValAx.AxID := 753999904;
		ValAx.Scaling.Max := YAxis.Max;
		ValAx.Scaling.Min := YAxis.Min;
		if ifint(YAxis.LogBase) and YAxis.LogBase >= 2 and YAxis.LogBase <= 1000 then
			ValAx.Scaling.LogBase := YAxis.LogBase;
		ValAx.Scaling.Orientation := YAxis.ReverseOrder ? 'maxMin' : 'minMax';
		ValAx.Del := YAxis.None;
		ValAx.AxPos := YAxis.ReverseOrder ? 'r' : 'l';
		ValAx.NumFmt.FormatCode := chartValAxNumFmtFormatCode(Type);
		ValAx.NumFmt.SourceLinked := true;
		ValAx.MajorTickMark := 'none';
		ValAx.MinorTickMark := 'none';
		ValAx.TickLblPos := 'nextTo';
		drawPlotAreaSpPr(ValAx.SpPr);
		drawPlotAreaTxPr(ValAx.TxPr);
		ValAx.CrossAx := 754001152;
		ValAx.Crosses := 'autoZero';
		ValAx.CrossBetween := chartValAxCrossBetween(Type);
		if XAxis.MajorGridlines then
			drawPlotAreaSpPr(ValAx.MajorGridlines.SpPr);
		if XAxis.MinorGridlines then
			drawPlotAreaSpPr(ValAx.MinorGridlines.SpPr);
		ValAx.MajorUnit := YAxis.MajorUnit;
		if Type in array('contour', 'wireframecontour') then
			ValAx.TickLblPos := 'none';
	End;
	
	Function chartValAxCrossBetween(t);
	Begin
		m := array(
		'area':                        'midCat',
		'areastacked':                 'midCat',
		'areapercentstacked':          'midCat',
		'area3d':                      'midCat',
		'area3dstacked':               'midCat',
		'area3dpercentstacked':        'midCat',
		'bar':                         'between',
		'barstacked':                  'between',
		'barpercentstacked':           'between',
		'bar3dclustered':              'between',
		'bar3dstacked':                'between',
		'bar3dpercentstacked':         'between',
		'bar3dconeclustered':          'between',
		'bar3dconestacked':            'between',
		'bar3dconepercentstacked':     'between',
		'bar3dpyramidclustered':       'between',
		'bar3dpyramidstacked':         'between',
		'bar3dpyramidpercentstacked':  'between',
		'bar3dcylinderclustered':      'between',
		'bar3dcylinderstacked':        'between',
		'bar3dcylinderpercentstacked': 'between',
		'col':                         'between',
		'colstacked':                  'between',
		'colpercentstacked':           'between',
		'col3d':                       'between',
		'col3dclustered':              'between',
		'col3dstacked':                'between',
		'col3dpercentstacked':         'between',
		'col3dcone':                   'between',
		'col3dconeclustered':          'between',
		'col3dconestacked':            'between',
		'col3dconepercentstacked':     'between',
		'col3dpyramid':                'between',
		'col3dpyramidclustered':       'between',
		'col3dpyramidstacked':         'between',
		'col3dpyramidpercentstacked':  'between',
		'col3dcylinder':               'between',
		'col3dcylinderclustered':      'between',
		'col3dcylinderstacked':        'between',
		'col3dcylinderpercentstacked': 'between',
		'doughnut':                    'between',
		'line':                        'between',
		'pie':                         'between',
		'pie3d':                       'between',
		'pieofpiechart':               'between',
		'barofpiechart':               'between',
		'radar':                       'between',
		'scatter':                     'between',
		'surface3d':                   'midCat',
		'wireframesurface3d':          'midCat',
		'contour':                     'midCat',
		'wireframecontour':            'midCat',
		'bubble':                      'midCat',
		'bubble3d':                    'midCat');
		return m[t];
	End;
	
	Function chartValAxNumFmtFormatCode(t);
	Begin
		m := array(
		'area':                        'General',
		'areastacked':                 'General',
		'areapercentstacked':          '0%',
		'area3d':                      'General',
		'area3dstacked':               'General',
		'area3dpercentstacked':        '0%',
		'bar':                         'General',
		'barstacked':                  'General',
		'barpercentstacked':           '0%',
		'bar3dclustered':              'General',
		'bar3dstacked':                'General',
		'bar3dpercentstacked':         '0%',
		'bar3dconeclustered':          'General',
		'bar3dconestacked':            'General',
		'bar3dconepercentstacked':     '0%',
		'bar3dpyramidclustered':       'General',
		'bar3dpyramidstacked':         'General',
		'bar3dpyramidpercentstacked':  '0%',
		'bar3dcylinderclustered':      'General',
		'bar3dcylinderstacked':        'General',
		'bar3dcylinderpercentstacked': '0%',
		'col':                         'General',
		'colstacked':                  'General',
		'colpercentstacked':           '0%',
		'col3d':                       'General',
		'col3dclustered':              'General',
		'col3dstacked':                'General',
		'col3dpercentstacked':         '0%',
		'col3dcone':                   'General',
		'col3dconeclustered':          'General',
		'col3dconestacked':            'General',
		'col3dconepercentstacked':     '0%',
		'col3dpyramid':                'General',
		'col3dpyramidclustered':       'General',
		'col3dpyramidstacked':         'General',
		'col3dpyramidpercentstacked':  '0%',
		'col3dcylinder':               'General',
		'col3dcylinderclustered':      'General',
		'col3dcylinderstacked':        'General',
		'col3dcylinderpercentstacked': '0%',
		'doughnut':                    'General',
		'line':                        'General',
		'pie':                         'General',
		'pie3d':                       'General',
		'pieofpiechart':               'General',
		'barofpiechart':               'General',
		'radar':                       'General',
		'scatter':                     'General',
		'surface3d':                   'General',
		'wireframesurface3d':          'General',
		'contour':                     'General',
		'wireframecontour':            'General',
		'bubble':                      'General',
		'bubble3d':                    'General');
		return m[t];
	End;
	
	Function drawPlotAreaTxPr(TxPr);
	Begin
		TxPr.BodyPr.Rot := -60000000;
		TxPr.BodyPr.SpcFirstLastPara := true;
		TxPr.BodyPr.VertOverflow := 'ellipsis';
		TxPr.BodyPr.Vert := 'horz';
		TxPr.BodyPr.Wrap := 'square';
		TxPr.BodyPr.Anchor := 'ctr';
		TxPr.BodyPr.AnchorCtr := true;
		TxPr.P.PPr.DefRPr.Sz := 900;
		TxPr.P.PPr.DefRPr.Bold := false;
		TxPr.P.PPr.DefRPr.Italic := false;
		TxPr.P.PPr.DefRPr.U := 'none';
		TxPr.P.PPr.DefRPr.Strike := 'noStrike';
		TxPr.P.PPr.DefRPr.Kern := 1200;
		TxPr.P.PPr.DefRPr.Baseline := 0;
		TxPr.P.PPr.DefRPr.SolidFill.SchemeClr.Val := 'tx1';
		TxPr.P.PPr.DefRPr.SolidFill.SchemeClr.LumMod := 15000;
		TxPr.P.PPr.DefRPr.SolidFill.SchemeClr.LumOff := 85000;
		TxPr.P.PPr.DefRPr.Latin.Typeface := '+mn-lt';
		TxPr.P.PPr.DefRPr.Ea.Typeface := '+mn-ea';
		TxPr.P.PPr.DefRPr.Cs.Typeface := '+mn-cs';
		TxPr.P.EndParaRPr.Lang := 'en-US';
	End;
	
	Function drawPlotAreaSpPr(SpPr);
	Begin
		SpPr.Ln.W := 9525;
		SpPr.Ln.Cap := 'flat';
		SpPr.Ln.Cmpd := 'sng';
		SpPr.Ln.Algn := 'ctr';
		SpPr.Ln.SolidFill.SchemeClr.Val := 'tx1';
		SpPr.Ln.SolidFill.SchemeClr.LumMod := 15000;
		SpPr.Ln.SolidFill.SchemeClr.LumOff := 85000;
	End;
	
	Function setChartSer(o);
	Begin
		SerArr := array();
		for i:=0 to length(Series)-1 do Begin
			ser := TOfficeObj('TSer');
			SerArr union= array(('name':'c:ser','obj':ser,'attrEx':'','nodeType':'','attrName':''));
			ser.IDx := i + Ord;
			ser.Ord := i + Ord;
			setTx(ser.Tx.StrRef, Series[i]['Name'], i);
			setSpPr(ser.SpPr, i);
			setMarker(ser.Marker, i);
			setDpt(ser, i);
			//setDLbls(ser.DLbls);
			//ser.Dlbls.Del := 1;
			//ser.InvertIfNegative := false;
			setCat(ser.Cat, i);
			setVal(ser.Val, i);
			setXVal(ser.XVal, i);
			setYVal(ser.YVal, i);
			setBubbleSize(ser.BubbleSize, i);
			setBubble3D(ser, i);
		End;
		o.chart.Ser := SerArr;
	End;
	
	Function _setExcelCellVal(cell, v);
	Begin
		//v is utf8
		if ifObj(Excel) then Begin
			Excel.SetCellValue('Sheet1', cell, class(TSXml).Utf8ToCurCodePage(v));
		End;
	End;
	
	Function setTx(strRef, name, i);
	Begin
		if not IsWord_ then Begin
			strRef.F := name;
			return;
		End;
		[err, col] := ColumnNumberToName(i + 2);
		strRef.F := 'Sheet1!$' $ col $ '$1';
		strRef.strCache.ptCount := 1;
		strRef.strCache.pt.IDx := 0;
		strRef.strCache.pt.V := name;
		_setExcelCellVal(col $ '1', name);
	End;
	
	Function setBubble3D(ser, i);
	Begin
		if Type <> 'bubble3d' then return;
		ser.Bubble3D := true;
	End;
	
	Function setBubbleSize(BubbleSize, i);
	Begin
		if not (Type in array('bubble', 'bubble3d')) then return;
		_setVal(BubbleSize, i);
	End;
	
	Function setYVal(Val, i);
	Begin
		if not (Type in array('scatter', 'bubble', 'bubble3d')) then return;
		_setVal(Val, i);
	End;
	
	Function setXVal(xVal, i);
	Begin
		if not (Type in array('scatter')) then return;
		_setCat(xVal, i);
	End;
	
	Function setVal(Val, ind);
	Begin
		if Type in array('scatter', 'bubble', 'bubble3d') then return;
		_setVal(Val, ind);
	End;
	
	Function _setVal(Val, ind);
	Begin
		data := Series[ind]['Values'];
		if ifstring(data) then
			Val.NumRef.F := data;	//excel图表（Sheet1!$C$2:$C$6）
		else if istable(data) then Begin	//word 图表
			cnt := length(data);
			//[err, axis] := ColumnNumberToName(2 * ind + 2);
			[err, axis] := ColumnNumberToName(ind + 2);
			Val.NumRef.F := format('Sheet1!$%s$2:$%s$%d', axis, axis, cnt+1);
			Val.NumRef.NumCache.PtCount := cnt;
			Val.NumRef.NumCache.formatCode := 'General';
			for i:=0 to cnt-1 do Begin
				Tpt := TOfficeObj('Tpt');
				Tpt.IDx := i;
				Tpt.V := data[i];
				//[err,cell] := CoordinatesToCellName(2*ind+2, i+2);
				[err,cell] := CoordinatesToCellName(ind+2, i+2);
				_setExcelCellVal(cell, data[i]);
				Val.NumRef.NumCache.NewChildNode( array("field":"", "name":"c:pt", "obj":Tpt, "attrEx":"", "nodeType":"") );
			End;
		End;
	End;
	
	Function setCat(Cat, ind);
	Begin
		if Type in array('scatter', 'bubble', 'bubble3d') then return;
		_setCat(Cat, ind);
	End;
	
	Function _setCat(Cat, ind);
	Begin
		Categories := Series[ind]['Categories'];
		if ifstring(Categories) then
			cat.StrRef.F := Categories;	//excel图表（Sheet1!$A$2:$A$6）
		else if istable(Categories) then Begin	//word 图表
			cnt := length(Categories);
			//[err, axis] := ColumnNumberToName(2 * ind + 1);
			cat.StrRef.F := format('Sheet1!$A$2:$A$%d', cnt+1);
			cat.StrRef.StrCache.PtCount := cnt;
			for i:=0 to cnt-1 do Begin
				Tpt := TOfficeObj('Tpt');
				Tpt.IDx := i;
				Tpt.V := Categories[i];
				[err,cell] := CoordinatesToCellName(2*ind+1, i+2);
				if ind = 0 then
					_setExcelCellVal(cell, Tpt.V);
				cat.StrRef.StrCache.NewChildNode( array("field":"", "name":"c:pt", "obj":Tpt, "attrEx":"", "nodeType":"") );
			End;
		End;
	End;
	
	Function setDLbls(DLbls);
	Begin
		if Type in array('scatter','surface3d', 'wireframesurface3d', 'contour', 'wireframecontour', 'bubble', 'bubble3d') then 
			return;
		DLbls.ShowLegendKey := ShowLegendKey;
		DLbls.ShowVal := ShowVal;
		DLbls.ShowCatName := ShowCatName;
		DLbls.ShowSerName := ShowSerName;
		DLbls.ShowBubbleSize := ShowBubbleSize;
		DLbls.ShowPercent := ShowPercent;
		DLbls.ShowLeaderLines := ShowLeaderLines;
	End;

	Function setDpt(o, ind);
	Begin
		if not (Type in array('pie','pie3d')) then return;
		data := Series[ind]['Values'];
		if ifstring(data) then Begin
			o.Dpt.IDx := 0;
			o.Dpt.Bubble3D := false;
			setPieSppr(o.Dpt.Sppr);
		End
		else if istable(data) then Begin
			cnt := length(data);
			r := array();
			for i:=0 to cnt-1 do Begin
				dpt := TOfficeObj('TDpt');
				dpt.IDx := i;
				dpt.Bubble3D := false;
				if i=0 then 
					setPieSppr(dpt.sPpr);
				r[length(r)] := array('name':'c:dPt','obj':dpt,'attrEx':'','nodeType':'','attrName':'');
			End;
			o.DptEx := r;
		End;
	End;
	
	Function setPieSppr(sPpr);
	Begin
		SpPr.SolidFill.SchemeClr.Val := 'accent1';
		SpPr.Ln.W := 25400;
		SpPr.Ln.Cap := 'rnd';
		SpPr.Ln.SolidFill.SchemeClr.Val := 'lt1';
		SpPr.Sp3D.ContourW := 25400;
		SpPr.Sp3D.ContourClr.SchemeClr.Val := 'lt1';
	End;
	
	Function setMarker(Marker, i);
	Begin
		if not (Type in array('scatter', 'line')) then return;
		if Type = 'scatter' then
			Marker.Symbol := 'circle';
		Marker.Size := 5;
		if ifstring(Series[i]['Symbol']) then
			Marker.Symbol := Series[i]['Symbol'];
		if ifint(Series[i]['Size']) then
			Marker.Size := Series[i]['Size'];
			
		if i < 6 then Begin
			marker.SpPr.SolidFill.SchemeClr.Val := 'accent' $ (i + 1);
			Marker.SpPr.Ln.W := 9252;
			Marker.SpPr.Ln.SolidFill.SchemeClr.Val := 'accent' $ (i + 1);
		End;
	End;
	
	Function setSppr(SpPr, i);
	Begin
		if Type = 'line' then Begin
			SpPr.Ln.algn := 'ctr';
			SpPr.Ln.cmpd := 'sng';
			SpPr.Ln.cap := 'rnd';
			SpPr.Ln.W := 8000;
			//SpPr.Ln.NoFill := true;
			SpPr.Ln.prstDash := 'solid';
			SpPr.Ln.round := true;
			SpPr.Ln.SolidFill.SchemeClr.Val := 'accent' $ ((Ord+i)%6+1);
			return;
		End;
		if Type = 'scatter' then Begin
			w := Series[i]['LineWidth'];
			SpPr.Ln.W := 0.25 > w || w > 999 ? 25400 : 12700 * w;
			SpPr.Ln.Cap := 'rnd';
			SpPr.Ln.SolidFill.SchemeClr.Val := 'accent' $ ((Ord+i)%6+1);
			return;
		End;
	End;
	
	Function getSharp(t);
	Begin
		m := array(
		'bar3dconeclustered':          'cone',
		'bar3dconestacked':            'cone',
		'bar3dconepercentstacked':     'cone',
		'bar3dpyramidclustered':       'pyramid',
		'bar3dpyramidstacked':         'pyramid',
		'bar3dpyramidpercentstacked':  'pyramid',
		'bar3dcylinderclustered':      'cylinder',
		'bar3dcylinderstacked':        'cylinder',
		'bar3dcylinderpercentstacked': 'cylinder',
		'col3dcone':                   'cone',
		'col3dconeclustered':          'cone',
		'col3dconestacked':            'cone',
		'col3dconepercentstacked':     'cone',
		'col3dpyramid':                'pyramid',
		'col3dpyramidclustered':       'pyramid',
		'col3dpyramidstacked':         'pyramid',
		'col3dpyramidpercentstacked':  'pyramid',
		'col3dcylinder':               'cylinder',
		'col3dcylinderclustered':      'cylinder',
		'col3dcylinderstacked':        'cylinder',
		'col3dcylinderpercentstacked': 'cylinder');
		return m[t];
	End;
	
	Function getChartName(t);
	Begin
		m := array(
		'area': 'areaChart',
		'areastacked': 'areaChart',
		'areapercentstacked': 'areaChart',
		'area3d': 'area3DChart',
		'area3dstacked': 'area3DChart',
		'area3dpercentstacked': 'area3DChart',
		'bar': 'barChart',
		'barstacked': 'barChart',
		'barpercentstacked': 'barChart',
		'bar3dclustered': 'bar3DChart',
		'bar3dstacked':  'bar3DChart',
		'bar3dpercentstacked': 'bar3DChart',
		'bar3dconeclustered': 'bar3DChart',
		'bar3dconestacked': 'bar3DChart',
		'bar3dconepercentstacked': 'bar3DChart',
		'bar3dpyramidclustered': 'bar3DChart',
		'bar3dpyramidstacked': 'bar3DChart',
		'bar3dpyramidpercentstacked': 'bar3DChart',
		'bar3dcylinderclustered': 'bar3DChart',
		'bar3dcylinderstacked': 'bar3DChart',
		'bar3dcylinderpercentstacked': 'bar3DChart',
		'col': 'barChart',
		'colstacked': 'barChart',
		'colpercentstacked': 'barChart',
		'col3d': 'bar3DChart',
		'col3dclustered': 'bar3DChart',
		'col3dstacked': 'bar3DChart',
		'col3dpercentstacked': 'bar3DChart',
		'col3dcone': 'bar3DChart',
		'col3dconeclustered': 'bar3DChart',
		'col3dconestacked': 'bar3DChart',
		'col3dconepercentstacked': 'bar3DChart',
		'col3dpyramid': 'bar3DChart',
		'col3dpyramidclustered': 'bar3DChart',
		'col3dpyramidstacked': 'bar3DChart',
		'col3dpyramidpercentstacked': 'bar3DChart',
		'col3dcylinder': 'bar3DChart',
		'col3dcylinderclustered': 'bar3DChart',
		'col3dcylinderstacked': 'bar3DChart',
		'col3dcylinderpercentstacked': 'bar3DChart',
		'bubble': 'bubbleChart',
		'bubble3d': 'bubbleChart');
		return 'c:' $ m[t];
	End;
	
	Function getVaryColors(t);
	Begin
		m := array(
		'barstacked':        100,
		'barpercentstacked': 100,
		'colstacked':        100,
		'colpercentstacked': 100
		);
		return m[t];
	End;
	
	Function getGrouping(t);
	Begin
		m := array(
		'area':                        'standard',
		'areastacked':                 'stacked',
		'areapercentstacked':          'percentStacked',
		'area3d':                      'standard',
		'area3dstacked':               'stacked',
		'area3dpercentstacked':        'percentStacked',
		'bar':                         'clustered',
		'barstacked':                  'stacked',
		'barpercentstacked':           'percentStacked',
		'bar3dclustered':              'clustered',
		'bar3dstacked':                'stacked',
		'bar3dpercentstacked':         'percentStacked',
		'bar3dconeclustered':          'clustered',
		'bar3dconestacked':            'stacked',
		'bar3dconepercentstacked':     'percentStacked',
		'bar3dpyramidclustered':       'clustered',
		'bar3dpyramidstacked':         'stacked',
		'bar3dpyramidpercentstacked':  'percentStacked',
		'bar3dcylinderclustered':      'clustered',
		'bar3dcylinderstacked':        'stacked',
		'bar3dcylinderpercentstacked': 'percentStacked',
		'col':                         'clustered',
		'colstacked':                  'stacked',
		'colpercentstacked':           'percentStacked',
		'col3d':                       'standard',
		'col3dclustered':              'clustered',
		'col3dstacked':                'stacked',
		'col3dpercentstacked':         'percentStacked',
		'col3dcone':                   'standard',
		'col3dconeclustered':          'clustered',
		'col3dconestacked':            'stacked',
		'col3dconepercentstacked':     'percentStacked',
		'col3dpyramid':                'standard',
		'col3dpyramidclustered':       'clustered',
		'col3dpyramidstacked':         'stacked',
		'col3dpyramidpercentstacked':  'percentStacked',
		'col3dcylinder':               'standard',
		'col3dcylinderclustered':      'clustered',
		'col3dcylinderstacked':        'stacked',
		'col3dcylinderpercentstacked': 'percentStacked',
		'line':                        'standard');
		return m[t];
	End;
	
	Function getBarDir(t);
	Begin
		m := array(
		'bar':                         'bar',
		'barstacked':                  'bar',
		'barpercentstacked':           'bar',
		'bar3dclustered':              'bar',
		'bar3dstacked':                'bar',
		'bar3dpercentstacked':         'bar',
		'bar3dconeclustered':          'bar',
		'bar3dconestacked':            'bar',
		'bar3dconepercentstacked':     'bar',
		'bar3dpyramidclustered':       'bar',
		'bar3dpyramidstacked':         'bar',
		'bar3dpyramidpercentstacked':  'bar',
		'bar3dcylinderclustered':      'bar',
		'bar3dcylinderstacked':        'bar',
		'bar3dcylinderpercentstacked': 'bar',
		'col':                         'col',
		'colstacked':                  'col',
		'colpercentstacked':           'col',
		'col3d':                       'col',
		'col3dclustered':              'col',
		'col3dstacked':                'col',
		'col3dpercentstacked':         'col',
		'col3dcone':                   'col',
		'col3dconestacked':            'col',
		'col3dconeclustered':          'col',
		'col3dconepercentstacked':     'col',
		'col3dpyramid':                'col',
		'col3dpyramidclustered':       'col',
		'col3dpyramidstacked':         'col',
		'col3dpyramidpercentstacked':  'col',
		'col3dcylinder':               'col',
		'col3dcylinderclustered':      'col',
		'col3dcylinderstacked':        'col',
		'col3dcylinderpercentstacked': 'col',
		'line':                        'standard');
		return m[t];
	End;

	isWord_;
End;

Type TPageLine = Class
	Function Create(w);
	Begin
		Width := w;
		Init();
	End;
	
	Function Init();
	Begin
		MaxLineHeight := 0;
		CurrentLine := 0;
		txt_ := '';
	End;
	
	Function Add(ch, rowHeight, rPr);
	Begin
		newLine := false;
		txt := txt_;
		[charW, cnt] := _getCharWidth(ch, rPr);
		if CurrentLine + charW > Width then Begin
			mh := MaxLineHeight;
			Init();	//新行
			newLine := true;
		End;
		CurrentLine += charW;
		if rowHeight > MaxLineHeight then 
			MaxLineHeight := rowHeight;
		return array(newLine, mh, cnt, txt);
	End;
	
	Function _getCharWidth(ch, rPr);
	Begin
		iChar := ord(ch);
		cnt := iChar > 127 ? 3 : 1;
		ratio := cnt=1 ? 0.5 : 1;
		if ifObj(rPr) then Begin
			size := max(rPr.Size, rPr.szCs);
			if size=0 then size := 21;
			return array(size * 10 * ratio, cnt);
		End;
		return array(210 * ratio, cnt);	//默认五号字
	End;
	
	Width:integer;
	MaxLineHeight:integer;
	CurrentLine:integer;
	txt_:string;
End;

//页面设置
Type TSectPr = Class
	Function Create(docx, node);
	Begin
		docx_ := docx;
		PageNo := 1;
		LinePos := 0;
		PageHash := array();
		ContentArr := array();
		if ifObj(node) then
			Init(node);
	End;
	
	Function Init(node);
	Begin
		pgSz := node.FirstChildElement('w:pgSz');
		if ifObj(pgSz) then Begin
			w := pgSz.GetAttribute('w:w');
			h := pgSz.GetAttribute('w:h');
		End;
		pgMar := node.FirstChildElement('w:pgMar');
		if ifObj(pgMar) then Begin
			left := pgMar.GetAttribute('w:left');
			right := pgMar.GetAttribute('w:right');
			top := pgMar.GetAttribute('w:top');
			bottom := pgMar.GetAttribute('w:bottom');
		End;
		PageWidth := Class(TSXml).SafeStrToIntDef(w, 11906)-Class(TSXml).SafeStrToIntDef(left,1800)-Class(TSXml).SafeStrToIntDef(right,1800);
		PageHeight := Class(TSXml).SafeStrToIntDef(h, 16838)-Class(TSXml).SafeStrToIntDef(top,1440)-Class(TSXml).SafeStrToIntDef(bottom,1440);
		docGrid := node.FirstChildElement('w:docGrid');
		LinePitch := ifObj(docGrid) ? Class(TSXml).SafeStrToIntDef(docGrid.GetAttribute('w:linePitch'), 312) : 312;
		PageLine := new TPageLine(PageWidth);
		if istable(ContentArr) then Begin	//计算当前章节页码
			//w:p;w:tbl
			for i:=0 to length(ContentArr)-1 do Begin
				[startPage,PageNo,LinePos] := _CalcPage(ContentArr[i]['obj'], PageNo, LinePos);//计算段落、表格、文本框、图片、形状等的页面及大小
				if ContentArr[i]['mark'] >= 0 then
					PageHash[ ContentArr[i]['mark'] ] := startPage;//记录页面
			End;
			
			//下一章节
			PageNo ++;
			ContentArr := array();
			LinePos := 0;
		End;
	End;
	
	Function Append(p);
	Begin
		ContentArr[ length(ContentArr) ] := array('obj':p, 'mark':-1);
	End;
	
	Function Mark(ind);
	Begin
		if istable(ContentArr) then
			ContentArr[ length(ContentArr)-1 ]['mark'] := ind;
	End;
	
	Function GetPageNo(ind);
	Begin
		if ifInt(PageHash[ind]) then 
			return PageHash[ind];
		return PageNo;
	End;
	
	//计算页面
	Function _CalcPage(obj, page, lpos, more);
	Begin
		startPage := page;
		curPageNo := page;
		curLinePos := lpos;
		case obj.Name() of
		'w:p':
			[startPage, pgNo, line] := _CalcParagraphPage(obj, curPageNo, curLinePos, more);
		'w:tbl':
			[startPage, pgNo, line] := _CalcTablePage(obj, curPageNo, curLinePos);
		End;
		return array(startPage, pgNo, line);
	End;
	
	//段落
	Function _CalcParagraphPage(p, page, lpos, more);
	Begin
		startPage := page;
		curPageNo := page;
		curLinePos := lpos;
		height := 0;//单位：点（1点=0.3527毫米=1/72英寸）
		ETU := 360045;//1cm单位
		defaultLineHeight := LinePitch;		//缺省行距
		ParagraphLineHeight := LinePitch;

		defaultPpr := docx_.StyleObject().defaultPpr_;//缺省段落
		defaultRpr := docx_.StyleObject().defaultRpr_;//缺省字体
		pPr := Class(TSXml).ReadPprFormat(p.node_);
		//存在段落样式
		StyleId := p.pPr.Value('StyleId');
		if StyleId then Begin
			oStyle := docx_.StyleObject().GetStyleById(StyleId);
			if ifObj(oStyle) then Begin
				stylePpr := oStyle.ReadPprFormat();	//读段落属性（缓存到StyleObject中）
				if not ifObj(pPr) then Begin
					pPr := stylePpr;
				End
				else
					Class(TSXml).CopyPprFormat(pPr, stylePpr);
				//Class(TSXml).CopyPprFormat(pPr, defaultPpr);
				
				defaultRpr := oStyle.ReadRprFormat();	//读段落字体属性（缓存到StyleObject中）
			End;
		End
		else if ifObj(defaultPpr) then Begin	//缺省样式
			if not ifObj(pPr) then Begin
				pPr := defaultPpr;
			End
			else
				Class(TSXml).CopyPprFormat(pPr, defaultPpr);
		End;
		
		LineRatio := 1.0;
		if ifObj(pPr) then Begin
			if pPr.LineSpacingRule = 'exact' and pPr.LineSpacing then 	//固定行距
				defaultLineHeight := _pPr.LineSpacing;
			else if pPr.LineSpacing then Begin
				LineRatio := pPr.LineSpacing / 240;
				//LineRatio := 1.0;
				defaultLineHeight := LineRatio * defaultLineHeight;	//多倍行距
			End;
			ParagraphLineHeight := _GetHeightRatio(pPr, pPr.rPr, LineRatio) * defaultLineHeight;	//缺省段落高度(字体)
		End;
		
		//段前
		before := (ifObj(pPr)) ? pPr.SpaceBefore : 0;
		after := ifObj(pPr) ? pPr.SpaceAfter : 0;
		//段中
		runs := p.GetRuns();
		for i:=0 to length(runs)-1 do Begin
			run := runs[i];
			rPr := Class(TSXml).ReadRprFormat(run.node_);
			if not ifObj(rPr) then
				rPr := defaultRpr;
			else
				Class(TSXml).CopyRprFormat(rPr, defaultRpr);
//_dumpRpr(rpr);
			RunLineHeight := _GetHeightRatio(pPr, rPr, LineRatio) * defaultLineHeight;	//缺省段落高度
			pic := run.node_.FirstChildElement('w:drawing/wp:inline/wp:extent');//图片
			if not ifObj(pic) then 
				pic := run.node_.FirstChildElement('mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:extent');//文本框
			if ifObj(pic) then Begin
				cy := Class(TSXml).SafeStrToIntDef(pic.GetAttribute('cy'), LinePitch);
				height := cy / ETU / 0.0325;
				_addLine(startPage, curPageNo, curLinePos, height, before, linesCnt ? false : true, txt);	//加入一行
				linesCnt ++;
				continue;
			End
			
			node := run.node_.FirstChildElement();
			while ifObj(node) do Begin
				name := node.GetName();
				if name = 'w:br' then Begin
					_addLine(startPage, curPageNo, curLinePos, (PageLine.MaxLineHeight ? PageLine.MaxLineHeight : RunLineHeight) + (linesCnt ? 0 : more), 0, linesCnt ? false : true, '');	//加入一行
					PageLine.Init();
					linesCnt ++;
				End
				else if name = 'w:t' then Begin
					txt := node.GetText();
					txtLen := length(txt);
					n := 0;
					while n < txtLen do Begin
						if ifObj(pPr) and PageLine.CurrentLine = 0 then Begin	//缩进、悬挂
							PageLine.CurrentLine += _getHanging(linesCnt, pPr);
						End;
						[newLine, LineHeight, cnt, t] := PageLine.Add(txt[n+1], RunLineHeight, rPr);
						PageLine.txt_ += txt[n+1:n+cnt];
						n += cnt;
						if newLine then Begin
							_addLine(startPage, curPageNo, curLinePos, LineHeight + (linesCnt ? 0 : more), before, linesCnt ? false : true, t);	//加入一行
							PageLine.CurrentLine += _getHanging(linesCnt+1, pPr);
							linesCnt ++;
						End;
					End;
				End;
				node := node.NextElement();
			End;
		End;
		if linesCnt = 0 and PageLine.CurrentLine = 0 then Begin //空行
			_addLine(startPage, curPageNo, curLinePos, ParagraphLineHeight + more, 0, true, '');	//加入一行
		End
		else if PageLine.CurrentLine then Begin
			_addLine(startPage, curPageNo, curLinePos, PageLine.MaxLineHeight, before, linesCnt ? false : true, PageLine.txt_);	//加入一行
			PageLine.Init();
			linesCnt ++;
		End
		else Begin
			PageLine.Init();
		End;
		//段后
//_dumpPpr(pPr);
//println('Begin Orer=curLinePos={}',curLinePos);
		curLinePos += after;
//println('End Orer=curLinePos={}\n\n\n\n',curLinePos);
		return array(startPage, curPageNo, curLinePos);
	End;
	
	//表格
	Function _CalcTablePage(tbl, page, lpos);
	Begin
		startPage := page;
		curPageNo := page;
		curLinePos := lpos;
		topH := Class(TSXml).SafeStrToIntDef(tbl.tblPr.Borders.Top.Value('Val'), 4);				//缺省0.5磅，一磅=20点
		bottomH := Class(TSXml).SafeStrToIntDef(tbl.tblPr.Borders.bottom.Value('Val'), 4);			//缺省0.5磅
		insideVH := Class(TSXml).SafeStrToIntDef(tbl.tblPr.Borders.insideV.Value('Val'), 4);		//缺省0.5磅
		iRow := 0;
		trNode := tbl.node_.FirstChildElement('w:tr');
		while ifObj(trNode) do Begin
			maxPageNo := curPageNo;
			maxLinePos := curLinePos;
			tr := new TwTr(nil, 'w:tr');
			tr.RootObj := trNode;
			vh := Class(TSXml).SafeStrToIntDef(tr.tblPrEx.Borders.insideV.Value('Val'), insideVH);	//行的上边框
			tcNode := trNode.FirstChildElement('w:tc');
			while ifObj(tcNode) do Begin	//计算每一个单元格占用页面
				tcPageNo := curPageNo;
				tcLinePos := curLinePos;
				iCol := 0;
				pNode := tcNode.FirstChildElement();
				while ifObj(pNode) do Begin
					name := pNode.GetName();
					obj := _getDocObject(pNode, name);
					if ifObj(obj) then Begin
						[tcStartPage,tcPageNo,tcLinePos] := _CalcPage(ContentArr[i]['obj'], tcPageNo, tcLinePos, iCol = 0 ? (iRow = 0 ? topH * 2.5 : vh * 2.5) : 0);
						iCol ++;
					End;
					pNode := pNode.NextElement();
				End;
				if iCol = 0 then Begin	//空单元格
					_addLine(tcStartPage, tcPageNo, tcLinePos, (iRow = 0 ? topH * 2.5 : vh * 2.5) + LinePitch, 0, false, '');
				End;
				if maxPageNo < tcPageNo then Begin
					maxPageNo := tcPageNo;
					maxLinePos := tcLinePos;
				End
				else if maxPageNo = tcPageNo and maxLinePos < tcLinePos then Begin
					maxLinePos := tcLinePos;
				End;
				tcNode := tcNode.NextElement('w:tc');
			End;
			iRow++;
			trNode := trNode.NextElement('w:tr');
			curPageNo := maxPageNo;
			curLinePos := maxLinePos;
		End;
		//底边框
		_addLine(startPage, curPageNo, curLinePos, bottomH * 2.5, 0, false, '');
		
		return array(startPage, curPageNo, curLinePos);
	End;
	
	Function _addLine(startPage, curPageNo, curLinePos, height, before, firstLine, t);
	Begin
//println('换行：curLinePos={},height={}, before={}, txt={}',curLinePos, height, before, t);	
		if curLinePos + height > PageHeight  then Begin	//放不下，换页
			curPageNo++;
			curLinePos := height;
//println('换页：curLinePos={},txt={}',curLinePos, t);
		End
		else 
			curLinePos += height + (curLinePos = 0 ? 0 : before);
		if firstLine then
			startPage := curPageNo;
	End;
	
	Function _GetHeightRatio(pPr, rPr, LineRatio);
	Begin
		if lineRule = 'exact' then	//固定行距
			return 1.0;
		if not ifObj(rPr) then
			return 1.0;

		return _Font2LineHeight(rPr, LineRatio);		//字体大小对应的行距(倍数)
	End;
	
	Function _Font2LineHeight(rPr, LineRatio);
	Begin
		size := max(ifnil(rPr.Size) ? 0 : rPr.Size, ifnil(rPr.szCs) ? 0 : rPr.szCs);
		if size = 0 then size := 21;//缺省五号字
		if rPr.rFont.hint in array('eastAsia', 'zh-CN') or rPr.rFont.eastAsia <> '' then Begin
			return ceil(size*10/(LinePitch*LineRatio-200/3));
		End;
		
		return ceil(size*10/(LinePitch*LineRatio-38));
	End;
	
	docx_;
	PageWidth:integer;
	PageHeight:integer;
	LinePitch:integer;	//行距
	PageNo;
	LinePos;
	ContentArr;
	PageHash;
	PageLine;
End;

//w:body
Type TDocumentBody = Class(DocObject)
	Function Create();overload;
	Begin
		Create(nil);
	End;
	
	Function Create(node);overload;
	Begin
		name_ := 'w:body';
		InitNode(node);
	End;
	
	Function InitNode(node);
	Begin
		node_ := node;
		//设置最后一个段落
		_setLastParagraph();
	End;
	
	Function _setLastParagraph();
	Begin
		lastParagraph_ := nil;
		if ifObj(node_) then Begin
			last := node_.LastChild();
			while ifObj(last) do Begin
				name := last.GetName();
				if name in array('w:p', 'w:tbl') then Begin
					lastParagraph_ := last;
					break;
				End;
				last := last.Prev();
			End;
		End;
	End;
	
	///返回文档中全部对象列表(TParagraph、TTable等)
	Function Parts();
	Begin
		return getDocumentObjects(node_, '');
	End;
	
	///word文档所有段落
	///返回：TParagraph对象数组
	Function Paragraphs();
	Begin
		parts := getDocumentObjects(node_, 'w:p');
		r := array();
		for i:=0 to length(parts)-1 do Begin
			r[i] := new TParagraph(parts[i].node_);
		End;
		return r;
	End;
	
	///添加新段落
	///paragraph: TParagraph对象
	///posOpt: 段落位置，0 在DOCX文件开头；-1 文件尾；N 在第N段之后；DocumentPart对象 在posOpt之后新添加段落
	///[styleId]: int 样式ID
	///返回TParagraph对象
	Function AddParagraph(paragraph, posOpt, styleId);
	Begin
		if ifString(styleId) and styleId <> '' then Begin
			paragraph.Format.StyleId := styleId;
		End;
		addPart(posOpt, paragraph);
		p := new TParagraph(paragraph.node_);
		//复制段落字体属性
		p.CopyRunFormat(false, nil);
		_set_lastParagraph_(posOpt, p.node_);//设置最后一个段落
		return p;
	End;
	
	///删除指定段落
	///posOpt: 段落位置，0 在DOCX文件开头；-1 文件尾；N 第N段；posOpt段落
	///返回：true
	Function DelParagraph(posOpt);
	Begin
		node := findNode(posOpt, false);
		if ifInt(node) then Begin
			if node = 0 then
				node := node_.FirstChildElement('w:p');
			else if node = -1 then
				node := lastParagraph_;
		End;
		if not ifObj(node) then
			return false;
		next := node.NextElement('w:p');
		node_.DeleteChild(node);
		if not ifObj(next) then
			_setLastParagraph();
		return true;
	End;

	///添加标题
	///title: string
	///posOpt: 段落位置，0 在DOCX文件开头；-1 文件尾；N 在第N段之后；DocumentPart对象 在posOpt之后新添加段落
	///level: int 标题级别（0-9）
	///返回TParagraph对象
	Function AddHeading(title, posOpt, styleId);
	Begin
		paragraph := new TParagraph();
		paragraph.Run.SetText( title );
		if ifObj(document_) then Begin
			id := document_.GetBookMarkID();
			paragraph.MarkStart.Name := '_Toc' $ id;
			paragraph.MarkStart.ID := id;
			paragraph.MarkEnd.ID := id;
		End;
		return AddParagraph(paragraph, posOpt, styleId);
	End;
	
	///插入分页符
	///posOpt: 段落位置，0 在DOCX文件开头；-1 文件尾；N 在第N段之后；DocumentPart对象 在posOpt之后新添加段落
	///返回TParagraph对象
	Function AddBreak(posOpt, tp);
	Begin
		paragraph := new TParagraph();
		if tp <> '' then
			paragraph.Run.Br.Type := tp;
		return AddParagraph(paragraph, posOpt);
	End;
	
	//word文档所有内容的文本串数组，包含段落信息
	//返回：array(("pNode":nodeObj, "pIndex":p, "rNode":nodeObj, "rIndex":r))
	Function TextArray();override;
	Begin
		r := array();
		ps := getDocumentObjects(node_, 'w:p');
		for i:=0 to length(ps)-1 do Begin
			pArr := ps[i].TextArray();
			if length(pArr) then Begin
				update pArr set ['pIndex'] = i end;
				r union= pArr;
			End
			else Begin
				r[ length(r) ] := array('pNode':ps[i].node_, 'pIndex':i, 'rNode':nil, 'rIndex':-1);//空段落
			End;
		End;
		return r;
	End;
	
	///word文档所有表格个数
	///返回：int
	Function TablesCount();
	Begin
		t := getDocumentObjects(node_, 'w:tbl');
		return length(t);
	End;
	
	///word文档所有表格
	///返回：TTable对象数组
	Function Tables();
	Begin
		return getDocumentObjects(node_, 'w:tbl');
	End;
	
	///word文档指定表格
	///n: int 第n个表格 
	///返回：TTable对象
	Function GetTable(i);
	Begin
		t := getDocumentObjects(node_, 'w:tbl');
		if i < 0 or i >= length(t) then return 0;
		tbl := new TTable(t[i].node_);
		return tbl;
	End;
	
	///插入数据表
	///tbl: TTable对象
	///[posOpt: 段落位置]，0 在DOCX文件开头；-1 文件尾；N 在第N段之后；DocumentPart对象 在posOpt之后新添加表格
	Function InsertTable(tbl, posOpt);
	Begin
		addPart(posOpt, tbl);
		TOfficeApi().Set('CurrentTable', tbl.node_);
		tblBorders := class(TSXml).GetNode(tbl.node_, 'w:tblPr/w:tblBorders');
		tblCellMar := class(TSXml).GetNode(tbl.node_, 'w:tblPr/w:tblCellMar');
		if ifObj(tblBorders) or ifObj(tblCellMar) then Begin
			borders := ifObj(tblBorders) ? tblBorders.Marshal() : nil;
			cellmar := ifObj(tblCellMar) ? tblCellMar.Marshal() : nil;
		End;
		defaultParagraph := tbl.Paragraph;
		if not ifObj(defaultParagraph) then Begin
			defaultParagraph := new TParagraph();
			defaultParagraph.pPr.rPr.Lang := 'en-US';
			defaultParagraph.pPr.rPr.eastAsia := 'zh-CN';
			defaultParagraph.Run.rPr.Lang := 'en-US';
			defaultParagraph.Run.rPr.eastAsia := 'zh-CN';
		End;
		defaultpPr := defaultParagraph.pPr.Marshal();
		defaultrPr := defaultParagraph.pPr.rPr.Marshal();
		
		for i:=0 to length(tbl.Data_)-1 do Begin
			trNode := tbl.node_.InsertEndChild('element', 'w:tr');
			multiLine := false;
			if ifstring(tbl.Data_[i, j]) and Pos('\n', tbl.Data_[i, j]) then
				multiLine := true;
			for j:=0 to tbl.colCount_-1 do Begin
				//对象太多的话，对象效率奇慢，优化掉(性能可能相差50倍)
				if 0 then Begin
					tc := new TCell();
					tc.TcPr.Width := tbl.TblGrid.GridCol[j]['obj'].W;
					tc.TcPr.Type := 'dxa';
					tc.SetText(tbl.Data_[i, j]);
					trNode.InsertEndChild(tc.Marshal());
					continue;
				End;
				
				tcNode := trNode.InsertEndChild('element', 'w:tc');
				tcPrNode := tcNode.InsertEndChild('element', 'w:tcPr');
				tcWNode := tcPrNode.InsertEndChild('element', 'w:tcW');
				tcWNode.SetAttribute('w:w', tbl.TblGrid.GridCol[j]['obj'].W);
				tcWNode.SetAttribute('w:type', 'dxa');
				if multiLine then Begin
					defaultParagraph.node_ := nil;
					defaultParagraph.Run.ClearText();
					defaultParagraph.Run.SetText(tbl.Data_[i, j]);
					tcNode.InsertEndChild(defaultParagraph.Marshal());
				End
				else Begin
					pNode := tcNode.InsertEndChild('element', 'w:p');
					pNode.InsertEndChild(defaultpPr);
					rNode := pNode.InsertEndChild('element', 'w:r');
					rNode.InsertEndChild(defaultrPr);
					tNode := rNode.InsertEndChild('element','w:t', class(TSXml).CurCodePageToUtf8(tbl.Data_[i, j]));
					if _preserve(tbl.Data_[i, j]) then
						tNode.SetAttribute('xml:space', 'preserve');
				End;
(*
<w:tc>
	<w:tcPr>
		<w:tcW w:w="700" w:type="dxa"/>
	</w:tcPr>
	<w:p>
		<w:pPr>
			<w:rPr>
				<w:lang w:eastAsia="zh-CN" w:val="en-US"/>
			</w:rPr>
		</w:pPr>
		<w:r>
			<w:rPr>
				<w:lang w:eastAsia="zh-CN" w:val="en-US"/>
			</w:rPr>
			<w:t>Index</w:t>
		</w:r>
	</w:p>
</w:tc>
*)
			End;
			if ifObj(tblCellMar) then Begin
				c := class(TSXml).GetNode(trNode, 'w:tblPrEx/w:tblCellMar', 'first');
				class(TSXml).UpdateNode(c, cellmar[0]['attributes'], cellmar[0]['children']);
			End;
			if ifObj(tblBorders) then Begin
				b := class(TSXml).GetNode(trNode, 'w:tblPrEx/w:tblBorders', 'first');
				class(TSXml).UpdateNode(b, borders[0]['attributes'], borders[0]['children']);
			End;
		End;
		node_.Parent().SetAttribute('mc:Ignorable', 'w14 w15 wp14');
		node_.Parent().SetAttribute('xmlns:w15', 'http://schemas.microsoft.com/office/word/2012/wordml');
		_set_lastParagraph_(posOpt, tbl.node_);
		
		p := new TTable(tbl.node_);
		return p;
	End;
	
	///插入图片
	///picture: TPicture对象
	///[posOpt: 段落位置]，0 在DOCX文件开头；-1 文件尾；N 在第N段之后；DocumentPart对象 在posOpt之后新添加表格
	///[docx]: 可选参数，TSDocxFile对象，在TTextBox、TCell中调用需要传入文档对象
	Function AddPicture(picture, posOpt, docx);
	Begin
		if ifObj(docx) then Begin
			zipfile_ := docx.Zip();
			picture.Run.Drawing.WInline.ID := docx.GetDocPrId();
		End;
		if not ifBinary(picture.Image) or length(picture.Image)=0 then 
			raise 'Invalid Image Data.';
		if not ifObj(zipfile_) then
			raise 'no support';
		image := new TSImage(picture.Image);
		xml := zipfile_.Get('word/_rels/document.xml.rels');
		files := sselect ['FileName'] from zipfile_.Files() where AnsiStartsText('word/media/image', ['FileName']) end;
		for i:=0 to length(files)-1 do Begin
			if zipfile_.Diff(files[i], picture.Image) = 0 then Begin
				prefix := ReplaceStr(files[i], 'word/', '');
				[maxRid, imageFile, rid] := class(TSXml).FindRelationshipRid(xml, prefix);
			End;
		End;
		if rid = 0 then Begin
			imageCnt := length(files) + 1;
			imageFile := 'media/image' $ imageCnt $ '.' $ image.ExtFileName;
			[rid, target] := class(TSXml).FindRelationshipRid(xml, '');
			rid ++;
			class(TSXml).AddRelationshipRid(xml, imageFile, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid);
			zipfile_.Add('word/' + imageFile, picture.Image);
			contentXml := zipfile_.Get('[Content_Types].xml');
			class(TSXml).AddDefaultContentType(contentXml, image.ExtFileName, 'image/' $ image.ExtFileName);
		End;
		[cx, cy] := picture.ScaledDimensions(image);//extent 元素通过其属性指定此对象的高度和宽度为 [cx,cy] ETU (英语公制单位) 
		//println('cx={},cy={},w={},h={}',cx,cy,image.px_width,image.px_height);
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.BlipFill.blip.Embed := 'rId' $ rid;
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.BlipFill.Stretch.FillRect := 1;
		picId := getPictureMaxId() + 1;
		picture.Run.Drawing.WInline.Name := '图片 ' $ picId;
		picture.Run.Drawing.WInline.Descr := class(TSXml).CurCodePageToUtf8(picture.Descr);
		picture.Run.Drawing.WInline.cNvGraphicFramePr.xmlns := 'http://schemas.openxmlformats.org/drawingml/2006/main';
		picture.Run.Drawing.WInline.cNvGraphicFramePr.noChangeAspect := 1;
		picture.Run.Drawing.WInline.Graphic.xmlns := 'http://schemas.openxmlformats.org/drawingml/2006/main';
		picture.Run.Drawing.WInline.Graphic.GraphicData.uri := 'http://schemas.openxmlformats.org/drawingml/2006/picture';
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.xmlns := 'http://schemas.openxmlformats.org/drawingml/2006/picture';
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.nvPicPr.CNvPr.ID := picture.Run.Drawing.WInline.ID;
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.nvPicPr.CNvPr.Name := picture.Run.Drawing.WInline.Name;
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.nvPicPr.CNvPr.Descr := picture.Run.Drawing.WInline.Descr;
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.nvPicPr.cNvPicPr.NodeName := 'pic:cNvPicPr';
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.nvPicPr.cNvPicPr.PicLocks := 1;
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.spPr.PrstGeom.prst := 'rect';
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.spPr.PrstGeom.avLst := true;
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.spPr.XFrm.Off.X := 0;
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.spPr.XFrm.Off.Y := 0;
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.spPr.XFrm.Ext.CX := cx;
		picture.Run.Drawing.WInline.Graphic.GraphicData.Pic.spPr.XFrm.Ext.CY := cy;
		picture.Run.Drawing.WInline.distR := 114300;
		picture.Run.Drawing.WInline.distL := 114300;
		picture.Run.Drawing.WInline.distB := 0;
		picture.Run.Drawing.WInline.distT := 0;
		picture.Run.Drawing.WInline.cy := cy;
		picture.Run.Drawing.WInline.cx := cx;
		//picture.Run.Drawing.WInline.r := 0;
		//picture.Run.Drawing.WInline.b := 5080;
		//picture.Run.Drawing.WInline.t := 0;
		//picture.Run.Drawing.WInline.l := 0;
		addPart(posOpt, picture);
		
		p := new TPicture(picture.node_);
		_set_lastParagraph_(posOpt, picture.node_);
		picture.node_.InsertFirstChild('element', 'w:pPr');
		TOfficeApi().Set('CurrentShape', picture.node_);
		return p;
	End;
	
	///文档中全部的批注信息
	///返回：TDocComments对象
	Function Comments();overload;
	Begin
		t := array();
		[startCnt, endCnt, tCnt, index] := array(0, 0, 0, 0);
		p := node_.FirstChildElement('w:p');
		while ifObj(p) do Begin
			child := p.FirstChildElement();
			rIndex := 0;
			while ifObj(child) do Begin
				id := -1;
				name := child.GetName();
				if name = 'w:commentRangeStart' then Begin
					startCnt ++;
					id := strtoint(child.GetAttribute('w:id'));
					t[ tCnt++ ] := array('pNode':p, 'rNode':child, 'Name':name, 'Start':startCnt, 'End':endCnt, 'ID':id, 'pIndex':index);
				End
				else if name = 'w:commentRangeEnd' then Begin
					endCnt ++;
					id := strtoint(child.GetAttribute('w:id'));
					t[ tCnt++ ] := array('pNode':p, 'rNode':child, 'Name':name, 'Start':startCnt, 'End':endCnt, 'ID':id, 'pIndex':index);
				End
				else if name = 'w:r' and startCnt > endCnt then Begin
					t[ tCnt++ ] := array('pNode':p, 'rNode':child, 'Name':name, 'Start':startCnt, 'End':endCnt, 'ID':-1, 'pIndex':index);
				End;
				child := child.NextElement();
			End;
			index ++;
			p := p.NextElement('w:p');
		End;
		return new TDocComments(t);
	End;

	//返回TDocSection对象集合
	Function Sections();overload;
	Begin
		index := 0;
		r := array();
		node := node_.FirstChildElement();
		while ifObj(node) do Begin
			name := node.GetName();
			if name = 'w:sectPr' then Begin
				section := new TDocSection(node, index++, zipfile_);
				r[length(r)] := section;
			End
			else if name = 'w:p' then Begin
				child := class(TSXml).GetNode(node, 'w:pPr/w:sectPr', false);
				if ifObj(child) then Begin
					section := new TDocSection(node, index++, zipfile_);
					r[length(r)] := section;
				End;
			End;
			node := node.NextElement();
		End;
		return r;
	End;

	//index：integer 章节索引
	//返回：指定TDocSection对象
	Function Sections(index);overload;
	Begin
		if index < 0 then Begin	//返回文档最后一个章节（缺省章节）
			node := node_.LastChild('w:sectPr');
			if ifObj(node) then 
				return new TDocSection(node, -1, zipfile_);
			return nil;
		End;
		arr := Sections();
		if length(arr) >= index then
			return nil;
		return arr[index];
	End;
	
	//添加章节
	//section：TDocSection对象
	//posOpt: 位置，0 在DOCX文件开头；-1 文件尾；N 在第N段之后；DocumentPart对象 在posOpt之后新添加章节
	//返回：TDocSection对象
	Function AddSection(section, posOpt);overload;
	Begin
		section.zipfile_ := zipfile_;
		p := new TParagraph();
		p.pPr.NewChildNode( array("field":"", "name":"w:sectPr", "obj":section, "attrEx":"", "nodeType":"") );
		p := AddParagraph(p, posOpt, '');//段落对象
		return new TDocSection(p.node_.FirstChildElement('w:sectPr'), -2, zipfile_);
	End;
	
	Function ExecInnerTSL(docx);
	Begin
		//表格
		t := array();
		tslFuncCount := 0;
		errArr := array();
		tArr := Tables();
		for i:=0 to length(tArr)-1 do Begin
			col := tArr[i].Cols();
			row := tArr[i].Rows();
			for r:= 1 to row do Begin
				for c:=1 to col do Begin
					cell := tArr[i].Cell(r, c);
					[err, cnt, err] := cell.ExecInnerTSL(docx);//递归
					tslFuncCount += cnt; 
					errArr union= err;
				End;
			End;
		End;
		
		//文本框
		ps := Paragraphs();
		for i:=0 to length(ps)-1 do Begin
			boxs := ps[i].TextBoxs();
			for j:=0 to length(boxs)-1 do Begin
				[err, cnt, err] := boxs[j].ExecInnerTSL(docx);//递归
				if cnt then 
					boxs[j].Apply();
				tslFuncCount += cnt; 
				errArr union= err;
			End;
		End;
		
		//页脚、页眉
		sArr := Sections();
		tpArr := array('default','even','first');
		for i:=0 to length(sArr)-1 do Begin
			for k, name in tpArr do Begin
				h := sArr[i].Header(name);
				if ifObj(h) then Begin
					[err, cnt, err] := h.ExecInnerTSL(docx);//递归
					tslFuncCount += cnt; 
					errArr union= err;
				End;
					
				f := sArr[i].Footer(name);
				if ifObj(f) then Begin
					[err, cnt, err] := f.ExecInnerTSL(docx);//递归
					tslFuncCount += cnt; 
					errArr union= err;
				End;
			End;
		End;
		
		[err, cnt, err] := ExecInnerTSLImpl(docx);
		tslFuncCount += cnt; 
		errArr union= err;
		return array(length(errArr), tslFuncCount, errArr);
	End;
	
	Function RunTslCode(code, err);
	Begin
		try
			//println('run code=[{}]', code);
			if code <> '' then 
				eval(&code);
		except
			err := ExceptObject.ErrInfo;
			return false;
		End;
		return true;
	End;
	
	Function ExecInnerTSLImpl(docx);
	Begin
		tslFuncCount := 0;
		errArr := array();
		tslArr := array();
		tArr := TextArray();
		flag := '';
		code := nil;
		begParagraphIndex := -1;
		begPos := 0;
		begTxtLen := 0;
		while i < length(tArr) do Begin
			txt := '';
			iStep := 1;		
			if ifObj(tArr[i]['rNode']) then Begin
				run := new TRun(tArr[i]['rNode']);
				txt := run.Text();
				if class(TSXml).IsUtf8() then
					txt := UTF8ToAnsi(txt);
			End;
			k := 1;
			wz := 1;
			txtLen := length(txt);
			while k <= txtLen do Begin
				c := txt[k];
				case flag of
				'':
					if c = '[' then Begin
						flag := '[';
						begParagraphIndex := i;
						begPos := wz;
						begTxtLen := txtLen;
					End;
				'[': 
					if c = 'T' or c = 't' then 
						flag := '[T';
					else 
						flag := '';
				'[T': 
					if c = 'S' or c = 's' then 
						flag := '[TS';
					else 
						flag := '';
				'[TS': 
					if c = 'L' or c = 'l' then 
						flag := '[TSL';
					else 
						flag := '';
				'[TSL': 
					if c = ']' then Begin
						flag := '[TSL]';
						tslArr := tArr[begParagraphIndex:i,:];
						code := '';
						k++;
						wz++;
						continue;
					End
					else 
						flag := '';
				'[TSL]':
					if c = '[' then Begin
						flag := '[TSL][';
						endPos := 0;
					End
				'[TSL][': 
					if c = '/' then
						flag := '[TSL][/';
					else
						flag := '[TSL]';
				'[TSL][/': 
					if c = 'T' or c='t' then
						flag := '[TSL][/T';
					else
						flag := '[TSL]';
				'[TSL][/T': 
					if c = 'S' or c='s' then
						flag := '[TSL][/TS';
					else
						flag := '[TSL]';
				'[TSL][/TS': 
					if c = 'L' or c='l' then
						flag := '[TSL][/TSL';
					else
						flag := '[TSL]';
				'[TSL][/TSL': 
					if c = ']' then Begin
						tslBegParagraphNode := tslArr[0]['pNode'];
						tslEndParagraphNode := tArr[i]['pNode'];
						ind := length(tslArr) - 1;
						if tslArr[ind]['pIndex'] <> tArr[i]['pIndex'] or tslArr[ind]['rIndex'] <> tArr[i]['rIndex'] then Begin
							ind ++;
							tslArr[ind] := tArr[i];
						End;
						if begPos > 1 then Begin //函数前分割为新的w:r
							prevRun := run._duplicate_r(tArr[begParagraphIndex]['rNode']);
							run._adjust_r(tArr[begParagraphIndex]['rNode'], 0, begPos - 1);
							tslArr[0]['rNode'] := prevRun;
						End;
						if k < txtLen then Begin	//函数后面分割为新的w:r
							oldNode := run.node_;
							if begParagraphIndex = i and begPos > 1 then 
								oldNode := prevRun;
							tArr[i]['rNode'] := run._duplicate_r(oldNode);
							run._adjust_r(tArr[i]['rNode'], wz, txtLen);
							iStep := 0;
						End;
						curRunNode := tslArr[0]['rNode'];
						curRun := new TRun(curRunNode);
						curRun.ClearText();
						rmvPara := array();
						for m := 1 to length(tslArr) - 1 do Begin
							if ifObj(tslArr[m]['rNode']) then Begin
								tslArr[m]['pNode'].DeleteChild(tslArr[m]['rNode']);
								hasrNode := tslArr[m]['pNode'].FirstChildElement('w:r');
								if not ifObj(hasrNode) then
									rmvPara[ tslArr[m]['pIndex'] ] := tslArr[m]['pNode'];
							End
							else
								rmvPara[ tslArr[m]['pIndex'] ] := tslArr[m]['pNode'];
						End;
						for index, pNode in rmvPara do Begin				
							pNode.Parent().DeleteChild(pNode);
						End;
						//run inner tsl
						code := leftstr(code, lengthW(code) - 5 - endPos);
						CodePage := TOfficeApi().Get('CodePage');
						TOfficeApi().Set('Docx', docx);
						TOfficeApi().Set('CurrentParagraph', tslBegParagraphNode);
						TOfficeApi().Set('CurrentPosition', tslBegParagraphNode);
						TOfficeApi().Set('CurrentRun', curRunNode);
						TOfficeApi().Set('CodePage', 'gbk');
						if not RunTslCode(code, err) then Begin
							echo 'run code=',code,',err=', err, '\n';
							errArr[ length(errArr) ] := array('code':code, 'err':err);
						End;
						tslFuncCount ++;
						tNode := curRun.node_.FirstChildElement('w:t');
						if not ifObj(tNode) then Begin	//没有在外部插入文字
							tslBegParagraphNode.DeleteChild(curRunNode);
							//兼容WordTemplate函数，不删除空段落（TSL脚本段落）
							//hasrNode := tslBegParagraphNode.FirstChildElement('w:r');
							//if not ifObj(hasrNode) then Begin//删除空段落
							//	tslBegParagraphNode.Parent().DeleteChild(tslBegParagraphNode);
							//	tslBegParagraphNode := nil;
							//End;
						End;
						//段落炸裂
						curPosotion := TOfficeApi().Get('CurrentPosition');
						if i+iStep < length(tArr) and tArr[i+iStep]['pNode'] = tslEndParagraphNode and tslBegParagraphNode <> curPosotion then Begin
							data := tslEndParagraphNode.Marshal();
							NewParagraphNode := tslEndParagraphNode.Parent().InsertAfterChild(curPosotion, data[0]);//复制段落
							rmvArr := array();
							cnt := 0;
							curLine := 0;
							prevRNode := tArr[i+iStep]['rNode'].PrevElement('w:r');
							while ifObj(prevRNode) do Begin
								curLine ++;
								prevRNode := prevRNode.PrevElement('w:r');
							End;
							rmvN := 0;
							nextRNode := tArr[i+iStep]['rNode'];
							while ifObj(nextRNode) do Begin
								rmvArr[rmvN++] := nextRNode;
								nextRNode := nextRNode.NextElement('w:r');
							End;
							rNode := NewParagraphNode.FirstChildElement('w:r');
							nI := 0;
							rIndex := 0;
							while ifObj(rNode) do Begin
								cnt ++;
								if cnt <= curLine then Begin
									rmvArr[rmvN++] := rNode;
								End
								else Begin
									tArr[i+iStep+nI]['pNode'] := NewParagraphNode;
									tArr[i+iStep+nI]['rNode'] := rNode;
									tArr[i+iStep+nI]['rIndex'] := rIndex++;
									nr := new TRun(tArr[i+iStep+nI]['rNode']);
									nI ++;
								End;
								rNode := rNode.NextElement('w:r');
							End;
							//删除重复的run
							for rmvN := 0 to length(rmvArr)-1 do begin
								rmvArr[rmvN].Parent().DeleteChild(rmvArr[rmvN]);
							End;
						End;
						TOfficeApi().Set('CodePage', CodePage);
						
						flag := '';
						code := nil;
						tslArr := array();
						break;
					End
					else
						flag := '[TSL]';
				End;
				if Ord(c) > 127 then Begin
					if ifstring(code) then
						code += txt[k:k+1];
					k ++;
				End
				else if ifstring(code) then
					code += c;
				k ++;
				wz ++;
			End;
			if length(tslArr) then Begin
				//println('pIndex={},txt={},i={}',tArr[i]['pIndex'], txt, i);
				if i and i < length(tArr) and tArr[i]['pIndex'] <> tArr[i+1]['pIndex'] then Begin
					code += '\n';
					endPos ++;
				End;
				ind := length(tslArr) - 1;
				if tslArr[ind]['pIndex'] <> tArr[i]['pIndex'] or tslArr[ind]['rIndex'] <> tArr[i]['rIndex'] then
					tslArr[ind + 1] := tArr[i];
			End;
			i += iStep;
		End;
		return array(length(errArr), tslFuncCount, errArr);
	End;
	
	Function ExecTsTag(docx, tagName, tagObj);
	Begin
		//表格
		t := array();
		tslTagCount := 0;
		errArr := array();
		tArr := Tables();
		for i:=0 to length(tArr)-1 do Begin
			col := tArr[i].Cols();
			row := tArr[i].Rows();
			for r:= 1 to row do Begin
				for c:=1 to col do Begin
					cell := tArr[i].Cell(r, c);
					[err, cnt, err] := cell.ExecTsTag(docx, tagName, tagObj);//递归
					tslTagCount += cnt; 
					errArr union= err;
				End;
			End;
		End;
		
		//文本框
		ps := Paragraphs();
		for i:=0 to length(ps)-1 do Begin
			boxs := ps[i].TextBoxs();
			for j:=0 to length(boxs)-1 do Begin
				[err, cnt, err] := boxs[j].ExecTsTag(docx, tagName, tagObj);//递归
				if cnt then 
					boxs[j].Apply();
				tslTagCount += cnt; 
				errArr union= err;
			End;
		End;
		
		//页脚、页眉
		sArr := Sections();
		tpArr := array('default','even','first');
		for i:=0 to length(sArr)-1 do Begin
			for k, name in tpArr do Begin
				h := sArr[i].Header(name);
				if ifObj(h) then Begin
					[err, cnt, err] := h.ExecTsTag(docx, tagName, tagObj);//递归
					tslTagCount += cnt; 
					errArr union= err;
				End;
					
				f := sArr[i].Footer(name);
				if ifObj(f) then Begin
					[err, cnt, err] := f.ExecTsTag(docx, tagName, tagObj);//递归
					tslTagCount += cnt; 
					errArr union= err;
				End;
			End;
		End;
		
		[err, cnt, err] := ExecTsTagImpl(docx, tagName, tagObj);
		tslTagCount += cnt; 
		errArr union= err;
		return array(length(errArr), tslTagCount, errArr);
	End;
	
	Function ExecTsTagImpl(docx, tagName, tagObj);
	Begin
		tslTagCount := 0;
		errArr := array();
		tagArr := array();
		tArr := TextArray();
		tagAttribute := '';
		tagStr := '';
		tagStatus := '';//array('','head', 'attribute', 'tail');
		tagHead := '[' + tagName;
		tagTail := '[/' + tagName;
		tmp := array();
		while i < length(tArr) do Begin
			txt := '';
			iStep := 1;
			if ifObj(tArr[i]['rNode']) then Begin
				run := new TRun(tArr[i]['rNode']);
				txt := run.Text();
				if class(TSXml).IsUtf8() then
					txt := UTF8ToAnsi(txt);
			End;
			k := 1;
			wz := 1;
			txtLen := length(txt);
			while k <= txtLen do Begin
				c := txt[k];
				if c = ']' and (tagStatus = 'head' or tagStatus = 'attribute') and tagStr = tagHead then Begin //TAG头结束标志
					tagStr := '';
					tagArr := tArr[tmp['head-begin-paragraph']:i,:];
					wz++;
					tagStatus := 'tail';
					tmp['head-end-paragraph'] := i;
					tmp['head-end-pos'] := k++;
					tmp['head-end-wz'] := wz;
					tmp['head-end-txtlen'] := txtLen;
					continue;
				End;
				case tagStatus of
				'':
					if c = '[' then Begin
						tagStr := '[';
						tmp['head-begin-paragraph'] := i;
						tmp['head-begin-pos'] := k;
						tmp['head-begin-wz'] := wz;
						tmp['head-begin-txtlen'] := txtLen;
						tagStatus := 'head';
						tagAttribute := '';
					End;
				'head':
					if c = ' ' and tagStr = tagHead then Begin //找到TAG属性
						tagStatus := 'attribute';
					End
					else if length(tagStr) < length(tagHead) and lowercase(c) = lowercase(tagHead[ length(tagStr) + 1 ]) then Begin
						tagStr += tagHead[ length(tagStr) + 1 ];
					End
					else //继续寻找TAG开始标志
						tagStatus := '';
				'attribute':
					tagAttribute += c;
				'tail':
					if c=']' and tagStr = tagTail then Begin //查找到完整标签
						ind := length(tagArr) - 1;
						if tagArr[ind]['pIndex'] <> tArr[i]['pIndex'] or tagArr[ind]['rIndex'] <> tArr[i]['rIndex'] then Begin
							ind ++;
							tagArr[ind] := tArr[i];
						End;

						//[/tag]后
						if k < txtLen then Begin	//后面分割为新的w:r
							tArr[i]['rNode'] := run._duplicate_r(tArr[i]['rNode']);
							run._adjust_r(tArr[i]['rNode'], wz, txtLen);
							iStep := 0;
						End;
						//前[/tag]
						tagInd := length(tagArr) - i + tmp['tail-begin-paragraph'] - 1;
						if tmp['tail-begin-pos'] > 1 then Begin
							nNode := run._duplicate_r(tagArr[tagInd]['rNode']);
							run._adjust_r(tagArr[tagInd]['rNode'], 0, tmp['tail-begin-wz'] - 1);
							tagArr[tagInd]['pNode'].DeleteChild(nNode);
							tmp['tag-end'] := tagInd;
						End
						else if tmp['tail-begin-pos'] = 1 then Begin
							tmp['tag-end'] := tagInd - 1;
						End;

						//[tag]后
						firstNode := tagArr[0]['rNode'];
						tagInd := length(tagArr) - i + tmp['head-end-paragraph'] - 1;
						if tmp['head-end-pos'] < tmp['head-end-txtlen'] then Begin
							oldNode := tagArr[tagInd]['rNode'];
							tagArr[tagInd]['rNode'] := run._duplicate_r(oldNode);
							run._adjust_r(tagArr[tagInd]['rNode'], tmp['head-end-wz'] - 1, tmp['head-end-txtlen']);
							tmp['tag-beg'] := tagInd;
							if tmp['head-begin-paragraph'] <> tmp['head-end-paragraph'] then
								tagArr[tagInd]['pNode'].DeleteChild(oldNode);
						End
						else if tmp['head-end-pos'] = tmp['head-end-txtlen'] and tagInd then Begin
							tmp['tag-beg'] := tagInd + 1;
						End;
						//前[tag]
						if tmp['head-begin-pos'] > 1 then Begin
							run._adjust_r(firstNode, 0, tmp['head-begin-wz'] - 1);
							if firstNode = tagArr[0]['rNode'] then
								tagArr[0]['rNode'] := nil;
						End
						else if tagInd=0 and tmp['tag-beg']=0 then
							tagArr[0]['pNode'].DeleteChild(firstNode);

						//执行TAG逻辑
						r := array();
						for nI := 0 to length(tagArr)-1 do Begin
							if not ifObj(tagArr[nI]['rNode']) then continue;
							if nI >= tmp['tag-beg'] and nI <= tmp['tag-end'] then
								r[length(r)] := tagArr[nI];//标签中间文字内容
							else Begin //删除标签
								tagArr[nI]['pNode'].DeleteChild(tagArr[nI]['rNode']);
								node := tagArr[nI]['pNode'].FirstChildElement('w:r');
								if not ifObj(node) then Begin
									tagArr[nI]['pNode'].Parent().DeleteChild(tagArr[nI]['pNode']);
								End;
							End;
						End;
						tagObj.Init(tagName, tagAttribute, r);
						tagObj.Apply();
						tslTagCount++;
						
						tagStatus := '';
						tagArr := array();
						break;
					End
					else if length(tagStr) < length(tagTail) and lowercase(c) = lowercase(tagTail[ length(tagStr) + 1 ]) then Begin
						tagStr += tagTail[ length(tagStr) + 1 ];
						if tagStr = '[' then Begin
							tmp['tail-begin-paragraph'] := i;
							tmp['tail-begin-pos'] := k;
							tmp['tail-begin-wz'] := wz;
							tmp['tail-begin-txtlen'] := txtLen;
						End;
					End
					else //继续寻找TAG结束标志
						tagStr := '';
				End;
				if Ord(c) > 127 then Begin
					k ++;
				End
				k ++;
				wz ++;
			End;
			if length(tagArr) then Begin
				if i and i < length(tArr) and tArr[i]['pIndex'] <> tArr[i+1]['pIndex'] then Begin
					endPos ++;
				End;
				ind := length(tagArr) - 1;
				if tagArr[ind]['pIndex'] <> tArr[i]['pIndex'] or tagArr[ind]['rIndex'] <> tArr[i]['rIndex'] then
					tagArr[ind + 1] := tArr[i];
			End;
			i += iStep;
		End;
		return array(length(errArr), tslTagCount, errArr);
	End;
	
	Function GetHeadingListImpl(docx, posOpt, UpperHeadingLevel, LowerHeadingLevel, numIds, bHeadList);
	Begin
		r := array();
		if ifObj(posOpt) then
			pNode := posOpt.NextElement();
		else
			pNode := node_.FirstChildElement();
		sectPr := new TSectPr(docx, nil);
		while ifObj(pNode) do Begin
			name := pNode.GetName();
			if ifarray(numIds) and name = 'w:sectPr' then 
				sectPr.Init(pNode);
			else if name = 'w:p' then Begin
				sectNode := pNode.FirstChildElement('w:sectPr');
				if ifObj(sectNode) then Begin	//章节
					sectPr.Init(pNode);
				End
				else Begin
					p := new TParagraph(pNode);
					//统计数字项目编号
					numArr := array();
					ilvl := -1;
					numId := '';
					if ifarray(numIds) then Begin
						sectPr.Append(p);
						numId := p.Format.NumPr.Value('numId');
						lvlStr := p.Format.NumPr.Value('Level');
						if not ifnil(numId) and not ifnil(lvlStr) then Begin
							ilvl := Class(TSXml).SafeStrToIntDef(lvlStr, -1);
							if ilvl >= 0 and ilvl < 10 then Begin
								if not istable(numIds[numId]) then 
									numIds[numId] := array(0,0,0,0,0,0,0,0,0,0);
								prev := numIds[numId, ilvl];
								if prev then Begin
									for i:=ilvl+1 to 9 do 
										numIds[numId, i] := 0;
								End;
								numIds[numId, ilvl]++;
								numArr := numIds[numId];
							End;
						End;
					End;
					if bHeadList then Begin	//统计大纲显示（目录）
						styleId := p.Format.Value('StyleId');
						if styleId <> '' then Begin
							obj := docx.StyleObject().GetStyleById(styleId);
							if ifObj(obj) then Begin
								level := obj.HeadingLevel();
								iLevel := Class(TSXml).SafeStrToIntDef(level, -1);
								if iLevel+1 >= UpperHeadingLevel and iLevel+1 <= LowerHeadingLevel then Begin
									r[ind]['Level'] := strtoint(level);
									r[ind]['Paragraph'] := p;
									r[ind]['Text'] := p.Text();
									r[ind]['numId'] := integer(numId);	//数字项目编号
									r[ind]['ilvl'] := ilvl;		//级别
									r[ind]['numArr'] := numArr;	//累加数字编码
									sectPr.Mark(ind);//标记段落
									ind++;
								End;
							End;
						End;
					End;
				End;
			End
			else if ifarray(numIds) and name = 'w:tbl' then Begin
				tbl := TOfficeObj('TTable');
				tbl.Init(pNode);
				sectPr.Append(tbl);
				rows := tbl.Rows();
				cols := tbl.Cols();
				for i:=1 to rows do Begin
					for j:=1 to cols do Begin
						cell := tbl.Cell(i, j);
						[a, b] := cell.GetHeadingListImpl(docx, nil, UpperHeadingLevel, LowerHeadingLevel, numIds, false);//表格内递归查找，统计数字项目编号，但不显示在大纲中
					End;
				End;
			End;
			pNode := pNode.NextElement();
		End;
		
		if ifarray(numIds) then Begin	//设置页面
			for i:=0 to length(r)-1 do Begin
				r[i]['pageNo'] := sectPr.GetPageNo(i);
			End;
		End;
		return r;
	End;
	
	Function getPictureMaxId();
	Begin
		id := 0;
		pNode := node_.FirstChildElement('w:p');
		while ifObj(pNode) do Begin
			rNode := pNode.FirstChildElement('w:r');
			while ifObj(rNode) do Begin
				node := class(TSXml).GetNode(rNode, 'w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blibFill/a:blib');
				if ifObj(node) then Begin
					v := node.GetAttribute('r:embed');
					if v <> '' then Begin
						iVal := strtoint(v);
						if iVal > id then id := iVal;
					End;
				End;
				rNode := rNode.NextElement('w:r');
			End;
			pNode := pNode.NextElement('w:p');
		End;
		return id;
	End;
	
	Function addPart(posOpt, o);
	Begin
		node := posOpt;
		if ifObj(posOpt) and not (posOpt is Class(XmlNode)) then
			node := posOpt.Node();
		node := findNode(node, true);
		nodeArr := o.Marshal();
		if ifObj(node) then Begin
			o.node_ := node_.InsertAfterChild(node, nodeArr);	//XmlNode节点对象或DocObject对象
		End
		else if node = 0 then Begin
			o.node_ := node_.InsertFirstChild(nodeArr);
		End
		else if node < 0 then Begin
			o.node_ := node_.InsertEndChild(nodeArr);
		End
		else Begin
			raise 'Invalid input param.';
		End;
		TOfficeApi().Set('CurrentPosition', o.node_);
	End;
	
	Function findNode(posOpt, b);
	Begin
		if not ifObj(lastParagraph_) then 
			return 0;
		if ifObj(posOpt) then
			return posOpt;
		if b and posOpt = 0 then Begin
			return 0;
		End;
		if posOpt < 0 then 
			return lastParagraph_;
		
		if ifInt(posOpt) then Begin
			node := node_.FirstChildElement();
			ind := 0;
			while ifObj(node) do Begin
				name := node.GetName();
				if name = 'w:p' or name = 'w:tbl' then
					ind ++;
				if ind = posOpt + ifthen(b, 0, 1) then 
					return node;
				node := node.NextElement();
			End;
		End;
		if b then
			return lastParagraph_;
		return 0;
	End;
	
	Function getText(t);
	Begin
		if not ifstring(t) then return '' $ t;
		return t;
		txt := ReplaceStr(t, '\t', '<w:tab/>');
		txt := ReplaceStr(txt, '\r\n', '<w:br/>');
		txt := ReplaceStr(txt, '\n', '<w:br/>');
		return txt;
	End;

	Function _set_lastParagraph_(posOpt, node);
	Begin
		if not ifObj(lastParagraph_) then 
			lastParagraph_ := node;
		else if ifInt(posOpt) and posOpt = -1 then
			lastParagraph_ := node;
		else if ifObj(posOpt) then Begin
			posNode := posOpt;
			if not (posOpt is Class(XmlNode)) then
				posNode := posOpt.Node();
			if lastParagraph_.Eq(posNode) then Begin
				_setLastParagraph();
			End;
		End;
	End;
	
	zipfile_;
	lastParagraph_;
	document_;
End;

Type TDocHeaderFooter = Class(TDocumentBody)
	Function Create(rid, obj, name);
	Begin
		rID_ := rid;
		xmlObj_ := obj;
		node := xmlObj_.FirstChildElement(name);
		Index := -1;
		Class(TDocumentBody).Create(node);
		name_ := name;
	End;
	
	///添加页码
	///fmt：string，页码格式（eg："第 {0} 页，共 {1} 页"）
	///font：字体格式
	Function AddPageNumber(fmt, font);
	Begin
		r := array();
		fmtLen := length(fmt);
		txt := '';
		while i < fmtLen do Begin
			if fmt[i+1] = '{' and i + 2 <= fmtLen and fmt[i+3] = '}' then Begin
				if txt <> '' then 
					r[ cnt++ ] := txt;
				r[ cnt++ ] := fmt[i+1:i+3];
				txt := '';
				i += 3;
			End
			else Begin
				txt += fmt[i+1];
				i ++;
			End;
		End;
		if txt <> '' then 
			r[ cnt++ ] := txt;
		p := TOfficeObj('TParagraph');
		class(TSXml).CopyRprFormat(p.pPr.rPr, font);
		for i:=0 to length(r)-1 do Begin
			run := p.AddRun();
			if r[i] = '{0}' then Begin	//页码
				run.fldCharType := 'begin';
				class(TSXml).CopyRprFormat(run.rPr, font);
				PageNo := p.AddRun();
				PageNo.InstrText := ' PAGE \\* MERGEFORMAT ';
				PageNo.InstrTextSpace := 'preserve';
				class(TSXml).CopyRprFormat(PageNo.rPr, font);
				run := p.AddRun();
				run.fldCharType := 'end';
				class(TSXml).CopyRprFormat(run.rPr, font);
			End
			else if r[i] = '{1}' then Begin	//总页数
				run.fldCharType := 'begin';
				class(TSXml).CopyRprFormat(run.rPr, font);
				TotalPageNo := p.AddRun();
				TotalPageNo.InstrText := ' NUMPAGES \\* MERGEFORMAT ';
				TotalPageNo.InstrTextSpace := 'preserve';
				class(TSXml).CopyRprFormat(TotalPageNo.rPr, font);
				run := p.AddRun();
				run.fldCharType := 'end';
				class(TSXml).CopyRprFormat(run.rPr, font);
			End
			else Begin
				run.SetText( r[i] );
				class(TSXml).CopyRprFormat(Run.rPr, font);
			End;
		End;
		return AddParagraph(p, -1, nil);
	End;
	
	rId_:integer;
	xmlFileName_:string;
	root_;
	xmlObj_;
End;

Type TDocSection = Class(DocObject, TDocSectionImpl)
	Function Create();overload;
	Begin
		Create(nil);
	End;
	
	Function Create(node);overload;
	Begin
		Create(node, -1, nil);
	End;
	
	Function Create(node, index, z);overload;
	Begin
		Index_ := index;
		name_ := 'w:sectPr';
		node_ := node;
		zipfile_ := z;
		Class(TDocSectionImpl).Create(nil, name_);
		InitRootNode(node);
	End;

	///返回指定页眉
	///type：页眉类型，（default、even、first）
    ///default, Header for odd pages or all if no even header.
    ///first, Header for first page of section.
    ///even, Header for even pages of recto/verso section.
	Function Header(type);
	Begin
		return _getHeaderFooter('w:headerReference', type);
	End;
	
	///返回指定页脚
	///type：页眉类型，（default、even、first）
    ///default, Header for odd pages or all if no even header.
    ///first, Header for first page of section.
    ///even, Header for even pages of recto/verso section.
	Function Footer(type);
	Begin
		return _getHeaderFooter('w:footerReference', type);
	End;
	
	///添加页眉
	///type：页眉类型，（default、even、first）
    ///default, Header for odd pages or all if no even header.
    ///first, Header for first page of section.
    ///even, Header for even pages of recto/verso section.
	Function AddHeader(type);
	Begin
		return _AddHeaderFooter('header', (ifNil(type) or type = '') ? 'default' : type);
	End;
	
	///添加页脚
	///type：页眉类型，（default、even、first）
    ///default, Header for odd pages or all if no even header.
    ///first, Header for first page of section.
    ///even, Header for even pages of recto/verso section.
	Function AddFooter(type);
	Begin
		return _AddHeaderFooter('footer', (ifNil(type) or type = '') ? 'default' : type);
	End;
	
	Function _AddHeaderFooter(headerFooter, hfType);
	Begin
		if headerFooter = 'header' then Begin
			name := 'w:hdr';
			type := 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/header';
			ContentType := 'application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml';
			obj := _getHeaderFooter('w:headerReference', hfType);	//页眉已经存在
			fileContent := '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:hdr xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:wpsCustomData="http://www.wps.cn/officeDocument/2013/wpsCustomData" mc:Ignorable="w14 w15 wp14"></w:hdr>';
		End
		else Begin
			name := 'w:ftr';
			type := 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer';
			ContentType := 'application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml';
			obj := _getHeaderFooter('w:footerReference', hfType);	//页脚已经存在
			fileContent := '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:ftr xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 wp14"></w:ftr>';
		End
		if ifObj(obj) then return obj;
		rels := zipfile_.Get('word/_rels/document.xml.rels');
		[rid, target] := class(TSXml).FindRelationshipRid(rels, '');//最大rId
		rid ++;
		files := sselect ['FileName'] from zipfile_.Files() where AnsiStartsText('word/' $ headerFooter, ['FileName']) end;
		fid := length(files) + 1;//文件ID号
		target := headerFooter $ fid $ '.xml';
		class(TSXml).AddRelationshipRid(rels, target, type, 'rId'$rid, nil);//添加rId
		PartName := '/word/' $ headerFooter $ fid $ '.xml';
		contentXml := zipfile_.Get('[Content_Types].xml');
		class(TSXml).AddOverrideContentType(contentXml, partName, contentType);//添加Contet_Types
		fname := 'word/' $ headerFooter $ fid $ '.xml';
		zipfile_.Add(fname, fileContent);//创建页脚、页眉文件
		node := node_.InsertFirstChild('element', headerFooter = 'header' ? 'w:headerReference' : 'w:footerReference');
		node.SetAttribute('w:type', hfType);
		node.SetAttribute('r:id', 'rId'$rid);
		if hfType = 'first' then Begin
			docGridNode := node_.FirstChildElement('w:docGrid');
			titlePg := node_.FirstChildElement('w:titlePg');
			if not ifObj(titlePg) then Begin
				if ifObj(docGridNode) then 
					titlePg := node_.InsertBeforeChild(docGridNode,'element','w:titlePg');
				else
					titlePg := node_.InsertEndChild('element','w:titlePg');
			End;
		End;
		
		if hfType = 'even' then Begin
			settingsXml := zipfile_.Get('word/settings.xml');
			if ifObj(settingsXml) then Begin
				evenObj := settingsXml.FirstChildElement('w:settings').FirstChildElement('w:evenAndOddHeaders');
				if not ifObj(evenObj) then
					evenObj := settingsXml.FirstChildElement('w:settings').InsertFirstChild('element','w:evenAndOddHeaders');
				evenObj.SetAttribute('w:val', 1);
			End;
		End;
		return new TDocHeaderFooter(rid, zipfile_.Get(fname), name);//返回页脚、页眉对象
	End;

	Function _getRid(key, type);
	Begin
		if ifNil(type) or type = '' then
			type := 'default';
		node := node_.FirstChildElement(key);
		while ifObj(node) do Begin
			name := node.GetName();
			if name = key then Begin
				if type = node.GetAttribute('w:type') then 
					return node.GetAttribute('r:id');
			End;
			node := node.NextElement(key);
		End;
		return '';
	End;

	Function _getHeaderFooter(key, type);
	Begin
		rid := _getRid(key, type);
		if rid='' then return nil;
		rels := zipfile_.Get('word/_rels/document.xml.rels');
		theNode := class(TSXml).FindRelationship(rels, rid);
		if not ifObj(theNode) then
			return nil;
		fname := 'word/' $ theNode.GetAttribute('Target');
		xml := zipfile_.Get(fname);
		if ifObj(xml) then
			return new TDocHeaderFooter(rid, xml, key = 'w:headerReference' ? 'w:hdr' : 'w:ftr');
		return nil;
	End;

	Index_:integer;
	zipfile_;	//压缩文件对象
End;

//node_ -> w:p/w:r/mc:AlternateContent/mc:Choice/mc:Fallback/w:pict/v:shape/v:textbox/w:txbxContent
Type TTextBox = Class(TDocumentBody, TTextBoxImpl)
	Function Create();overload;
	Begin
		Create(nil);
	End;
	
	Function Create(node);overload;
	Begin
		Class(TTextBoxImpl).Create(nil, 'w:txbxContent');
		Class(TDocumentBody).Create(node);
		name_ := 'w:txbxContent';
		InitRootNode(node);
	End;
	
	Function Create(pNode, name);overload;
	Begin
		Create(nil);
	End;
	
	Function Init(pNode, nodeEx);
	Begin
		pNode_ := pNode;
		NodeEx_ := nodeEx;
	End;
	
	Function Apply();override;
	Begin
		if ifObj(NodeEx_) then Begin
			data := node_.Marshal();
			NodeEx_.DeleteChildren();
			class(TSXml).UpdateNode(NodeEx_, data[0]['attributes'], data[0]['children']);
		End;
	End;
	
	pNode_;//<w:p>
	NodeEx_;//w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:txbx/wps:txbxContent
End;

//w:tr
Type TRow = Class(DocObject, TwTr)
	Function Create(node);
	Begin
		node_ := node;
		Class(TwTr).Create(nil, 'w:tr');
	End;
	
	Property Format read readFormat;
	Function readFormat();
	Begin
		return TrPr;
	End;
	
	Property FormatEx read readFormatEx;
	Function readFormatEx();
	Begin
		return tblPrEx;
	End;
	
	Function Apply();virtual;
	Begin
		arr := Marshal();
		class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']);
	End;
End;

//w:tc
Type TCell = Class(TDocumentBody, TWTc)
	Function Create();overload;
	Begin
		Create(nil);
	End;
	Function Create(node);overload;
	Begin
		Class(TDocumentBody).Create(node);
		Create(node, 'w:tc');
	End;
	
	Function Create(pNode, name);overload;
	Begin
		Class(TWTc).Create(nil, 'w:tc');
		InitRootNode(pNode);
		name_ := 'w:tc';
		mergeSpan_ := 0;
		pPr_ := new TwpPr();
	End;
	
	Property Format read readFormat;
	Function readFormat();
	Begin
		return TcPr;
	End;
	
	Property PFormat read readPFormat;
	Function readPFormat();
	Begin
		return pPr_;
	End;
	
	Function Apply(); override;
	Begin
		arr := Marshal();
		class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']);
		
		arr := pPr_.Marshal();
		if length(arr['attributes']) or length(arr['children']) then Begin
			pNode := node_.FirstChildElement('w:p');
			while ifObj(pNode) do Begin
				pPr := class(TSXml).GetNode(pNode, 'w:pPr', 'first');
				class(TSXml).UpdateNode(pPr, arr['attributes'], arr['children']);
				pNode := pNode.NextElement();
			End;
		End;
	End;
	
	///添加文字
	Function SetText(txt);
	Begin
		if not ifString(txt) then 
			lines := array('' $ txt);
		else
			lines := str2array(txt, '\n');
		for i:=0 to length(lines)-1 do Begin
			newp := new TParagraph();
			newp.pPr.rPr.Lang := 'en-US';
			newp.pPr.rPr.eastAsia := 'zh-CN';
			newp.Run.rPr.Lang := 'en-US';
			newp.Run.rPr.eastAsia := 'zh-CN';
			newp.Run.SetText( lines[i] );
			NewChildNode( array("field":"", "name":"w:p", "obj":newp, "attrEx":"", "nodeType":"") );
		End;
		if not istable(lines) then
			P.Run.T := '';
	End;
	
	Function Clear();
	Begin
		node := node_.FirstChildElement('w:p');
		while ifObj(node) do Begin
			n := node.NextElement();
			if ind = 0 then
				node.DeleteChildren();
			else
				node_.DeleteChild(node);
			ind++;
			node := n;
		End;
	End;
	
	Function Row();
	Begin
		return new TRow(node_.Parent());
	End;
	
	Function Append(c);
	Begin
		ps := c.Paragraphs();
		for i:=0 to length(ps)-1 do Begin
			data := ps[i].node_.Marshal();
			w := node_.InsertEndChild(data[0]);
		End;
	End;
	
	mergeSpan_:integer;
	pPr_;//段落格式
End;

//w:tbl
Type TTable = Class(DocObject, TTableImpl)
	Function Create();overload;
	Begin
		Create(nil);
	End;
	
	Function Create(node);overload;
	Begin
		name_ := 'w:tbl';
		Class(TTableImpl).Create(nil, 'w:tbl');
		if ifObj(node) then
			Init(node);
	End;
	
	Function Root();override;
	Begin
		return node_;
	End;
	
	Function Init(node);
	Begin
		node_ := node;
		cells_ := array();
		iCol_ := 0;
		row := node.FirstChildElement('w:tr');
		while ifObj(row) do Begin
			col := row.FirstChildElement('w:tc');
			iCol := 0;
			while ifObj(col) do Begin
				//c := new TCell(col);
				cells_[iRow, iCol] := array(col, 0);
				iCol ++;
				mergeSpan := _getVSpan(col);//合并单元格
				if mergeSpan > 0 then Begin
					//c.mergeSpan_ := mergeSpan;
					cells_[iRow, iCol, 1] := mergeSpan;
					for j:=1 to mergeSpan-1 do Begin
						cells_[iRow, iCol] := nil;
						iCol ++;
					End;
				End;
				if iCol > iCol_ then iCol_ := iCol;
				col := col.NextElement('w:tc');
			End;
			iRow ++;
			row := row.NextElement('w:tr');
		End;
		InitRootNode(node);
	End;
	
	///设置表格数据
	///data: table，数据表
	///[includeHeader: bool] 是否包括表头，默认FALSE
	///[includeIndex: bool] 是否自动添加索引号，默认FALSE
	Function SetData(docx, data, includeHeader, includeIndex);
	Begin
		if not IsTable(data) then
			raise "Invalid Data.";
		[rowcount,colcount] := mSize(data);//一维数组
		if colcount = 0 then 
			data := array(data);
		fields := FieldNames(data);
		if IsTable(fields) then Begin
			r := nils(length(data),length(fields));
			r[:,:] := data;
			data := r;
		End;
		if includeIndex then Begin
			n := length(data)-1;
			r := array(0->n);
			data := `r | data;
		End;
		if includeHeader and IsTable(fields) then Begin
			if includeIndex then
				fields := array("Index") union fields;
			data := array(fields) union data;
		End;
		Data_ := data;
		//TblPr.StyleId := 'Normal Table';
		TblPr.Width := 0;
		TblPr.WidthType := 'auto';
		TblPr.Borders.Top.Val := 'single';
		TblPr.Borders.Left.Val := 'single';
		TblPr.Borders.Bottom.Val := 'single';
		TblPr.Borders.Right.Val := 'single';
		TblPr.Borders.InsideH.Val := 'single';
		TblPr.Borders.InsideV.Val := 'single';
		TblPr.CellMar.Top := 0;
		TblPr.CellMar.Left := 108;
		TblPr.CellMar.Bottom := 0;
		TblPr.CellMar.Right := 108;
		TblPr.CellMar.TopType := 'dxa';
		TblPr.CellMar.LeftType := 'dxa';
		TblPr.CellMar.BottomType := 'dxa';
		TblPr.CellMar.RightType := 'dxa';
		//TblPr.FirstColumn := 1;
		//TblPr.FirstRow := 1;
		//TblPr.LastColumn := 0;
		//TblPr.LastRow := 0;
		//TblPr.NoVBand := 1;
		//TblPr.NoHBand := 0;
		//TblPr.Val := '04A0';

		width := getBlockWidth(docx);
		[rowCount, cnt] := MSize(data);
		colCount_ := cnt;
		colWidth_ := colCount_ ? integer(width / colCount_) : 0;
		gridArr := array();
		for i:=0 to colCount_-1 do Begin
			gcol := new TwGridCol();
			gcol.W := colWidth_;
			gridArr union= array(('name':'w:gridCol','obj':gcol,'attrEx':'','nodeType':'','attrName':''));
		End;
		TblGrid.GridCol := gridArr;
	End;

	Property Format read readFormat;
	Function readFormat();
	Begin
		return TblPr;
	End;
	
	Property Paragraph read readParagraph;
	Function readParagraph();
	Begin
		if not ifObj(paragraph_) then
			paragraph_ := new TParagraph();
		return paragraph_;
	End;
	
	Property FormatEx read readFormatEx;
	Function readFormatEx();
	Begin
		return TblPr.tblpPr;
	End;
	
	///修改表格属性
	Function Apply(); override;
	Begin
		arr := Marshal();
		class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']);
	End;
	
	///列数
	Function Cols();
	Begin
		return iCol_;
	End;
	
	///行数
	Function Rows();
	Begin
		return length(cells_);
	End;
	
	///获取单元格
	Function Cell(row, col);
	Begin
		if row > length(cells_) then return nil;
		c := cells_[row-1, col-1];
		if ifNil(c) then return nil;
		cellObj := new TCell(c[0]);
		cellObj.mergeSpan_ := c[1];
		return cellObj;
	End;
	
	///设置列宽
	Function ColumnWidth(n, wth);
	Begin
		if n >0 and n <= length(TblGrid.GridCol) then 
			TblGrid.GridCol[n-1]['obj'].W := wth;
	End;

	/// 设置行高
    Function RowHeight(row, height);
    Begin
		if row <= 0 or row > Rows() then return;
		node := node_.FirstChildElement('w:tr');
		cnt := row - 1;
		while(cnt) do
		begin
			node := node.NextElement('w:tr');
			cnt--;
		end
		trnode := node.FirstChildElement("w:trPr");
		if not ifObj(trnode) then trnode := node.InsertFirstChild('element', 'w:trPr');
		node := trnode.FirstChildElement('w:trHeight');
		if not ifObj(node) then node := trnode.InsertFirstChild('element', 'w:trHeight');
		node.SetAttribute('w:val', height);
    End;

	Function Height(row);
	Begin
		if row <= 0 or row > Rows() then return nil;
		node := node_.FirstChildElement('w:tr');
		cnt := row - 1;
		while(cnt) do
		begin
			node := node.NextElement('w:tr');
			cnt--;
		end
		obj := new TwTr();
		obj.InitRootNode(node);
		return obj.TrPr.Value('Height');
	End;

	Function Width(col);
	Begin
		obj := Cell(1, col);
		return obj.Format.Value('Width');
	End;
	
	///合并单元格
	///del: bool，是否删除其它单元格内容（只保留左上单元格内容）
	Function Merge(top, left, bottom, right, del);overload;
	Begin
		//<w:gridSpan w:val="3"/>
		//<w:vMerge w:val="restart"/>
		rowCount := Rows();
		if left > right or top > bottom or left > iCol_ or top > rowCount or (left = right and top = bottom) then 
			return 'Invalid input param.';
		//合并其它单元格
		[left2, right2, top2, bottom2] := array(left, right, top, bottom);
		//println('merge(left2, right2, top2, bottom2)={}',array(left2, right2, top2, bottom2));
		for i:=left to right do Begin
			if top > 1 then Begin
				c1 := Cell(top - 1, i);
				c2 := Cell(top, i);
				if (c2 = nil or c2.mergeSpan_ > 0) and (c1 = nil or c1.mergeSpan_ > 0) then Begin
					top2 := _getTop(top - 1, i, top2); 
				End;
			End;
			
			if bottom < rowCount then Begin
				c1 := Cell(bottom, i);
				c2 := Cell(bottom + 1, i);
				if (c2 = nil or c2.mergeSpan_ > 0) and (c1 = nil or c1.mergeSpan_ > 0) then Begin
					bottom2 := _getBottom(bottom + 1, rowCount, i, bottom2);
				End;
			End;
		End;
		for i:=top to bottom do Begin
			if left > 1 then Begin
				c1 := Cell(i, left - 1);
				c2 := Cell(i, left);
				if c2 = nil and (c1 = nil or c1.mergeSpan_ > 0) then
					left2 := _getLeft(i, left - 1, left2); 
			End;
			
			if right < iCol_ then Begin
				c1 := Cell(i, right);
				c2 := Cell(i, right + 1);
				if c2 = nil and (c1 = nil or c1.mergeSpan_ > 0) then
					right2 := _getRight(i, right + 1, right2); 
			End;
		End;
		//println('merge(left2, right2, top2, bottom2)={}\n',array(left2, right2, top2, bottom2));
		val := right2 - left2 + 1;
		theCell := Cell(top2, left2);
		for row:=top2 to bottom2 do Begin
			c := Cell(row, left2);
			c.mergeSpan_ := val;
			gridSpan := class(TSXml).GetNode(c.node_, 'w:tcPr/w:gridSpan', true);
			gridSpan.SetAttribute('w:val', val);
			node := class(TSXml).GetNode(c.node_, 'w:tcPr/w:vMerge', true);
			node.SetAttribute('w:val', row=top2 ? 'restart' : 'continue');
			if row <> top2 then Begin
				if not del then 
					theCell.Append(c);
				c.Clear();
			End;
			
			for col:=left2 + 1 to right2 do Begin
				c := Cell(row, col);
				if ifObj(c) then Begin
					if not del then 
						theCell.Append(c);
					c.node_.Parent().DeleteChild(c.node_);
					cells_[row-1, col-1] := nil;
				End;
			End;
		End;
		
		return 'ok';
	End;
	
	///合并单元格
	///hcell: string，左上角坐标，eg: 'B2'
	///vcell: string，右下角坐标，eg: 'C4'
	///del: bool，是否删除其它单元格内容（只保留左上单元格内容）
	Function Merge(hCell, vCell, del);overload;
	Begin
		[err1, left, top] := CellNameToCoordinates(hCell);
		[err2, right, bottom] := CellNameToCoordinates(vCell);
		if err1 or err2 then 
			return 'Invalid input Coordinates.';
		return Merge(top, left, bottom, right, del);
	End;
	
	Function _getLeft(row, iCol, left2);
	Begin
		for i:=iCol downto 1 do Begin
			c := Cell(row, i);
			if ifObj(c) then Begin
				if i < left2 then
					left2 := i;
				break;
			End;
		End;
		return left2;
	End;
	
	Function _getRight(row, iCol, right2);
	Begin
		for i:=iCol to iCol_ do Begin
			c := Cell(row, i);
			if ifObj(c) then
				break;
			if i > right2 then
				right2 := i;
		End;
		return right2;
	End;
	
	Function _getTop(top, iCol, top2);
	Begin
		for i:=top downto 1 do Begin
			c := Cell(i, iCol);
			if ifObj(c) and c.mergeSpan_ < 1  then Begin
				break;
			End;
			if i < top2 then 
				top2 := i;
		End;
		return top2;
	End;
	
	Function _getBottom(bottom, rowCount, iCol, bottom2);
	Begin
		for i:=bottom to rowCount do Begin
			c := Cell(i, iCol);
			if ifObj(c) and c.mergeSpan_ < 1 then Begin
				break;
			End;
			if i > bottom2 then
				bottom2 := i;
		End;
		return bottom2;
	End;
	
	Function _getVSpan(node);
	Begin
		vMerge := class(TSXml).GetNode(node, 'w:tcPr/w:vMerge');
		if ifObj(vMerge) and vMerge.GetAttribute('w:val') in array('restart', 'continue') then Begin
			nSpan := class(TSXml).GetNode(node, 'w:tcPr/w:gridSpan');
			if ifObj(nSpan) then Begin
				return strtoint(nSpan.GetAttribute('w:val'));
			End;
		End;
		return -1;
	End;
	
	Function getBlockWidth(docx);
	Begin
		sectPr := docx.Body().node_.FirstChildElement('w:sectPr');
		try
			width := sectPr.FirstChildElement('w:pgSz').GetAttribute('w:w');
			left := sectPr.FirstChildElement('w:pgMar').GetAttribute('w:left');
			right := sectPr.FirstChildElement('w:pgMar').GetAttribute('w:right');
			return strtoint(width) - strtoint(left) - strtoint(right);
		except
		End;
		return strtoint(width);
	End;
	
	iCol_:integer;
	cells_;
	Data_;
	colCount_;
	colWidth_;
	paragraph_;//缺省单元格段落格式、字体格式
End;

Type TCoreProperties = Class(DocObject)
	Property Author read readAuthor write writeAuthor;
	Property Category read readCategory write writeCategory;
	Property Description read readDescription write writeDescription;
	Property Subject read readSubject write writeSubject;
	Property Title read readTitle write writeTitle;
	Property Version read readVersion write writeVersion;
	Property Rversion read readRversion write writeRversion;
	Property KeyWords read readKeyWords write writeKeyWords;
	Property Created read readCreated write writeCreated;
	Property Modified read readModified write writeModified;
	Property LastModifiedBy read readLastModifiedBy write writeLastModifiedBy;
private
	Function readAuthor();
	Begin
		return propValue('dc:creator');
	End;
	
	Function readCategory();
	Begin
		return propValue('cp:category');
	End;
	
	Function readDescription();
	Begin
		return propValue('dc:description');
	End;
	
	Function readSubject();
	Begin
		return propValue('dc:subject');
	End;
	
	Function readTitle();
	Begin
		return propValue('dc:title');
	End;
	
	Function readVersion();
	Begin
		return propValue('cp:version');
	End;
	
	Function readRversion();
	Begin
		return propValue('cp:rversion');
	End;
	
	Function readKeyWords();
	Begin
		return propValue('cp:keywords');
	End;
	
	Function readLastModifiedBy();
	Begin
		return propValue('cp:lastModifiedBy');
	End;
	
	Function readCreated();
	Begin
		return propValue('dcterms:created');
	End;
	
	Function readModified();
	Begin
		return propValue('dcterms:modified');
	End;
	
	Function propValue(k);
	Begin
		node := class(TSXml).GetNode(node_, k);
		if not ifObj(node) then return '';
		return class(TSXml).Utf8ToCurCodePage( node.GetText() );
	End;
	
	Function propNode(k);
	Begin
		n := node_.FirstChildElement(k);
		if ifObj(n) then return n;
		return node_.InsertEndChild('element', k);
	End;

	Function writeAuthor(v);
	Begin
		return propNode('dc:creator').SetValue(class(TSXml).CurCodePageToUtf8(v));
	End;
	
	Function writeCategory(v);
	Begin
		return propNode('cp:category').SetValue(class(TSXml).CurCodePageToUtf8(v));
	End;
	
	Function writeDescription(v);
	Begin
		return propNode('dc:description').SetValue(class(TSXml).CurCodePageToUtf8(v));
	End;
	
	Function writeSubject(v);
	Begin
		return propNode('dc:subject').SetValue(class(TSXml).CurCodePageToUtf8(v));
	End;
	
	Function writeTitle(v);
	Begin
		return propNode('dc:title').SetValue(class(TSXml).CurCodePageToUtf8(v));
	End;
	
	Function writeVersion(v);
	Begin
		return propNode('cp:version').SetValue(class(TSXml).CurCodePageToUtf8(v));
	End;
	
	Function writeRversion(v);
	Begin
		return propNode('cp:rversion').SetValue(class(TSXml).CurCodePageToUtf8(v));
	End;
	
	Function writeKeyWords(v);
	Begin
		return propNode('cp:keywords').SetValue(class(TSXml).CurCodePageToUtf8(v));
	End;
	
	Function writeLastModifiedBy(v);
	Begin
		return propNode('cp:lastModifiedBy').SetValue(class(TSXml).CurCodePageToUtf8(v));
	End;
	
	Function writeCreated(v);
	Begin
		return propNode('dcterms:created').SetValue(class(TSXml).GetDatetimeStr(v));
	End;
	
	Function writeModified(v);
	Begin
		return propNode('dcterms:modified').SetValue(class(TSXml).GetDatetimeStr(v));
	End;
End;

//w:latentStyles
//		Attributes(w:name、w:count、w:defLockedState、w:defQFormat、w:defSemiHidden、w:defUIPriority、w:defUnhideWhenUsed)


//w:style
//        'w:name', 'w:aliases', 'w:basedOn', 'w:next', 'w:link',
//        'w:autoRedefine', 'w:hidden', 'w:uiPriority', 'w:semiHidden',
//        'w:unhideWhenUsed', 'w:qFormat', 'w:locked', 'w:personal',
//        'w:personalCompose', 'w:personalReply', 'w:rsid', 'w:pPr', 'w:rPr',
//        'w:tblPr', 'w:trPr', 'w:tcPr', 'w:tblStylePr'
Type TDocxStyle = Class(TDocxStyleImpl)
	Function Create(); overload;
	Begin
		create(nil);
	End;

	Function Create(node); overload;
	Begin
		Init(node);
		Class(TDocxStyleImpl).Create(nil, 'w:style');
	End;
	
	Function Init(node);
	Begin
		if ifObj(node) then Begin
			node_ := node;
			wType := node.GetAttribute('w:type');
			styleId := node.GetAttribute('w:styleId');
			nameObj := node.FirstChildElement('w:name');
			if ifObj(nameObj) then
				Name := nameObj.GetAttribute('w:val');
			InitRootNode(node);
		End;
	End;
	
	///显示大纲级别
	Function HeadingLevel();
	Begin
		node := class(TSXml).GetNode(node_, 'w:pPr/w:outlineLvl');
		if ifObj(node) then
			return node.GetAttribute('w:val');
		return '';
	End;
	
	Function ReadPprFormat();
	Begin
		if ifObj(pPr_) then 
			return pPr_;
		pPr_ := Class(TSXml).ReadPprFormat(node_);
		return pPr_;
	End;
	
	Function ReadRprFormat();
	Begin
		if ifObj(rPr_) then 
			return rPr_;
		rPr_ := Class(TSXml).ReadRprFormat(node_);
		return rPr_;
	End;
	
	Function Apply();
	Begin
		if ifObj(rPr_) then Begin
			arr := rPr_.Marshal();
			if length(arr['attributes']) or length(arr['children']) then Begin
				class(TSXml).UpdateNode(rPr_.Root(), arr['attributes'], arr['children']);
			End;
		End;
		
		if ifObj(pPr_) then Begin
			arr := pPr_.Marshal();
			if length(arr['attributes']) or length(arr['children']) then Begin
				class(TSXml).UpdateNode(pPr_.Root(), arr['attributes'], arr['children']);
			End;
		End;

		arr := self.Marshal();
		if length(arr['attributes']) or length(arr['children']) then Begin
			class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']);
		End;
	End;
	
	node_;
	pPr_;
	rPr_;
End;

Type TNumStyle = Class(TNumStyleImpl)
	Function Create(); overload;
	Begin
		create(nil);
	End;

	Function Create(node); overload;
	Begin
		Init(node);
		Class(TNumStyleImpl).Create(nil, 'w:num');
	End;
	
	Function Init(node);
	Begin
		if ifObj(node) then Begin
			node_ := node;
			abstractNumId := node.GetAttribute('w:abstractNumId');
			typeNode := node.FirstChildElement('w:multiLevelType');
			if ifObj(typeNode) then
				multiLevelType := typeNode.GetAttribute('w:val');
			fmtNode := class(TSXml).GetNode(node, 'w:lvl/w:numFmt');
			if ifObj(fmtNode) then
				numFmt := fmtNode.GetAttribute('w:val');
			InitRootNode(node);
		End;
	End;
	
	Function Root();override;
	Begin
		return node_;
	End;
	
	///数字项目编号样式ID
	Function Id();
	Begin
		return abstractNumId;
	End;
	
	///数字项目编号字符串
	Function GetText(ilvl, arr);
	Begin
		if numFmt = 'bullet' then
			return '';
		if not ifarray(levels_) then Begin
			levels_ := array();
			node := node_.FirstChildElement('w:lvl');
			while ifObj(node) do Begin
				startObj := node.FirstChildElement('w:start');
				fmtObj := node.FirstChildElement('w:numFmt');
				textObj := node.FirstChildElement('w:lvlText');
				start := ifObj(startObj) ? Class(TSXml).SafeStrToIntDef(startObj.GetAttribute('w:val'), 1) : 1;
				fmt := ifObj(fmtObj) ? fmtObj.GetAttribute('w:val') : '';
				lvlText := ifObj(textObj) ? textObj.GetAttribute('w:val') : '';
				levels_[length(levels_)] := array('node':node, 'text':lvlText, 'numFmt':fmt, 'start':start);
				node := node.NextElement('w:lvl');
			End;
		End;
		if ilvl < 0 or ilvl >= length(levels_) then
			return '';
		str := levels_[ilvl]['text'];
		for i:=ilvl downto 0 do Begin
			srcFmt := '%' $ (i + 1);
			destStr := _getNumStr(arr[i], levels_[i]['numFmt'], levels_[i]['start']-1);
			str := ReplaceStr(str, srcFmt, destStr);
		End;
		return str;
	End;
	
	Function _getNumStr(index, fmt, start);
	Begin
		num := index + start;
		if fmt = 'decimal' or num >= 10000 then //数字项目编号 14.1.1
			return '' $ num;
		//中文编号
		chNum := array('零','一','二','三','四','五','六','七','八','九','十','十一','十二','十三','十四','十五','十六','十七','十八','十九');
		if num < 20 then 
			return chNum[num];
		v4 := int(num/1000);
		s4 := v4 ? chNum[v4] + '千' : '';
		v3 := int((num % 1000) / 100);
		s3 := v3 ? chNum[v3] + '百' : (s4 <> '' ? '零' : '');
		v2 := int((num % 100) / 10);
		s2 := v2 ? chNum[v2] + '十' : ((s4+s3) <> '' ? '零' : '');
		v1 := num % 10;
		s1 := v1 ? chNum[v1] : '';
		if s3='零' and s2='零' then s3 := '';
		if s1='' and s2='零' then s2 := '';
		return s4 + s3 + s2 + s1;
	End;
	
	numFmt;
	node_;
	levels_;
End;

Function _getDocObject(node, name);
Begin
	p := nil;
	case name of
	'w:del','w:ins':
		p := new TRevision(node);
	'w:p':
		p := new TParagraph(node);
	'w:tbl':
		p := new TTable(node);
	'w:r':
		p := new TRun();
	End;
	if ifObj(p) then Begin
		p.node_ := node;
		p.name_ := name;
	End;
	return p;
End;

///返回全部列表
Function getDocumentObjects(parent, prefix);
Begin
	ps := array();
	node := parent.FirstChildElement();
	while ifObj(node) do Begin
		name := node.GetName();
		if length(prefix) = 0 or (ifstring(prefix) and name = prefix) or (istable(prefix) and (name in prefix)) then Begin
			p := _getDocObject(node, name);
			if p = nil then Begin
				p := new DocObject();
				p.node_ := node;
				p.name_ := name;
			End;
			ps[ length(ps) ] := p;
		End;
		node := node.NextElement();
	End;
	return ps;
End;

Function getDocumentObject(parent, prefix, index);
Begin
	node := parent.FirstChildElement();
	cnt := 0;
	while ifObj(node) do Begin
		name := node.GetName();
		if length(prefix) = 0 or (ifstring(prefix) and name = prefix) or (istable(prefix) and (name in prefix)) then Begin
			if cnt then Begin //第index个对象
				p := _getDocObject(node, name);
				if ifObj(p) then Begin
					return p;
				End;
			End;
			cnt ++;
		End;
		node := node.NextElement();
	End;
	return nil;
End;

Function _text(r);
Begin
	txt := '';
	for i:= 0 to length(r)-1 do Begin
		if i and r[i]['pIndex'] > 0 and r[i]['pIndex'] <> r[i-1]['pIndex'] then 
			txt += '\n';
		if ifObj(r[i]['rNode']) then Begin
			run := new TRun(r[i]['rNode']);
			txt += run.Text();
		End;
	End;
	return txt;
End;

Function _getHanging(linesCnt, pPr);
Begin
	wth := pPr.LeftIndent + pPr.RightIndent;
	if linesCnt = 0 then Begin
		if pPr.Hanging then
			wth -= pPr.Hanging;
		else if pPr.FirstLineIndent then
			wth += pPr.FirstLineIndent;
	End;
//_dumpPpr(pPr);
//println('>>>>>行首，lines={}, wth={}', linesCnt, wth);
	return wth;
End;

Function _dumpPpr(pPr);
Begin
	if not ifObj(pPr) then
		return println('pPr is null');
	println('SpaceBefore={},SpaceAfter={},LineSpacing={},LineSpacingRule={},Left={},Right={},Hanging={},FirstLineIndent={}',
		pPr.SpaceBefore, pPr.SpaceAfter, pPr.LineSpacing,pPr.LineSpacingRule,pPr.LeftIndent,pPr.RightIndent,pPr.Hanging,pPr.FirstLineIndent);
End;

Function _dumpRpr(rPr);
Begin
	if not ifObj(rPr) then
		return println('rPr is null');
	println('sz={},szCs={},hint={},eastAsia={}',
		rPr.Size,rPr.szCs,rPr.rFont.hint,rPr.rFont.eastAsia);
End;

//文本前后是否包含空格
Function _preserve(str);
Begin
	if not ifstring(str) then return false;
	cnt := length(str);
	spaceArr := array(' ','	');
	if cnt and (str[1] in spaceArr or (cnt > 1 and str[cnt] in spaceArr)) then
		return true;
	return false;
End;

