--- a/trunk/json/json-pac/Functions/STRUCT_TO_JSON/svnobj
+++ b/trunk/json/json-pac/Functions/STRUCT_TO_JSON/svnobj
@@ -1,6 +1,6 @@
-Gx_l½F!0…jüo45i·©a•=ÆbSystem.StringL{6f9dac99-8de1-4efc-8465-68ac443b7d08}SpecialFuncL{0db3d7bb-cde0-4416-9a7b-ce49a0124323}NoneImplementationL{3b83b776-fb25-43b8-99f2-3c507c9143fc}TextDocument	L{f3878285-8e4f-490b-bb1b-9acbb7eb04db}
-TextLinesL{a5de0b0b-1cb5-4913-ac21-9d70293ec00d}Id
longTagTextÒ(*======================================================================================================= STRUCT_TO_JSON()VAuthor: Tim Van Meppelen, Pro Electric Inc.(timv@proelectric.com"Date: Nov 2, 2018lcreate a JSON string from a structure of JSONVAR typesÔ========================================================================================================*)”thisloopstarttime:= TIME();	//store the time of the beginning of this loop8Execute_TRIG(CLK:= Execute);0Abort_TRIG(CLK:= Abort);,IF Execute_TRIG.Q THENl//must see a rising edge on execute to start composing†	starttime:= TIME();	//store the time of the beginning of execution 	compose:= TRUE;	Busy:= TRUE; "	Aborted:= FALSE;!	Done:= FALSE;"	Error:= FALSE;#&	ErrorPosition:= 0;$(	bufferposition:= 1;%&	jsonvarindex:= 1;	&H	FOR i:= 1 TO GPL_JSON.MAX_LEVELS DO'(	//clear names array(*		names[i].Name:= '';)4		names[i].ArrayIndex:= 0;*	END_FOR+0	//clear previous string,	SysMemSet(-,		pDest:= JSONString, . 		udiValue:= 0, /6		udiCount:= JSONStringSize0	);1END_IF2(IF Abort_TRIG.Q THEN3	Busy:= FALSE;4 	Aborted:= TRUE;5"	compose:= FALSE;6´WHILE compose AND (jsonvarindex <= NumberOfVars) AND (bufferposition < JSONStringSize) DO 7D//loop through all local variables8`	objectstr:= '';	//clear previous object string	9¢	names:= JSONVars^[jsonvarindex].Names;	//helper variable for name array property:	;6	IF (jsonvarindex = 1) THEN<~		objectstr:= CONCAT(objectstr, '{');	//open JSON string with {= 		IF Format THEN>f			objectstr:= CONCAT(objectstr, GPL_JSON.NEWLINE);?		END_IF@
-	ELSEA‚		IF NOT (VariableArraySize AND (names[1].ArrayIndex > 0) AND (JSONVars^[jsonvarindex].ValueType = JSONVALUETYPE.json_null)) THENBĻ		//don't write the value if the current variable is an array, and the value is nullCˆ			objectstr:= CONCAT(objectstr, ',');	//comma in between each valueD`			IF Format AND (names[1].ArrayIndex <= 1) THENE`			//new line after each comma, except in arraysFj				objectstr:= CONCAT(objectstr, GPL_JSON.NEWLINE);	G			END_IF	H	END_IFIˆ	FOR namesindex:= JSONVars^[jsonvarindex].ParentVar-1 TO 1 BY -1 DO Jx	//start at the second highest variable level and count downK˜	//open new objects or arrays, and write a single name:value pair at level 1LÔ		//======================open new objects or arrays, or create new name:value pairs======================M˜		IF names[namesindex].NewArray AND (names[namesindex].ArrayIndex <= 1) THENN6		//new array at this levelOZ			CreateName(Name:= names[namesindex].Name);P$			CreateArray();	Q		END_IF	RĪ		IF (jsonvarindex <> 1) AND (namesindex > 1) AND names[namesindex].NewObject THENSz		//new object at this level, don't create objects at level 1TZ			IF (names[namesindex].ArrayIndex = 0) THENU~			//only create an object name if this is not part of an arrayV\				CreateName(Name:= names[namesindex].Name);W			END_IFX&			CreateObject();	Y		Z0		IF (namesindex=1) THEN[B		//only write a value at level 1\Z			IF (names[namesindex].ArrayIndex > 0) THEN]:			//array, create value only^†				IF NOT (VariableArraySize AND (names[1].ArrayIndex > 0) AND (JSONVars^[jsonvarindex].ValueType = JSONVALUETYPE.json_null)) THEN_Ž				//don't write the value if the current variable is an array, and the value is null`Þ					CreateValue(ValueType:= JSONVars^[jsonvarindex].ValueType, Value:= JSONVars^[jsonvarindex].AsString);					a				END_IFb			ELSEc(			//name:value pairdŌ				CreateValue(ValueType:= JSONVars^[jsonvarindex].ValueType, Value:= JSONVars^[jsonvarindex].AsString);e|	FOR namesindex:= 1 TO JSONVars^[jsonvarindex].ParentVar-1 DO fR	//start at the lowest level and count upg˜	//close objects or arrays if this is the last value in this object or arrayhJ		IF names[namesindex].EndObject THENi„		//close object at this level, unless it's the last object in thej"			CloseObject();kJ		IF names[namesindex].EndArray THEN	l:		//close array at this levelm"			CloseArray();	n	END_FOR	oˆ	//concatenate the temporary object string to the JSON string outputp	StrConcatA(q8		pstFrom:= ADR(objectstr), rX		pstTo:= ADR(JSONString^[bufferposition]), sX		iBufferSize:= UDINT_TO_INT(JSONStringSize)t	);	u‚	bufferposition:= bufferposition + DINT_TO_UDINT(LEN(objectstr));vN	IF (jsonvarindex >= NumberOfVars) THENw8	//end of vars, close stringx$		compose:= FALSE;y		Busy:= FALSE;z 		Done:= TRUE;		{F		ComposeTime:= TIME() - starttime;| 		//JSONString^[bufferposition]:= ASCII.CLOSE_BRACE;;	//close JSON object with }}”		JSONString^[bufferposition]:= ASCII.NULL;	//null character to end string~ˆ	IF TIME() >= (thisloopstarttime + GPL_JSON.MAX_EXECUTION_TIME) THENŽ	//this function block won't take up more than GPL_JSON.MAX_EXECUTION_TIME on one scan€Ę	//very long strings could take too long to compose in one task cycle, and cause a watchdog exception		RETURN;‚D	jsonvarindex:= jsonvarindex + 1;	ƒEND_WHILE„Interface…L{a9ed5b7e-75c5-4651-af16-d2c27e98cb94}†:FUNCTION_BLOCK STRUCT_TO_JSON‡VAR_INPUTˆ€	Execute:			BOOL;		//rising edge triggers compose of JSON string‰z	Abort:				BOOL;		//rising edge stops composing a JSON stringŠú	{attribute 'displaymode':='hex'}JSONString:		POINTER TO ARRAY[1..GPL_JSON.MAX_JSON_STRING] OF BYTE;	//pointer to JSON string‹T	JSONStringSize:		UDINT;		//size of stringŒč	JSONVars:			POINTER TO ARRAY[1..GPL_JSON.MAX_VARS] OF JSONVAR;	//pointer to local structure made up of type JSONVAR˜	NumberOfVars:		UINT;		//number of variables in the local structure or arrayŽÎ	VariableArraySize:	BOOL;		//don't write array values which are null, resulting in variable array sizes”	Format:				BOOL;		//add white space and indenting to the resulting stringEND_VAR‘VAR_OUTPUT’T	Busy:				BOOL;		//busy composing a string“	Done:				BOOL;		//successfully composed the whole string with no errors”f	Aborted:			BOOL;		//compose aborted by Abort input•Ē	Error:				BOOL;		//unexpected character detected, string not completely composed––	ErrorPosition:		UDINT;		//index of local object at which composing stopped—t	ComposeTime:		TIME;		//time it took to compose the string˜VAR™r	bufferposition:		UDINT;	//current position in the stringš,	jsonvarindex:		UDINT;›$	compose:			BOOL;	œ~	objectstr:			STRING(255);	//string created by current variableÆ	names:				ARRAY[1..GPL_JSON.MAX_LEVELS] OF JSONVARNAME;	//helper variable for names array propertyž&	namesindex:			INT;Ÿ	i:					UINT; .	Execute_TRIG:		R_TRIG;Ą,	Abort_TRIG:			R_TRIG;Ēt	thisloopstarttime:	TIME;		//time the current loop startedĢZ	starttime:			TIME;		//time composing startedĪ"UniqueIdGeneratorĨ1194ĶPOULevel§L{8e575c5b-1d37-49c6-941b-5c0ec7874787}ĻStandardĐ ChildObjectGuidsŠ8System.Collections.ArrayListŦ,AddAttributeSubsequentŽboolÐÐ-ÐÐ	E
-ÐÐ
­%ÚÐ-ÐÐ
­&ÚÐ-ÐÐ
­'ÚÐ-ÐÐ
­(ÚÐ-ÐÐ
­)ÚÐ-ÐÐ
­*ÚÐ-ÐÐ
­2ÚÐ-ÐÐ
­ÝÚÐ-ÐÐ
­ÞÚÐ-ÐÐ
­ØÚÐ-ÐÐ
­ÙÚÐ-ÐÐ
­ÚÚÐ-ÐÐ
­ÛÚÐ-ÐÐ
­ÜÚÐ-ÐÐ
­ÝÚÐ-ÐÐ
­ÞÚÐ-ÐÐ
­ßÚÐ-ÐÐ
­áÚÐ-ÐÐ
­âÚÐ- ÐÐ
­ãÚÐ-!ÐÐ
­äÚÐ-"ÐÐ
­ÚÐ-#ÐÐ
­ÚÐ-$ÐÐ
­ÚÐ-%ÐÐ
­KÚÐ-&ÐÐ
­@ÚÐ-'ÐÐ
­ØÚÐ-(ÐÐ
­MÚÐ-)ÐÐ
­—ÚÐ-*ÐÐ
­’ÚÐ-+ÐÐ
­“ÚÐ-,ÐÐ
­”ÚÐ--ÐÐ
­•ÚÐ-.ÐÐ
­–ÚÐ-/ÐÐ
­5ÚÐ-0ÐÐ
­íÚÐ-1ÐÐ
­îÚÐ-ÐÐ
­ïÚÐ-2ÐÐ
­ðÚÐ-3ÐÐ
­ñÚÐ-4ÐÐ
­òÚÐ-5ÐÐ
­óÚÐ-1ÐÐ
­3ÚÐ-ÐÐ
­5ÚÐ-ÐÐ
­ûÚÐ-ÐÐ
­6ÚÐ-6ÐÐ
­ÛÚÐ-7ÐÐ
­æÚÐ-8ÐÐ
­öÚÐ-9ÐÐ
­ÚÐ-:ÐÐ
­ÚÐ-;ÐÐ
­rÚÐ-<ÐÐ
­sÚÐ-=ÐÐ
­tÚÐ->ÐÐ
­ÚÐ-?ÐÐ
­™ÚÐ-@ÐÐ
­©ÚÐ-AÐÐ
­ŸÚÐ-BÐÐ
­ ÚÐ-CÐÐ
­¡ÚÐ-DÐÐ
­¢ÚÐ-EÐÐ
­£ÚÐ-FÐÐ
­›ÚÐ-GÐÐ
­kÚÐ-?ÐÐ
­ÚÐ-ÐÐ
­4ÚÐ-HÐÐ
­IÚÐ-ÐÐ
­”ÚÐ-IÐÐ
­"ÚÐ-JÐÐ
­LÚÐ-KÐÐ
­OÚÐ-LÐÐ
­TÚÐ-MÐÐ
­]ÚÐ-NÐÐ
­_ÚÐ-OÐÐ
­VÚÐ-PÐÐ
­bÚÐ-QÐÐ
­ÚÐ-ÐÐ
­dÚÐ-RÐÐ
­eÚÐ-SÐÐ
­gÚÐ-TÐÐ
­aÚÐ-UÐÐ
­fÚÐ-VÐÐ
­`ÚÐ-WÐÐ
­
-ÚÐ-XÐÐ
­ÚÐ-?ÐÐ
­qÚÐ-YÐÐ
­äÚÐ-ZÐÐ
­ÚÐ-[ÐÐ
­ÀÚÐ-\ÐÐ
­˜ÚÐ-]ÐÐ
­¤ÚÐ-^ÐÐ
­¥ÚÐ-_ÐÐ
­¦ÚÐ-`ÐÐ
­ÆÚÐ-aÐÐ
­ÁÚÐ-bÐÐ
­³ÚÐ-cÐÐ
­´ÚÐ-VÐÐ
­±ÚÐ-dÐÐ
­|ÚÐ-WÐÐ
­àÚÐ-?ÐÐ
­EÚÐ-*ÐÐ
­FÚÐ-:ÐÐ
­GÚÐ-eÐÐ
­HÚÐ-fÐÐ
­RÚÐ-gÐÐ
­;ÚÐ-hÐÐ
­<ÚÐ-iÐÐ
­=ÚÐ-jÐÐ
­>ÚÐ-?ÐÐ
­?ÚÐ-ÐÐ
­@ÚÐ-kÐÐ
­AÚÐ-lÐÐ
­BÚÐ-mÐÐ
­CÚÐ-QÐÐ
­DÚÐ-nÐÐ
­¸ÚÐ-:ÐÐ
­¹ÚÐ-oÐÐ
­ºÚÐ-pÐÐ
­»ÚÐ-qÐÐ
­‘ÚÐ-rÐÐ
­¼ÚÐ-sÐÐ
­9ÚÐ-tÐÐ
­OÚÐ-:ÐÐ
­@ÚÐ-uÐÐ
­ýÚÐ-ÐÐ
­ˆÚÐ-vÐÐ
­ŠÚÐ-wÐÐ
­‹ÚÐ-xÐÐ
­ŒÚÐ-yÐÐ
­‰ÚÐ-zÐÐ
­?ÚÐ-{ÐÐ
­ªÚÐ-|ÐÐ
­‡ÚÐ-}ÐÐ
­ÚÐ-HÐÐ
­þÚÐ-:ÐÐ
­ÿÚÐ-~ÐÐ
­ÚÐ-ÐÐ
­ÚÐ-€ÐÐ
­ÚÐ-ÐÐ
­ÚÐ-HÐÐ
­ÚÐ-:ÐÐ
­ÚÐ-‚ÐÐ
­{ÚÐ-ƒÐÐ
­	ÚÐ-Є…Ð	E
-%ÐÐ
­ÆÚÐ-†ÐÐ
­ÈÚÐ-‡ÐÐ
­ÉÚÐ-ˆÐÐ
­ÊÚÐ-‰ÐÐ
­+ÚÐ-ŠÐÐ
­ËÚÐ-‹ÐÐ
­ÌÚÐ-ŒÐÐ
­ÚÐ-ÐÐ
­ùÚÐ-ŽÐÐ
­ÍÚÐ-ÐÐ
­ÇÚÐ-ÐÐ
­ÚÐ-ÐÐ
­ÎÚÐ-‘ÐÐ
­ÏÚÐ-’ÐÐ
­ÐÚÐ-“ÐÐ
­ÑÚÐ-”ÐÐ
­ÒÚÐ-•ÐÐ
­<ÚÐ-–ÐÐ
­ÓÚÐ-—ÐÐ
­ÕÚÐ-ÐÐ
­ÚÐ-ÐÐ
­ÚÐ-˜ÐÐ
­iÚÐ-™ÐÐ
­ÚÐ-šÐÐ
­hÚÐ-›ÐÐ
­ÚÐ-œÐÐ
­ÚÐ-ÐÐ
­nÚÐ-žÐÐ
­ÚÐ-ŸÐÐ
­ÖÚÐ-:ÐÐ
­×ÚÐ- ÐÐ
­ùÚÐ-¡ÐÐ
­úÚÐ-¢ÐÐ
­üÚÐ-£ÐÐ
­nÚÐ-ÐÐ
­ÚÐ-ÐÐ
­ÚÐ-Ф-¥Ц§-¨©ªЫ¬­
\ No newline at end of file
+Gx_l—^!0…jüoºG6k÷µ&Ò’System.StringL{6f9dac99-8de1-4efc-8465-68ac443b7d08}SpecialFuncL{0db3d7bb-cde0-4416-9a7b-ce49a0124323}NoneImplementationL{3b83b776-fb25-43b8-99f2-3c507c9143fc}TextDocument	L{f3878285-8e4f-490b-bb1b-9acbb7eb04db}
+TextLinesL{a5de0b0b-1cb5-4913-ac21-9d70293ec00d}Id
longTagTextÒ(*======================================================================================================= STRUCT_TO_JSON()VAuthor: Tim Van Meppelen, Pro Electric Inc.(timv@proelectric.comzwith contributions from Stefan Dreyer github.com/stefandreyer"Date: Nov 2, 2018lcreate a JSON string from a structure of JSONVAR typesÔ========================================================================================================*)”thisloopstarttime:= TIME();	//store the time of the beginning of this loop8Execute_TRIG(CLK:= Execute);0Abort_TRIG(CLK:= Abort);,IF Execute_TRIG.Q THENl//must see a rising edge on execute to start composing†	starttime:= TIME();	//store the time of the beginning of execution 	compose:= TRUE; 	Busy:= TRUE;!"	Aborted:= FALSE;"	Done:= FALSE;#	Error:= FALSE;$&	ErrorPosition:= 0;%(	bufferposition:= 1;&&	jsonvarindex:= 1;	'H	FOR i:= 1 TO GPL_JSON.MAX_LEVELS DO((	//clear names array)*		names[i].Name:= '';*4		names[i].ArrayIndex:= 0;+	END_FOR,0	//clear previous string-	SysMemSet(.,		pDest:= JSONString, / 		udiValue:= 0, 06		udiCount:= JSONStringSize1	);2END_IF3(IF Abort_TRIG.Q THEN4	Busy:= FALSE;5 	Aborted:= TRUE;6"	compose:= FALSE;7´WHILE compose AND (jsonvarindex <= NumberOfVars) AND (bufferposition < JSONStringSize) DO 8D//loop through all local variables96	IF (jsonvarindex = 1) THEN:P	//set characteristics of first variable;ž	//characteristics of the first variable are not always set properly by FB_Init<		FOR varlevelindex:= 1 TO JSONVars^[jsonvarindex].ApplicationLevel-2 DO=¢		//every level of the first variable could be either a new object or a new array>ž			IF (JSONVars^[jsonvarindex].VarNameArray[varlevelindex].ArrayIndex = 1) THEN?P			//new array at the first array object@’				JSONVars^[jsonvarindex].VarNameArray[varlevelindex].NewArray:= TRUE;	An			ELSIF (varlevelindex > 1) OR (NumberofVars = 1) THENB‚			//new object at every level, special case for single variablesC’				JSONVars^[jsonvarindex].VarNameArray[varlevelindex].NewObject:= TRUE;D			END_IF			E		END_FORF	END_IFGL	IF (jsonvarindex = NumberOfVars) THENHN	//set characteristics of last variableIœ	//characteristics of the last variable are not always set properly by FB_InitJJ		//close all open arrays and objectsKž			IF (JSONVars^[jsonvarindex].VarNameArray[varlevelindex].ArrayIndex > 0) THENLN			//end array if an array index existsM’				JSONVars^[jsonvarindex].VarNameArray[varlevelindex].EndArray:= TRUE;	Nn			//end all objects, special case for single variablesO’				JSONVars^[jsonvarindex].VarNameArray[varlevelindex].EndObject:= TRUE;PH		objectstr:= '{';	//new JSON stringQ
+	ELSERb		objectstr:= '';	//clear previous object string	S	T¢	names:= JSONVars^[jsonvarindex].Names;	//helper variable for name array propertyU2	//first object, no commaV 		IF Format THENWf			objectstr:= CONCAT(objectstr, GPL_JSON.NEWLINE);X		END_IFYP	//add a comma between objects or arraysZ‚		IF NOT (VariableArraySize AND (names[1].ArrayIndex > 0) AND (JSONVars^[jsonvarindex].ValueType = JSONVALUETYPE.json_null)) THEN[¨		//don't write the value if the current variable is an array, and the value is null\ˆ			objectstr:= CONCAT(objectstr, ',');	//comma in between each value]`			IF Format AND (names[1].ArrayIndex <= 1) THEN^`			//new line after each comma, except in arrays_j				objectstr:= CONCAT(objectstr, GPL_JSON.NEWLINE);	`			END_IF	a.	IF (MaxLevel = 0) THENbl	//default, create all objects below the program levelc~		maxlevelindex:= JSONVars^[jsonvarindex].ApplicationLevel - 2;dV	//manually defined with the MaxLevel inpute6		maxlevelindex:= MaxLevel;f\	FOR namesindex:= maxlevelindex TO 1 BY -1 DO gN	//loop through all levels of an objecthÔ		//======================open new objects or arrays, or create new name:value pairs======================i˜		IF names[namesindex].NewArray AND (names[namesindex].ArrayIndex <= 1) THENj6		//new array at this levelkZ			CreateName(Name:= names[namesindex].Name);l$			CreateArray();	m|		ELSIF names[namesindex].NewObject AND (namesindex <> 1) THENn8		//new object at this levelo\			CreateName(Name:= names[namesindex].Name);	p(			CreateObject();		q		r0		IF (namesindex=1) THENsB		//only write a value at level 1tZ			IF (names[namesindex].ArrayIndex > 0) THENu:			//array, create value onlyv†				IF NOT (VariableArraySize AND (names[1].ArrayIndex > 0) AND (JSONVars^[jsonvarindex].ValueType = JSONVALUETYPE.json_null)) THENw¬				//don't write the value if the current variable is an array, and the value is nullxÞ					CreateValue(ValueType:= JSONVars^[jsonvarindex].ValueType, Value:= JSONVars^[jsonvarindex].AsString);					y				END_IFz			ELSE{(			//name:value pair|\				CreateName(Name:= names[namesindex].Name);}Ò				CreateValue(ValueType:= JSONVars^[jsonvarindex].ValueType, Value:= JSONVars^[jsonvarindex].AsString);~			END_IFP	FOR namesindex:= 1 TO maxlevelindex DO €R	//start at the lowest level and count up˜	//close objects or arrays if this is the last value in this object or array‚J		IF names[namesindex].EndArray THEN	ƒ:		//close array at this level„"			CloseArray();	…		END_IF		†v		IF names[namesindex].EndObject AND (namesindex <> 1) THEN‡<		//close object at this levelˆ"			CloseObject();‰	END_FOR	Šˆ	//concatenate the temporary object string to the JSON string output‹	StrConcatA(Œ8		pstFrom:= ADR(objectstr), X		pstTo:= ADR(JSONString^[bufferposition]), ŽX		iBufferSize:= UDINT_TO_INT(JSONStringSize)	);	‚	bufferposition:= bufferposition + DINT_TO_UDINT(LEN(objectstr));‘N	IF (jsonvarindex >= NumberOfVars) THEN’8	//end of vars, close string“$		compose:= FALSE;”		Busy:= FALSE;• 		Done:= TRUE;		–F		ComposeTime:= TIME() - starttime;—œ		JSONString^[bufferposition]:= ASCII.CLOSE_BRACE;;	//close JSON object with }˜L		bufferposition:= bufferposition + 1;™”		JSONString^[bufferposition]:= ASCII.NULL;	//null character to end stringšˆ	IF TIME() >= (thisloopstarttime + GPL_JSON.MAX_EXECUTION_TIME) THEN›¬	//this function block won't take up more than GPL_JSON.MAX_EXECUTION_TIME on one scanœÊ	//very long strings could take too long to compose in one task cycle, and cause a watchdog exception		RETURN;žD	jsonvarindex:= jsonvarindex + 1;	ŸEND_WHILE Interface¡L{a9ed5b7e-75c5-4651-af16-d2c27e98cb94}¢:FUNCTION_BLOCK STRUCT_TO_JSON£VAR_INPUT¤€	Execute:			BOOL;		//rising edge triggers compose of JSON string¥z	Abort:				BOOL;		//rising edge stops composing a JSON string¦ú	{attribute 'displaymode':='hex'}JSONString:		POINTER TO ARRAY[1..GPL_JSON.MAX_JSON_STRING] OF BYTE;	//pointer to JSON string§T	JSONStringSize:		UDINT;		//size of string¨è	JSONVars:			POINTER TO ARRAY[1..GPL_JSON.MAX_VARS] OF JSONVAR;	//pointer to local structure made up of type JSONVAR©˜	NumberOfVars:		UINT;		//number of variables in the local structure or arrayªÎ	VariableArraySize:	BOOL;		//don't write array values which are null, resulting in variable array sizes«”	Format:				BOOL;		//add white space and indenting to the resulting string¬r	MaxLevel:			INT;		//max level at which to create objects­°	(*by default, STRUCT_TO_JSON will create variables starting at (Application level - 2).®²	This will work for most variables and structures defined in a program.  If your variable¯°	or structure is contained inside a function block, or nested in function blocks, it may°š	be necessary to set MaxLevel to restrict creating JSON after a certain level±&	MaxLevel examples:²f	Device: 4, Application: 3, Program: 2, Variable: 1³~	Device.Application.TestJSON_PRG.var1, default {"var1":"value"}´¸	Device.Application.TestJSON_PRG.var1, set MaxLevel=2 to get {TestJSON_PRG:{"var1":"value"}}µŒ	Device: 5, Application: 4, Program: 3, Function Block: 2, Variable: 1¶ª	Device.Application.TestJSON_PRG.Test_FB.var1, set MaxLevel=1 to get {"var1":"value"}·¾	Device.Application.TestJSON_PRG.Test_FB.var1, set MaxLevel=2 to get {Test_FB:{"var1":"value"}}¸Þ	Device.Application.TestJSON_PRG.Test_FB.var1, set MaxLevel=3 to get {TestJSON_PRG:{Test_FB:{"var1":"value"}}} ¹	*)ºEND_VAR»VAR_OUTPUT¼T	Busy:				BOOL;		//busy composing a string½	Done:				BOOL;		//successfully composed the whole string with no errors¾f	Aborted:			BOOL;		//compose aborted by Abort input¿¢	Error:				BOOL;		//unexpected character detected, string not completely composedÀ–	ErrorPosition:		UDINT;		//index of local object at which composing stoppedÁt	ComposeTime:		TIME;		//time it took to compose the stringÂVARÃr	bufferposition:		UDINT;	//current position in the stringÄ,	jsonvarindex:		UDINT;Å$	compose:			BOOL;	Æ~	objectstr:			STRING(255);	//string created by current variableÇÆ	names:				ARRAY[1..GPL_JSON.MAX_LEVELS] OF JSONVARNAME;	//helper variable for names array propertyÈ&	namesindex:			INT;É	i:					UINT;Ê.	Execute_TRIG:		R_TRIG;Ë,	Abort_TRIG:			R_TRIG;Ìt	thisloopstarttime:	TIME;		//time the current loop startedÍZ	starttime:			TIME;		//time composing startedÎ*	varlevelindex:		INT;Ï*	maxlevelindex:		INT;Ð"UniqueIdGeneratorÑ1334ÒPOULevelÓL{8e575c5b-1d37-49c6-941b-5c0ec7874787}ÔStandardÕ ChildObjectGuidsÖ8System.Collections.ArrayList×,AddAttributeSubsequentØboolÐÐ-ÐÐ	E
+¶ÐÐ
­%ÚÐ-ÐÐ
­&ÚÐ-ÐÐ
­'ÚÐ-ÐÐ
­(ÚÐ-ÐÐ
­6ÚÐ-ÐÐ
­)ÚÐ-ÐÐ
­*ÚÐ-ÐÐ
­2ÚÐ-ÐÐ
­ÝÚÐ-ÐÐ
­ÞÚÐ-ÐÐ
­ØÚÐ-ÐÐ
­ÙÚÐ-ÐÐ
­ÚÚÐ-ÐÐ
­ÛÚÐ-ÐÐ
­ÜÚÐ-ÐÐ
­ÝÚÐ-ÐÐ
­ÞÚÐ-ÐÐ
­ßÚÐ-ÐÐ
­áÚÐ- ÐÐ
­âÚÐ-!ÐÐ
­ãÚÐ-"ÐÐ
­äÚÐ-#ÐÐ
­ÚÐ-$ÐÐ
­ÚÐ-%ÐÐ
­ÚÐ-&ÐÐ
­KÚÐ-'ÐÐ
­@ÚÐ-(ÐÐ
­ØÚÐ-)ÐÐ
­MÚÐ-*ÐÐ
­—ÚÐ-+ÐÐ
­’ÚÐ-,ÐÐ
­“ÚÐ--ÐÐ
­”ÚÐ-.ÐÐ
­•ÚÐ-/ÐÐ
­–ÚÐ-0ÐÐ
­5ÚÐ-1ÐÐ
­íÚÐ-2ÐÐ
­îÚÐ-ÐÐ
­ïÚÐ-3ÐÐ
­ðÚÐ-4ÐÐ
­ñÚÐ-5ÐÐ
­òÚÐ-6ÐÐ
­óÚÐ-2ÐÐ
­ûÚÐ-ÐÐ
­6ÚÐ-7ÐÐ
­ÛÚÐ-8ÐÐ
­ÒÚÐ-ÐÐ
­ÖÚÐ-9ÐÐ
­ÛÚÐ-:ÐÐ
­àÚÐ-;ÐÐ
­èÚÐ-<ÐÐ
­éÚÐ-=ÐÐ
­êÚÐ->ÐÐ
­ëÚÐ-?ÐÐ
­ìÚÐ-@ÐÐ
­íÚÐ-AÐÐ
­îÚÐ-BÐÐ
­ïÚÐ-CÐÐ
­ðÚÐ-DÐÐ
­âÚÐ-EÐÐ
­ÜÚÐ-FÐÐ
­ÕÚÐ-ÐÐ
­ÝÚÐ-GÐÐ
­äÚÐ-HÐÐ
­ÞÚÐ-IÐÐ
­õÚÐ-<ÐÐ
­öÚÐ-JÐÐ
­øÚÐ-KÐÐ
­ùÚÐ-LÐÐ
­úÚÐ-MÐÐ
­ûÚÐ-AÐÐ
­üÚÐ-NÐÐ
­ýÚÐ-OÐÐ
­þÚÐ-DÐÐ
­æÚÐ-EÐÐ
­ßÚÐ-FÐÐ
­ÑÚÐ-9ÐÐ
­-ÚÐ-PÐÐ
­/ÚÐ-QÐÐ
­0ÚÐ-RÐÐ
­.ÚÐ-FÐÐ
­æÚÐ-SÐÐ
­öÚÐ-TÐÐ
­µÚÐ-ÐÐ
­ÚÐ-9ÐÐ
­´ÚÐ-UÐÐ
­sÚÐ-VÐÐ
­tÚÐ-WÐÐ
­ÚÐ-XÐÐ
­™ÚÐ-QÐÐ
­ºÚÐ-YÐÐ
­©ÚÐ-ZÐÐ
­ŸÚÐ-[ÐÐ
­ ÚÐ-\ÐÐ
­¡ÚÐ-]ÐÐ
­¢ÚÐ-^ÐÐ
­£ÚÐ-_ÐÐ
­›ÚÐ-`ÐÐ
­kÚÐ-XÐÐ
­ÚÐ-ÐÐ
­4ÚÐ-FÐÐ
­ÚÐ-ÐÐ
­IÚÐ-aÐÐ
­ÚÐ-bÐÐ
­ÚÐ-cÐÐ
­ÚÐ-QÐÐ
­ÚÐ-dÐÐ
­ÚÐ-eÐÐ
­ÚÐ-FÐÐ
­ÚÐ-SÐÐ
­”ÚÐ-fÐÐ
­LÚÐ-gÐÐ
­OÚÐ-hÐÐ
­TÚÐ-iÐÐ
­]ÚÐ-jÐÐ
­_ÚÐ-kÐÐ
­VÚÐ-lÐÐ
­²ÚÐ-mÐÐ
­eÚÐ-nÐÐ
­(ÚÐ-oÐÐ
­3ÚÐ-pÐÐ
­ÚÐ-XÐÐ
­qÚÐ-qÐÐ
­äÚÐ-rÐÐ
­ÚÐ-sÐÐ
­ÀÚÐ-tÐÐ
­˜ÚÐ-uÐÐ
­¤ÚÐ-vÐÐ
­¥ÚÐ-wÐÐ
­¦ÚÐ-xÐÐ
­ÆÚÐ-yÐÐ
­ÁÚÐ-zÐÐ
­³ÚÐ-{ÐÐ
­´ÚÐ-|ÐÐ
­±ÚÐ-}ÐÐ
­|ÚÐ-~ÐÐ
­àÚÐ-XÐÐ
­EÚÐ-+ÐÐ
­FÚÐ-SÐÐ
­ÚÐ-ÐÐ
­HÚÐ-€ÐÐ
­RÚÐ-ÐÐ
­®ÚÐ-‚ÐÐ
­¯ÚÐ-ƒÐÐ
­°ÚÐ-„ÐÐ
­­ÚÐ-…ÐÐ
­±ÚÐ-qÐÐ
­;ÚÐ-†ÐÐ
­<ÚÐ-‡ÐÐ
­=ÚÐ-ˆÐÐ
­>ÚÐ-XÐÐ
­DÚÐ-‰ÐÐ
­¸ÚÐ-SÐÐ
­¹ÚÐ-ŠÐÐ
­ºÚÐ-‹ÐÐ
­»ÚÐ-ŒÐÐ
­‘ÚÐ-ÐÐ
­¼ÚÐ-ŽÐÐ
­9ÚÐ-ÐÐ
­OÚÐ-SÐÐ
­@ÚÐ-ÐÐ
­ýÚÐ-ÐÐ
­ˆÚÐ-‘ÐÐ
­ŠÚÐ-’ÐÐ
­‹ÚÐ-“ÐÐ
­ŒÚÐ-”ÐÐ
­‰ÚÐ-•ÐÐ
­?ÚÐ-–ÐÐ
­ªÚÐ-—ÐÐ
­,ÚÐ-˜ÐÐ
­‡ÚÐ-™ÐÐ
­ÚÐ-FÐÐ
­þÚÐ-SÐÐ
­ÿÚÐ-šÐÐ
­ÚÐ-›ÐÐ
­ÚÐ-œÐÐ
­ÚÐ-ÐÐ
­ÚÐ-FÐÐ
­ÚÐ-SÐÐ
­ÚÐ-žÐÐ
­{ÚÐ-ŸÐÐ
­	ÚÐ-Р¡Ð	E
+6ÐÐ
­ÆÚÐ-¢ÐÐ
­ÈÚÐ-£ÐÐ
­ÉÚÐ-¤ÐÐ
­ÊÚÐ-¥ÐÐ
­+ÚÐ-¦ÐÐ
­ËÚÐ-§ÐÐ
­ÌÚÐ-¨ÐÐ
­ÚÐ-©ÐÐ
­ùÚÐ-ªÐÐ
­ÍÚÐ-«ÐÐ
­¼ÚÐ-¬ÐÐ
­ÚÐ-­ÐÐ
­"ÚÐ-®ÐÐ
­#ÚÐ-¯ÐÐ
­$ÚÐ-°ÐÐ
­ÚÐ-±ÐÐ
­ÚÐ-²ÐÐ
­ÚÐ-³ÐÐ
­%ÚÐ-´ÐÐ
­&ÚÐ-SÐÐ
­	ÚÐ-µÐÐ
­
+ÚÐ-¶ÐÐ
­ÚÐ-·ÐÐ
­*ÚÐ-¸ÐÐ
­+ÚÐ-¹ÐÐ
­ÇÚÐ-ºÐÐ
­ÚÐ-ÐÐ
­ÎÚÐ-»ÐÐ
­ÏÚÐ-¼ÐÐ
­ÐÚÐ-½ÐÐ
­ÑÚÐ-¾ÐÐ
­ÒÚÐ-¿ÐÐ
­<ÚÐ-ÀÐÐ
­ÓÚÐ-ÁÐÐ
­ÕÚÐ-ºÐÐ
­ÚÐ-ÐÐ
­ÚÐ-ÂÐÐ
­iÚÐ-ÃÐÐ
­ÚÐ-ÄÐÐ
­hÚÐ-ÅÐÐ
­ÚÐ-ÆÐÐ
­ÚÐ-ÇÐÐ
­nÚÐ-ÈÐÐ
­ÚÐ-ÉÐÐ
­ÖÚÐ-SÐÐ
­×ÚÐ-ÊÐÐ
­ùÚÐ-ËÐÐ
­úÚÐ-ÌÐÐ
­üÚÐ-ÍÐÐ
­ñÚÐ-ÎÐÐ
­ÚÐ-ÏÐÐ
­nÚÐ-ºÐÐ
­ÚÐ-ÐÐ
­ÚÐ-ÐÐ-ÑÐÒÓ-ÔÕÖÐ×Ø­
\ No newline at end of file