Subversion Repositories Kolibri OS

Rev

Rev 5519 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5519 Rev 5678
1
dword bufpointer;
1
dword bufpointer;
2
dword o_bufpointer;
2
dword o_bufpointer;
3
dword bufsize;
3
dword bufsize;
4
 
4
 
5
char URL[10000];
5
char URL[10000];
6
 
6
 
7
scroll_bar scroll_wv = { 15,200,398,44,0,2,115,15,0,0xeeeeee,0xBBBbbb,0xeeeeee,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1};
7
scroll_bar scroll_wv = { 15,200,398,44,0,2,115,15,0,0xeeeeee,0xBBBbbb,0xeeeeee,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1};
8
 
8
 
9
char header[2048];
9
char header[2048];
10
 
10
 
11
struct TWebBrowser {
11
struct TWebBrowser {
12
	llist list;
12
	llist list;
13
	dword draw_line_height, draw_line_width, draw_list_height;
13
	dword draw_line_width;
14
	DrawBufer DrawBuf;
14
	DrawBufer DrawBuf;
15
	void Prepare();
15
	void Prepare();
16
	void Parse();
16
	void Parse();
17
	void SetTextStyle();
17
	void SetTextStyle();
18
	void DrawPage();
18
	void DrawPage();
19
	void DrawScroller();
19
	void DrawScroller();
20
	void NewLine();
20
	void NewLine();
21
	void Perenos();
21
	void Perenos();
22
	byte end_parsing;
22
	byte end_parsing;
23
} WB1;
23
} WB1;
24
 
24
 
25
byte b_text, i_text, u_text, s_text, pre_text, blq_text, li_text, li_tab, 
25
byte b_text, i_text, u_text, s_text, pre_text, blq_text, li_text, li_tab, 
26
	link, ignor_text, cur_encoding, text_align, t_html, t_body;
26
	link, ignor_text, cur_encoding, text_align, t_html, t_body;
27
byte condition_text_active, condition_text_val, condition_href, condition_max;
27
byte condition_text_active, condition_text_val, condition_href, condition_max;
28
 
28
 
29
enum { _WIN, _DOS, _KOI, _UTF, _DEFAULT };
29
enum { _WIN, _DOS, _KOI, _UTF, _DEFAULT };
30
 
30
 
31
enum { ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT};
31
enum { ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT};
32
 
32
 
33
dword text_colors[300];
33
dword text_colors[300];
34
dword text_color_index;
34
dword text_color_index;
35
dword link_color_inactive;
35
dword link_color_inactive;
36
dword link_color_active;
36
dword link_color_active;
37
dword bg_color;
37
dword bg_color;
38
 
38
 
39
int stroka;
39
int stroka;
40
int stolbec;
40
int stolbec;
41
int tab_len;
41
int tab_len;
42
int anchor_line_num;
42
int anchor_line_num;
43
 
43
 
44
char line[500];
44
char line[500];
45
char tag[100];
45
char tag[100];
46
char tagparam[10000];
46
char tagparam[10000];
47
char parametr[1200];
47
char parametr[1200];
48
char options[4096];
48
char options[4096];
49
char anchor[256];
49
char anchor[256];
50
 
50
 
51
#include "..\TWB\history.h"
51
#include "..\TWB\history.h"
52
#include "..\TWB\links.h"
52
#include "..\TWB\links.h"
53
#include "..\TWB\colors.h"
53
#include "..\TWB\colors.h"
54
#include "..\TWB\unicode_tags.h"
54
#include "..\TWB\unicode_tags.h"
55
#include "..\TWB\img_cache.h"
55
#include "..\TWB\img_cache.h"
56
#include "..\TWB\parce_tag.h"
56
#include "..\TWB\parce_tag.h"
57
#include "..\TWB\table.h"
57
#include "..\TWB\table.h"
58
 
58
 
59
 
59
 
60
//=======================================================================
60
//=======================================================================
61
 
61
 
62
 
62
 
63
void TWebBrowser::DrawPage()
63
void TWebBrowser::DrawPage()
64
{
64
{
65
	int start_x, start_y, zstart_x, zstart_y, line_length, zline_length, stolbec_len, magrin_left=5;
65
	int start_x, start_y, line_length, stolbec_len, magrin_left=5;
-
 
66
	dword font_type;
66
	
67
	
67
	if (!header)
68
	if (!header)
68
	{
69
	{
69
		strcpy(#header, #line);
70
		strcpy(#header, #line);
70
		strcat(#header, " -");
71
		strcat(#header, " -");
71
		strcat(#header, #version);
72
		strcat(#header, #version);
72
		line = 0;
73
		line = 0;
73
		return;
74
		return;
74
	}
75
	}
75
	if (t_html) && (!t_body) return;
76
	if (t_html) && (!t_body) return;
76
	
77
	
77
	if (stroka >= 0) && (stroka - 2 < list.visible) && (line) && (!anchor)
78
	if (stroka >= 0) && (stroka - 2 < list.visible) && (line) && (!anchor)
78
	{
79
	{
79
		start_x = stolbec * 6 + list.x + magrin_left;
-
 
80
		start_y = stroka * list.line_h + list.y + magrin_left;
-
 
81
		zstart_x = stolbec * 6 + magrin_left * DrawBuf.zoomf + list.x;
80
		start_x = stolbec * 6 + magrin_left * DrawBuf.zoom + list.x;
82
		zstart_y = stroka * list.line_h * DrawBuf.zoomf + magrin_left + list.y;
81
		start_y = stroka * list.line_h + magrin_left + list.y;
83
		stolbec_len = strlen(#line);
82
		stolbec_len = strlen(#line);
84
		line_length = stolbec_len * 6;
-
 
85
		zline_length = stolbec_len * 6 * DrawBuf.zoomf;
83
		line_length = stolbec_len * 6 * DrawBuf.zoom;
-
 
84
 
-
 
85
		if (DrawBuf.zoom==1) font_type = 0x88; else font_type = 0x89;
86
 
86
 
87
		WriteBufText(start_x, 0, 0x88, text_colors[text_color_index], #line, buf_data);
87
		WriteBufText(start_x, 0, font_type, text_colors[text_color_index], #line, buf_data);
88
		if (b_text)	WriteBufText(start_x+1, 0, 0x88, text_colors[text_color_index], #line, buf_data);
88
		if (b_text)	WriteBufText(start_x+1, 0, font_type, text_colors[text_color_index], #line, buf_data);
89
		if (i_text) { stolbec++; DrawBuf.Skew(start_x, 0, line_length, list.line_h); }
89
		if (i_text) { stolbec++; DrawBuf.Skew(start_x, 0, line_length, list.line_h); } // bug with zoom>1
90
		if (s_text) DrawBuf.DrawBar(start_x, 4, line_length, 1, text_colors[text_color_index]);
90
		if (s_text) DrawBuf.DrawBar(start_x, list.line_h / 2 - DrawBuf.zoom, line_length, DrawBuf.zoom, text_colors[text_color_index]);
91
		if (u_text) DrawBuf.DrawBar(start_x, 8, line_length, 1, text_colors[text_color_index]);
91
		if (u_text) DrawBuf.DrawBar(start_x, list.line_h - DrawBuf.zoom - DrawBuf.zoom, line_length, DrawBuf.zoom, text_colors[text_color_index]);
92
		if (link) {
92
		if (link) {
93
			DrawBuf.DrawBar(start_x, 8, line_length, 1, text_colors[text_color_index]);
93
			DrawBuf.DrawBar(start_x, list.line_h - DrawBuf.zoom - DrawBuf.zoom, line_length, DrawBuf.zoom, text_colors[text_color_index]);
94
			UnsafeDefineButton(zstart_x-2, zstart_y-1, zline_length + 3, DrawBuf.zoomf * 10, PageLinks.count + 400 + BT_HIDE, 0xB5BFC9);
94
			UnsafeDefineButton(start_x-2, start_y-1, line_length + 3, DrawBuf.zoom * 10, PageLinks.count + 400 + BT_HIDE, 0xB5BFC9);
95
			PageLinks.AddText(#line, zline_length, draw_line_height, UNDERLINE);
95
			PageLinks.AddText(#line, line_length, list.line_h, UNDERLINE);
96
		}
96
		}
97
		stolbec += stolbec_len;
97
		stolbec += stolbec_len;
98
	}
98
	}
99
}
99
}
100
//=======================================================================
100
//=======================================================================
101
 
101
 
102
 
102
 
103
void BufEncode(int set_new_encoding)
103
void BufEncode(int set_new_encoding)
104
{
104
{
105
	int bufpointer_realsize;
105
	int bufpointer_realsize;
106
	cur_encoding = set_new_encoding;
106
	cur_encoding = set_new_encoding;
107
	if (o_bufpointer==0)
107
	if (o_bufpointer==0)
108
	{
108
	{
109
		o_bufpointer = malloc(bufsize);
109
		o_bufpointer = malloc(bufsize);
110
		strcpy(o_bufpointer, bufpointer);
110
		strcpy(o_bufpointer, bufpointer);
111
	}
111
	}
112
	else
112
	else
113
	{
113
	{
114
		strcpy(bufpointer, o_bufpointer);
114
		strcpy(bufpointer, o_bufpointer);
115
	}
115
	}
116
	if (set_new_encoding==_WIN) wintodos(bufpointer);
116
	if (set_new_encoding==_WIN) wintodos(bufpointer);
117
	if (set_new_encoding==_UTF) utf8rutodos(bufpointer);
117
	if (set_new_encoding==_UTF) utf8rutodos(bufpointer);
118
	if (set_new_encoding==_KOI) koitodos(bufpointer);
118
	if (set_new_encoding==_KOI) koitodos(bufpointer);
119
}
119
}
120
 
120
 
121
void TWebBrowser::Prepare(dword bufpos, in_filesize){
121
void TWebBrowser::Prepare(dword bufpos, in_filesize){
122
	bufsize = in_filesize;
122
	bufsize = in_filesize;
123
	bufpointer = bufpos;
123
	bufpointer = bufpos;
124
	Parse();
124
	Parse();
125
}
125
}
126
 
126
 
127
 
127
 
128
void TWebBrowser::Parse(){
128
void TWebBrowser::Parse(){
129
	word bukva[2];
129
	word bukva[2];
130
	int j;
130
	int j;
131
	byte ignor_param;
131
	byte ignor_param;
132
	char temp[768];
132
	char temp[768];
133
	dword bufpos = bufpointer;
133
	dword bufpos = bufpointer;
134
	int line_len;
134
	int line_len;
135
	
135
	
136
	b_text = i_text = u_text = s_text = blq_text = t_html = t_body =
136
	b_text = i_text = u_text = s_text = blq_text = t_html = t_body =
137
	li_text = link = ignor_text = text_color_index = text_colors[0] = li_tab = 
137
	li_text = link = ignor_text = text_color_index = text_colors[0] = li_tab = 
138
	condition_text_val = condition_text_active = 0; //îáíóëÿåì òåãè
138
	condition_text_val = condition_text_active = 0; //îáíóëÿåì òåãè
139
	end_parsing = false;
139
	end_parsing = false;
140
	condition_max = 255;
140
	condition_max = 255;
141
	text_align = ALIGN_LEFT;
141
	text_align = ALIGN_LEFT;
142
	link_color_inactive = 0x0000FF;
142
	link_color_inactive = 0x0000FF;
143
	link_color_active = 0xFF0000;
143
	link_color_active = 0xFF0000;
144
	bg_color = 0xFFFFFF;
144
	bg_color = 0xFFFFFF;
145
	DrawBuf.Fill(bg_color);
145
	DrawBuf.Fill(bg_color);
146
	PageLinks.Clear();
146
	PageLinks.Clear();
147
	strcpy(#header, #version);
147
	strcpy(#header, #version);
148
	stroka = -list.first;
148
	stroka = -list.first;
149
	stolbec = 0;
149
	stolbec = 0;
150
	line = 0;
150
	line = 0;
151
 
-
 
152
	draw_line_height = list.line_h * DrawBuf.zoomf;
151
 
153
	draw_line_width = list.w * DrawBuf.zoomf;
-
 
154
	draw_list_height = list.h * DrawBuf.zoomf;
152
	draw_line_width = list.w * DrawBuf.zoom;
155
 
153
 
156
	if (pre_text<>2)
154
	if (pre_text<>2)
157
	{
155
	{
158
		pre_text=0;
156
		pre_text=0;
159
		if (!strcmp(#URL + strlen(#URL) - 4, ".txt")) pre_text = 1;
157
		if (!strcmp(#URL + strlen(#URL) - 4, ".txt")) pre_text = 1;
160
		if (!strcmp(#URL + strlen(#URL) - 4, ".mht")) ignor_text = 1;
158
		if (!strcmp(#URL + strlen(#URL) - 4, ".mht")) ignor_text = 1;
161
	}
159
	}
162
	
160
	
163
	for ( ; (bufpointer+bufsize > bufpos) && (ESBYTE[bufpos]!=0); bufpos++;)
161
	for ( ; (bufpointer+bufsize > bufpos) && (ESBYTE[bufpos]!=0); bufpos++;)
164
	{
162
	{
165
		if (end_parsing) break;
163
		if (end_parsing) break;
166
		bukva = ESBYTE[bufpos];
164
		bukva = ESBYTE[bufpos];
167
		if (ignor_text) && (bukva!='<') continue;
165
		if (ignor_text) && (bukva!='<') continue;
168
		if (condition_text_active) && (condition_text_val != condition_href) && (bukva!='<') continue;
166
		if (condition_text_active) && (condition_text_val != condition_href) && (bukva!='<') continue;
169
		switch (bukva)
167
		switch (bukva)
170
		{
168
		{
171
		case 0x0a:
169
		case 0x0a:
172
			if (pre_text)
170
			if (pre_text)
173
			{
171
			{
174
				chrcat(#line, ' ');
172
				chrcat(#line, ' ');
175
				bukva = temp = NULL;
173
				bukva = temp = NULL;
176
				Perenos();
174
				Perenos();
177
				break;
175
				break;
178
			}
176
			}
179
		case '\9':
177
		case '\9':
180
			if (pre_text) //èíà÷å èä¸ì íà 0x0d	
178
			if (pre_text) //èíà÷å èä¸ì íà 0x0d	
181
			{
179
			{
182
				tab_len = strlen(#line) % 4;
180
				tab_len = strlen(#line) % 4;
183
				if (!tab_len) tab_len = 4;
181
				if (!tab_len) tab_len = 4;
184
				for (j=0; j
182
				for (j=0; j
185
				break;
183
				break;
186
			}
184
			}
187
			goto DEFAULT_MARK;		
185
			goto DEFAULT_MARK;		
188
		case '=': //quoted printable
186
		case '=': //quoted printable
189
			if (strcmp(#URL + strlen(#URL) - 4, ".mht")<>0) goto DEFAULT_MARK;
187
			if (strcmp(#URL + strlen(#URL) - 4, ".mht")<>0) goto DEFAULT_MARK;
190
 
188
 
191
			temp[0] = ESBYTE[bufpos+1];
189
			temp[0] = ESBYTE[bufpos+1];
192
			temp[1] = ESBYTE[bufpos+2];
190
			temp[1] = ESBYTE[bufpos+2];
193
			temp[2] = '\0';
191
			temp[2] = '\0';
194
			if (bukva = Hex2Symb(#temp))
192
			if (bukva = Hex2Symb(#temp))
195
			{
193
			{
196
				bufpos+=2;
194
				bufpos+=2;
197
				goto DEFAULT_MARK;
195
				goto DEFAULT_MARK;
198
			}
196
			}
199
			break;
197
			break;
200
			
198
			
201
		case '&': //  and so on
199
		case '&': //  and so on
202
			bufpos++;
200
			bufpos++;
203
			tag=0;
201
			tag=0;
204
			for (j=0; (ESBYTE[bufpos]<>';') && (j<7);   j++, bufpos++;)
202
			for (j=0; (ESBYTE[bufpos]<>';') && (j<7);   j++, bufpos++;)
205
			{
203
			{
206
				bukva = ESBYTE[bufpos];
204
				bukva = ESBYTE[bufpos];
207
				chrcat(#tag, bukva);
205
				chrcat(#tag, bukva);
208
			}
206
			}
209
			if (bukva = GetUnicodeSymbol()) goto DEFAULT_MARK;
207
			if (bukva = GetUnicodeSymbol()) goto DEFAULT_MARK;
210
			break;
208
			break;
211
		case '<':
209
		case '<':
212
			bufpos++; //ïðîìîòàåì ñèìâîë <
210
			bufpos++; //ïðîìîòàåì ñèìâîë <
213
			tag = parametr = tagparam = ignor_param = NULL;
211
			tag = parametr = tagparam = ignor_param = NULL;
214
			if (ESBYTE[bufpos] == '!') //ôèëüòðàöèÿ âíóòðè , äåðçêî
212
			if (ESBYTE[bufpos] == '!') //ôèëüòðàöèÿ âíóòðè , äåðçêî
215
			{
213
			{
216
				bufpos++;
214
				bufpos++;
217
				if (ESBYTE[bufpos] == '-')
215
				if (ESBYTE[bufpos] == '-')
218
				{
216
				{
219
				HH_:
217
				HH_:
220
					do
218
					do
221
					{
219
					{
222
						bufpos++;
220
						bufpos++;
223
						if (bufpointer + bufsize <= bufpos) break 2;
221
						if (bufpointer + bufsize <= bufpos) break 2;
224
					}
222
					}
225
					while (ESBYTE[bufpos] <>'-');
223
					while (ESBYTE[bufpos] <>'-');
226
					
224
					
227
					bufpos++;
225
					bufpos++;
228
					if (ESBYTE[bufpos] <>'-') goto HH_;
226
					if (ESBYTE[bufpos] <>'-') goto HH_;
229
				}
227
				}
230
			}
228
			}
231
			while (ESBYTE[bufpos] !='>') && (bufpos < bufpointer + bufsize) //ïîëó÷àåì òåã è åãî ïàðàìåòðû
229
			while (ESBYTE[bufpos] !='>') && (bufpos < bufpointer + bufsize) //ïîëó÷àåì òåã è åãî ïàðàìåòðû
232
			{
230
			{
233
				bukva = ESBYTE[bufpos];
231
				bukva = ESBYTE[bufpos];
234
				if (bukva == '\9') || (bukva == '\x0a') || (bukva == '\x0d') bukva = ' ';
232
				if (bukva == '\9') || (bukva == '\x0a') || (bukva == '\x0d') bukva = ' ';
235
				if (!ignor_param) && (bukva <>' ')
233
				if (!ignor_param) && (bukva <>' ')
236
				{
234
				{
237
					if (strlen(#tag)
235
					if (strlen(#tag)
238
				}
236
				}
239
				else
237
				else
240
				{
238
				{
241
					ignor_param = true;
239
					ignor_param = true;
242
					if (!ignor_text) && (strlen(#tagparam)+1
240
					if (!ignor_text) && (strlen(#tagparam)+1
243
				}
241
				}
244
				bufpos++;
242
				bufpos++;
245
			}
243
			}
246
			strlwr(#tag);
244
			strlwr(#tag);
247
 
245
 
248
			if (condition_text_active) && (condition_text_val != condition_href) 
246
			if (condition_text_active) && (condition_text_val != condition_href) 
249
			{
247
			{
250
				if (strcmp(#tag, "/condition")!=0) break;
248
				if (strcmp(#tag, "/condition")!=0) break;
251
			}
249
			}
252
			if (tag[strlen(#tag)-1]=='/') tag[strlen(#tag)-1]=NULL; //for br/
250
			if (tag[strlen(#tag)-1]=='/') tag[strlen(#tag)-1]=NULL; //for br/
253
			if (tagparam) GetNextParam();
251
			if (tagparam) GetNextParam();
254
 
252
 
255
			if (stolbec + strlen(#line) > list.column_max) Perenos();
253
			if (stolbec + strlen(#line) > list.column_max) Perenos();
256
			DrawPage();
254
			DrawPage();
257
			line = NULL;
255
			line = NULL;
258
			if (tag) SetTextStyle(WB1.DrawBuf.zoomf * 5 + list.x, stroka * draw_line_height + list.y + 5); //îáðàáîòêà òåãîâ
256
			if (tag) SetTextStyle(WB1.DrawBuf.zoom * 5 + list.x, stroka * list.line_h + list.y + 5); //îáðàáîòêà òåãîâ
259
			tag = parametr = tagparam = ignor_param = NULL;
257
			tag = parametr = tagparam = ignor_param = NULL;
260
			break;
258
			break;
261
		default:
259
		default:
262
			DEFAULT_MARK:
260
			DEFAULT_MARK:
263
			if (bukva<=15) bukva=' ';
261
			if (bukva<=15) bukva=' ';
264
			line_len = strlen(#line);
262
			line_len = strlen(#line);
265
			if (!pre_text) && (bukva == ' ')
263
			if (!pre_text) && (bukva == ' ')
266
			{
264
			{
267
				if (line[line_len-1]==' ') break; //no double spaces
265
				if (line[line_len-1]==' ') break; //no double spaces
268
				if (!stolbec) && (!line) break; //no paces at the beginning of the line
266
				if (!stolbec) && (!line) break; //no paces at the beginning of the line
269
			}
267
			}
270
			if (line_len < sizeof(line)) chrcat(#line, bukva);
268
			if (line_len < sizeof(line)) chrcat(#line, bukva);
271
			if (stolbec + line_len > list.column_max) Perenos();
269
			if (stolbec + line_len > list.column_max) Perenos();
272
		}
270
		}
273
	}
271
	}
274
	DrawPage();
272
	DrawPage();
275
	NewLine();
273
	NewLine();
276
	DrawBar(list.x, stroka * draw_line_height + list.y + 5, draw_line_width, -stroka * draw_line_height + draw_list_height - 5, bg_color);
274
	DrawBar(list.x, stroka * list.line_h + list.y + 5, draw_line_width, -stroka * list.line_h + list.h - 5, bg_color);
277
	DrawBar(list.x, list.visible * draw_line_height + list.y + 4, draw_line_width, -list.visible * draw_line_height + draw_list_height - 4, bg_color);
275
	DrawBar(list.x, list.visible * list.line_h + list.y + 4, draw_line_width, -list.visible * list.line_h + list.h - 4, bg_color);
278
	if (list.first == 0) list.count = stroka;
276
	if (list.first == 0) list.count = stroka;
279
	if (anchor) //åñëè ïîñðåäè òåêñòà ïîÿâèòñÿ íîâûé ÿêîðü - áóäåò áåñêîíå÷íûé öèêë
277
	if (anchor) //åñëè ïîñðåäè òåêñòà ïîÿâèòñÿ íîâûé ÿêîðü - áóäåò áåñêîíå÷íûé öèêë
280
	{
278
	{
281
		anchor=NULL;
279
		anchor=NULL;
282
		list.first=anchor_line_num;
280
		list.first=anchor_line_num;
283
		Parse();
281
		Parse();
284
	}
282
	}
285
	DrawScroller();
283
	DrawScroller();
286
}
284
}
287
 
285
 
288
void TWebBrowser::Perenos()
286
void TWebBrowser::Perenos()
289
{
287
{
290
	int perenos_num;
288
	int perenos_num;
291
	char new_line_text[4096];
289
	char new_line_text[4096];
292
	perenos_num = strrchr(#line, ' ');
290
	perenos_num = strrchr(#line, ' ');
293
	if (!perenos_num) && (strlen(#line)>list.column_max) perenos_num=list.column_max;
291
	if (!perenos_num) && (strlen(#line)>list.column_max) perenos_num=list.column_max;
294
	strcpy(#new_line_text, #line + perenos_num);
292
	strcpy(#new_line_text, #line + perenos_num);
295
	line[perenos_num] = 0x00;
293
	line[perenos_num] = 0x00;
296
	if (stroka-1 > list.visible) && (list.first <>0) end_parsing=true;
294
	if (stroka-1 > list.visible) && (list.first <>0) end_parsing=true;
297
	DrawPage();
295
	DrawPage();
298
	strcpy(#line, #new_line_text);
296
	strcpy(#line, #new_line_text);
299
	NewLine();
297
	NewLine();
300
}
298
}
301
 
299
 
302
 
300
 
303
char oldtag[100];
301
char oldtag[100];
304
void TWebBrowser::SetTextStyle(int left1, top1) {
302
void TWebBrowser::SetTextStyle(int left1, top1) {
305
	dword hr_color;
303
	dword hr_color;
306
	byte opened;
304
	byte opened;
307
	byte meta_encoding;
305
	byte meta_encoding;
308
	//ïðîâåðÿåì òåã îòêðûâàåòñÿ èëè çàêðûâàåòñÿ
306
	//ïðîâåðÿåì òåã îòêðûâàåòñÿ èëè çàêðûâàåòñÿ
309
	if (tag[0] == '/') 
307
	if (tag[0] == '/') 
310
	{
308
	{
311
		 opened = 0;
309
		 opened = 0;
312
		 strcpy(#tag, #tag+1);
310
		 strcpy(#tag, #tag+1);
313
	}
311
	}
314
	else opened = 1;
312
	else opened = 1;
315
		
313
		
316
	if (isTag("html"))
314
	if (isTag("html"))
317
	{
315
	{
318
		IF(!strcmp(#URL + strlen(#URL) - 4, ".mht")) IF (opened==0) ignor_text = 1; ELSE ignor_text = 0;
316
		IF(!strcmp(#URL + strlen(#URL) - 4, ".mht")) IF (opened==0) ignor_text = 1; ELSE ignor_text = 0;
319
		t_html = opened;
317
		t_html = opened;
320
		return;
318
		return;
321
	}
319
	}
322
 
320
 
323
	if (isTag("script")) || (isTag("style")) || (isTag("binary")) || (isTag("select")) ignor_text = opened;
321
	if (isTag("script")) || (isTag("style")) || (isTag("binary")) || (isTag("select")) ignor_text = opened;
324
 
322
 
325
	if(isTag("title"))
323
	if(isTag("title"))
326
	{
324
	{
327
		if (opened) header=NULL;
325
		if (opened) header=NULL;
328
		else if (!stroka) DrawTitle(#header); //òåã çàêðûëñÿ - âûâåëè ñòðîêó
326
		else if (!stroka) DrawTitle(#header); //òåã çàêðûëñÿ - âûâåëè ñòðîêó
329
		return;
327
		return;
330
	}
328
	}
331
 
329
 
332
	if (ignor_text) return;
330
	if (ignor_text) return;
333
	
331
	
334
	IF(isTag("q"))
332
	IF(isTag("q"))
335
	{
333
	{
336
		if (opened)
334
		if (opened)
337
		{
335
		{
338
			NewLine();
336
			NewLine();
339
			strcat(#line, ' \"');
337
			strcat(#line, ' \"');
340
		}
338
		}
341
		if (!opened)
339
		if (!opened)
342
		{
340
		{
343
			chrcat(#line, '\"');
341
			chrcat(#line, '\"');
344
			NewLine();
342
			NewLine();
345
		} 
343
		} 
346
	}
344
	}
347
 
345
 
348
	if (anchor) && (!strcmp(#parametr, "id=")) //î÷åíü ïëîõî!!! ïîòîìó ÷òî åñëè íå ïîñëåäíèé òåã, ðàáîòàòü íå áóäåò
346
	if (anchor) && (!strcmp(#parametr, "id=")) //î÷åíü ïëîõî!!! ïîòîìó ÷òî åñëè íå ïîñëåäíèé òåã, ðàáîòàòü íå áóäåò
349
	{
347
	{
350
		if (!strcmp(#anchor, #options))	anchor_line_num=list.first+stroka;
348
		if (!strcmp(#anchor, #options))	anchor_line_num=list.first+stroka;
351
	}
349
	}
352
	
350
	
353
	if (isTag("body"))
351
	if (isTag("body"))
354
	{
352
	{
355
		t_body = opened;
353
		t_body = opened;
356
		do{
354
		do{
357
			if (!strcmp(#parametr, "condition_max=")) condition_max = atoi(#options);
355
			if (!strcmp(#parametr, "condition_max=")) condition_max = atoi(#options);
358
			if (!strcmp(#parametr, "link=")) link_color_inactive = GetColor(#options);
356
			if (!strcmp(#parametr, "link=")) link_color_inactive = GetColor(#options);
359
			if (!strcmp(#parametr, "alink=")) link_color_active = GetColor(#options);
357
			if (!strcmp(#parametr, "alink=")) link_color_active = GetColor(#options);
360
			if (!strcmp(#parametr, "text=")) text_colors[0]=GetColor(#options);
358
			if (!strcmp(#parametr, "text=")) text_colors[0]=GetColor(#options);
361
			if (!strcmp(#parametr, "bgcolor="))
359
			if (!strcmp(#parametr, "bgcolor="))
362
			{
360
			{
363
				bg_color=GetColor(#options);
361
				bg_color=GetColor(#options);
364
				DrawBuf.Fill(bg_color);
362
				DrawBuf.Fill(bg_color);
365
			}
363
			}
366
		} while(GetNextParam());
364
		} while(GetNextParam());
367
		if (opened) && (cur_encoding==_DEFAULT)
365
		if (opened) && (cur_encoding==_DEFAULT)
368
		{
366
		{
369
			debugln("Document has no information about encoding, UTF will be used");
367
			debugln("Document has no information about encoding, UTF will be used");
370
			BufEncode(_UTF);
368
			BufEncode(_UTF);
371
		}
369
		}
372
		return;
370
		return;
373
	}
371
	}
374
 
372
 
375
	if (isTag("a"))
373
	if (isTag("a"))
376
	{
374
	{
377
		if (opened)
375
		if (opened)
378
		{
376
		{
379
			if (link) IF(text_color_index > 0) text_color_index--; //åñëè ïðåäûäóùèé òåã à íå áûë çàêðûò
377
			if (link) IF(text_color_index > 0) text_color_index--; //åñëè ïðåäûäóùèé òåã à íå áûë çàêðûò
380
 
378
 
381
			do{
379
			do{
382
				if (!strcmp(#parametr, "href="))
380
				if (!strcmp(#parametr, "href="))
383
				{
381
				{
384
					if (stroka - 1 > list.visible) || (stroka < -2) return;
382
					if (stroka - 1 > list.visible) || (stroka < -2) return;
385
					
383
					
386
					text_color_index++;
384
					text_color_index++;
387
					text_colors[text_color_index] = text_colors[text_color_index-1];
385
					text_colors[text_color_index] = text_colors[text_color_index-1];
388
					
386
					
389
					link = 1;
387
					link = 1;
390
					text_colors[text_color_index] = link_color_inactive;
388
					text_colors[text_color_index] = link_color_inactive;
391
					PageLinks.AddLink(#options, DrawBuf.zoomf * stolbec*6+left1, top1-2);
389
					PageLinks.AddLink(#options, DrawBuf.zoom * stolbec*6+left1, top1-DrawBuf.zoom);
392
				}
390
				}
393
				if (anchor) && (!strcmp(#parametr, "name="))
391
				if (anchor) && (!strcmp(#parametr, "name="))
394
				{
392
				{
395
					if (!strcmp(#anchor, #options))
393
					if (!strcmp(#anchor, #options))
396
					{
394
					{
397
						anchor_line_num=list.first+stroka;
395
						anchor_line_num=list.first+stroka;
398
					}
396
					}
399
				}
397
				}
400
			} while(GetNextParam());
398
			} while(GetNextParam());
401
		}
399
		}
402
		else {
400
		else {
403
			link = 0;
401
			link = 0;
404
			IF(text_color_index > 0) text_color_index--;
402
			IF(text_color_index > 0) text_color_index--;
405
		}
403
		}
406
		return;
404
		return;
407
	}
405
	}
408
 
406
 
409
	if (isTag("font"))
407
	if (isTag("font"))
410
	{
408
	{
411
		if (opened)
409
		if (opened)
412
		{
410
		{
413
			text_color_index++;
411
			text_color_index++;
414
			text_colors[text_color_index] = text_colors[text_color_index-1];
412
			text_colors[text_color_index] = text_colors[text_color_index-1];
415
		
413
		
416
			do{
414
			do{
417
				if (strcmp(#parametr, "color=") == 0) //&& (parametr[1] == '#')
415
				if (strcmp(#parametr, "color=") == 0) //&& (parametr[1] == '#')
418
				{
416
				{
419
					text_colors[text_color_index] = GetColor(#options);
417
					text_colors[text_color_index] = GetColor(#options);
420
				}
418
				}
421
			} while(GetNextParam());
419
			} while(GetNextParam());
422
		}
420
		}
423
		else
421
		else
424
			if (text_color_index > 0) text_color_index--;
422
			if (text_color_index > 0) text_color_index--;
425
		return;
423
		return;
426
	}
424
	}
427
	if (isTag("br")) {
425
	if (isTag("br")) {
428
		NewLine();
426
		NewLine();
429
		return;
427
		return;
430
	}
428
	}
431
	if (isTag("div")) || (isTag("header")) || (isTag("article")) || (isTag("footer")) {
429
	if (isTag("div")) || (isTag("header")) || (isTag("article")) || (isTag("footer")) {
432
		IF(oldtag[0] <>'h') NewLine();
430
		IF(oldtag[0] <>'h') NewLine();
433
		if (!strcmp(#parametr, "bgcolor="))
431
		if (!strcmp(#parametr, "bgcolor="))
434
		{
432
		{
435
			bg_color=GetColor(#options);
433
			bg_color=GetColor(#options);
436
			DrawBuf.Fill(bg_color);
434
			DrawBuf.Fill(bg_color);
437
		}
435
		}
438
		return;
436
		return;
439
	}
437
	}
440
	if (isTag("p")) {
438
	if (isTag("p")) {
441
		IF(oldtag[0] == 'h') return;
439
		IF(oldtag[0] == 'h') return;
442
		NewLine();
440
		NewLine();
443
		IF(opened) NewLine();
441
		IF(opened) NewLine();
444
		return;
442
		return;
445
	}
443
	}
446
 
444
 
447
	if(isTag("table")) {
445
	if(isTag("table")) {
448
		table.active = opened;
446
		table.active = opened;
449
		NewLine();
447
		NewLine();
450
		if (opened)	table.NewTable();
448
		if (opened)	table.NewTable();
451
	}
449
	}
452
 
450
 
453
	if(isTag("td")) {
451
	if(isTag("td")) {
454
		if (opened)
452
		if (opened)
455
		{
453
		{
456
			table.cur_col++;
454
			table.cur_col++;
457
			table.row_h = 0;
455
			table.row_h = 0;
458
			do {
456
			do {
459
				if (!strcmp(#parametr, "width="))
457
				if (!strcmp(#parametr, "width="))
460
				{
458
				{
461
					table.col_w[table.cur_col] = atoi(#options);
459
					table.col_w[table.cur_col] = atoi(#options);
462
					// NewLine();
460
					// NewLine();
463
					// strcpy(#line, #options);
461
					// strcpy(#line, #options);
464
					// NewLine();
462
					// NewLine();
465
				}
463
				}
466
			} while(GetNextParam());
464
			} while(GetNextParam());
467
		}
465
		}
468
		else
466
		else
469
		{
467
		{
470
			if (table.row_h > table.row_max_h) table.row_max_h = table.row_h;
468
			if (table.row_h > table.row_max_h) table.row_max_h = table.row_h;
471
		}
469
		}
472
	}
470
	}
473
 
471
 
474
	if(isTag("tr")) {
472
	if(isTag("tr")) {
475
		if (opened)
473
		if (opened)
476
		{
474
		{
477
			table.cur_col = 0;
475
			table.cur_col = 0;
478
			table.row_max_h = 0;
476
			table.row_max_h = 0;
479
			table.row_start = stroka;
477
			table.row_start = stroka;
480
		}
478
		}
481
		else
479
		else
482
		{
480
		{
483
			NewLine();
481
			NewLine();
484
			if (table.cur_row == 0) table.max_cols = table.cur_col;
482
			if (table.cur_row == 0) table.max_cols = table.cur_col;
485
			table.cur_row++;
483
			table.cur_row++;
486
			table.max_cols = table.cur_col;
484
			table.max_cols = table.cur_col;
487
		}
485
		}
488
	}
486
	}
489
 
487
 
490
	/*
488
	/*
491
	if (isTag("center"))
489
	if (isTag("center"))
492
	{
490
	{
493
		if (opened) text_align = ALIGN_CENTER;
491
		if (opened) text_align = ALIGN_CENTER;
494
		if (!opened)
492
		if (!opened)
495
		{
493
		{
496
			NewLine();
494
			NewLine();
497
			text_align = ALIGN_LEFT;
495
			text_align = ALIGN_LEFT;
498
		}
496
		}
499
		return;
497
		return;
500
	}
498
	}
501
	if (isTag("right"))
499
	if (isTag("right"))
502
	{
500
	{
503
		if (opened) text_align = ALIGN_RIGHT;
501
		if (opened) text_align = ALIGN_RIGHT;
504
		if (!opened)
502
		if (!opened)
505
		{
503
		{
506
			NewLine();
504
			NewLine();
507
			text_align = ALIGN_LEFT;
505
			text_align = ALIGN_LEFT;
508
		}
506
		}
509
		return;
507
		return;
510
	}
508
	}
511
	*/
509
	*/
512
	if (isTag("h1")) || (isTag("h2")) || (isTag("h3")) || (isTag("h4")) {
510
	if (isTag("h1")) || (isTag("h2")) || (isTag("h3")) || (isTag("h4")) {
513
		NewLine();
511
		NewLine();
514
		if (opened) && (stroka>1) NewLine();
512
		if (opened) && (stroka>1) NewLine();
515
		strcpy(#oldtag, #tag);
513
		strcpy(#oldtag, #tag);
516
		if (opened)
514
		if (opened)
517
		{
515
		{
518
			if (!strcmp(#parametr, "align=")) && (!strcmp(#options,"center")) text_align = ALIGN_CENTER;
516
			if (!strcmp(#parametr, "align=")) && (!strcmp(#options,"center")) text_align = ALIGN_CENTER;
519
			if (!strcmp(#parametr, "align=")) && (!strcmp(#options,"right")) text_align = ALIGN_RIGHT;
517
			if (!strcmp(#parametr, "align=")) && (!strcmp(#options,"right")) text_align = ALIGN_RIGHT;
520
			b_text = 1;
518
			b_text = 1;
521
		}
519
		}
522
		if (!opened)
520
		if (!opened)
523
		{
521
		{
524
			text_align = ALIGN_LEFT;
522
			text_align = ALIGN_LEFT;
525
			b_text = 0;
523
			b_text = 0;
526
		}
524
		}
527
		return;
525
		return;
528
	}
526
	}
529
	else
527
	else
530
		oldtag=NULL;
528
		oldtag=NULL;
531
		
529
		
532
	if (isTag("b")) || (isTag("strong")) || (isTag("big")) {
530
	if (isTag("b")) || (isTag("strong")) || (isTag("big")) {
533
		b_text = opened;
531
		b_text = opened;
534
		return;
532
		return;
535
	}
533
	}
536
	if(isTag("i")) || (isTag("em")) || (isTag("subtitle")) {
534
	if(isTag("i")) || (isTag("em")) || (isTag("subtitle")) {
537
		i_text = opened;
535
		i_text = opened;
538
		return;
536
		return;
539
	}	
537
	}	
540
	if (isTag("dt"))
538
	if (isTag("dt"))
541
	{
539
	{
542
		li_text = opened;
540
		li_text = opened;
543
		IF(opened == 0) return;
541
		IF(opened == 0) return;
544
		NewLine();
542
		NewLine();
545
		return;
543
		return;
546
	}
544
	}
547
	if (isTag("condition"))
545
	if (isTag("condition"))
548
	{
546
	{
549
		condition_text_active = opened;
547
		condition_text_active = opened;
550
		if (opened) && (!strcmp(#parametr, "show_if=")) condition_text_val = atoi(#options);
548
		if (opened) && (!strcmp(#parametr, "show_if=")) condition_text_val = atoi(#options);
551
		return;
549
		return;
552
	}
550
	}
553
	if (isTag("li")) || (isTag("dt")) //íàäî ñäåëàòü âëîæåííûå ñïèñêè
551
	if (isTag("li")) || (isTag("dt")) //íàäî ñäåëàòü âëîæåííûå ñïèñêè
554
	{
552
	{
555
		li_text = opened;
553
		li_text = opened;
556
		if (opened)
554
		if (opened)
557
		{
555
		{
558
			NewLine();
556
			NewLine();
-
 
557
			if (stroka > -1) && (stroka - 2 < list.visible) 
559
			if (stroka > -1) && (stroka - 2 < list.visible) DrawBuf.DrawBar(li_tab * 5 * 6 + list.x, list.line_h/2-2, 2, 2, 0x555555);
558
				DrawBuf.DrawBar(li_tab * 5 * 6 * DrawBuf.zoom + list.x, list.line_h / 2 - DrawBuf.zoom - DrawBuf.zoom, DrawBuf.zoom*2, DrawBuf.zoom*2, 0x555555);
560
		}
559
		}
561
		return;
560
		return;
562
	}
561
	}
563
	if (isTag("u")) || (isTag("ins")) u_text = opened;
562
	if (isTag("u")) || (isTag("ins")) u_text = opened;
564
	if (isTag("s")) || (isTag("strike")) || (isTag("del")) s_text = opened;
563
	if (isTag("s")) || (isTag("strike")) || (isTag("del")) s_text = opened;
565
	if (isTag("ul")) || (isTag("ol")) IF(!opened)
564
	if (isTag("ul")) || (isTag("ol")) IF(!opened)
566
	{
565
	{
567
		li_text = opened;
566
		li_text = opened;
568
		li_tab--;
567
		li_tab--;
569
		NewLine();
568
		NewLine();
570
	} ELSE li_tab++;
569
	} ELSE li_tab++;
571
	if (isTag("dd")) stolbec += 5;
570
	if (isTag("dd")) stolbec += 5;
572
	if (isTag("blockquote")) blq_text = opened;
571
	if (isTag("blockquote")) blq_text = opened;
573
	if (isTag("pre")) || (isTag("code")) pre_text = opened; 
572
	if (isTag("pre")) || (isTag("code")) pre_text = opened; 
574
	if (isTag("hr"))
573
	if (isTag("hr"))
575
	{
574
	{
576
		if (anchor) || (stroka < -1)
575
		if (anchor) || (stroka < -1)
577
		{
576
		{
578
			stroka+=2;
577
			stroka+=2;
579
			return;
578
			return;
580
		}
579
		}
581
		if (strcmp(#parametr, "color=") == 0) hr_color = GetColor(#options); else hr_color = 0x999999;
580
		if (strcmp(#parametr, "color=") == 0) hr_color = GetColor(#options); else hr_color = 0x999999;
582
		NewLine();
581
		NewLine();
583
		DrawBuf.DrawBar(5, list.line_h/2, list.w-10, 1, hr_color);
582
		DrawBuf.DrawBar(5, list.line_h/2, list.w-10, 1, hr_color);
584
		NewLine();
583
		NewLine();
585
	}
584
	}
586
	if (isTag("img"))
585
	if (isTag("img"))
587
	{
586
	{
588
		ImgCache.Images( left1, top1, WB1.list.w);
587
		ImgCache.Images( left1, top1, WB1.list.w);
589
		return;
588
		return;
590
	}
589
	}
591
	if (isTag("meta")) || (isTag("?xml"))
590
	if (isTag("meta")) || (isTag("?xml"))
592
	{
591
	{
593
		do{
592
		do{
594
			if (!strcmp(#parametr, "charset=")) || (!strcmp(#parametr, "content=")) || (!strcmp(#parametr, "encoding="))
593
			if (!strcmp(#parametr, "charset=")) || (!strcmp(#parametr, "content=")) || (!strcmp(#parametr, "encoding="))
595
			{
594
			{
596
				strcpy(#options, #options[strrchr(#options, '=')]); //ïîèñê â content=
595
				strcpy(#options, #options[strrchr(#options, '=')]); //ïîèñê â content=
597
				strlwr(#options);
596
				strlwr(#options);
598
				meta_encoding = _DEFAULT;
597
				meta_encoding = _DEFAULT;
599
				if (!strcmp(#options, "utf-8"))  || (!strcmp(#options,"utf8")) meta_encoding = _UTF;
598
				if (!strcmp(#options, "utf-8"))  || (!strcmp(#options,"utf8")) meta_encoding = _UTF;
600
				if (!strcmp(#options, "koi8-r")) || (!strcmp(#options, "koi8-u")) meta_encoding = _KOI;
599
				if (!strcmp(#options, "koi8-r")) || (!strcmp(#options, "koi8-u")) meta_encoding = _KOI;
601
				if (!strcmp(#options, "windows-1251")) || (!strcmp(#options, "windows1251")) meta_encoding = _WIN;
600
				if (!strcmp(#options, "windows-1251")) || (!strcmp(#options, "windows1251")) meta_encoding = _WIN;
602
				if (!strcmp(#options, "dos"))    || (!strcmp(#options, "cp-866"))   meta_encoding = _DOS;
601
				if (!strcmp(#options, "dos"))    || (!strcmp(#options, "cp-866"))   meta_encoding = _DOS;
603
				if (cur_encoding==_DEFAULT) BufEncode(meta_encoding);
602
				if (cur_encoding==_DEFAULT) BufEncode(meta_encoding);
604
				return;
603
				return;
605
			}
604
			}
606
		} while(GetNextParam());
605
		} while(GetNextParam());
607
		return;
606
		return;
608
	}
607
	}
609
}
608
}
610
 
609
 
611
void TWebBrowser::DrawScroller()
610
void TWebBrowser::DrawScroller()
612
{
611
{
613
	scroll_wv.max_area = list.count;
612
	scroll_wv.max_area = list.count;
614
	scroll_wv.cur_area = list.visible;
613
	scroll_wv.cur_area = list.visible;
615
	scroll_wv.position = list.first;
614
	scroll_wv.position = list.first;
616
 
615
 
617
	scroll_wv.all_redraw = 0;
616
	scroll_wv.all_redraw = 0;
618
	scroll_wv.start_x = list.x + list.w;
617
	scroll_wv.start_x = list.x + list.w;
619
	scroll_wv.start_y = list.y;
618
	scroll_wv.start_y = list.y;
620
 
619
 
621
	scroll_wv.size_y = list.h * DrawBuf.zoomf;
620
	scroll_wv.size_y = list.h;
622
	scroll_wv.start_x = list.w * DrawBuf.zoomf + list.x;
621
	scroll_wv.start_x = list.w * DrawBuf.zoom + list.x;
623
 
622
 
624
	scrollbar_v_draw(#scroll_wv);
623
	scrollbar_v_draw(#scroll_wv);
625
}
624
}
626
 
625
 
627
 
626
 
628
void TWebBrowser::NewLine()
627
void TWebBrowser::NewLine()
629
{
628
{
630
	int onleft, ontop, zontop;
629
	int onleft, ontop;
631
 
630
 
632
	onleft = list.x + 5;
631
	onleft = list.x + 5;
633
	ontop = stroka * list.line_h + list.y + 5;
632
	ontop = stroka * list.line_h + list.y + 5;
634
	zontop = stroka * list.line_h * DrawBuf.zoomf + list.y + 5;
-
 
635
	if (!stroka) DrawBar(list.x, list.y, draw_line_width, 5, bg_color);
633
	if (!stroka) DrawBar(list.x, list.y, draw_line_width, 5, bg_color);
636
	if (t_html) && (!t_body) return;
634
	if (t_html) && (!t_body) return;
637
	if (ontop>=list.y) && ( ontop < list.h+list.y-10)  && (!anchor)
635
	if (stroka * list.line_h + 5 >= 0) && ( stroka + 1 * list.line_h + 5 < list.h) && (!anchor)
638
	{
636
	{
639
		if (text_align == ALIGN_CENTER) DrawBuf.AlignCenter(onleft,ontop,list.w,list.line_h,stolbec * 6);
637
		if (text_align == ALIGN_CENTER) && (DrawBuf.zoom==1) DrawBuf.AlignCenter(onleft,ontop,list.w,list.line_h,stolbec * 6);
640
		if (text_align == ALIGN_RIGHT) DrawBuf.AlignRight(onleft,ontop,list.w,list.line_h,stolbec * 6);
638
		if (text_align == ALIGN_RIGHT) && (DrawBuf.zoom==1)  DrawBuf.AlignRight(onleft,ontop,list.w,list.line_h,stolbec * 6);
641
		DrawBuf.bufy = ontop;
639
		DrawBuf.bufy = ontop;
642
		DrawBuf.zbufy = zontop;
-
 
643
		DrawBuf.Show();
640
		DrawBuf.Show();
644
		DrawBuf.Fill(bg_color);
641
		DrawBuf.Fill(bg_color);
645
	}
642
	}
646
	stroka++;
643
	stroka++;
647
	if (blq_text) stolbec = 6; else stolbec = 0;
644
	if (blq_text) stolbec = 6; else stolbec = 0;
648
	if (li_text) stolbec = li_tab * 5;
645
	if (li_text) stolbec = li_tab * 5;
649
}
646
}
650
 
647
 
651
 
648
 
652
 
649
 
653
int isTag(dword text) 
650
int isTag(dword text) 
654
{ 
651
{ 
655
	if (!strcmp(#tag,text)) return 1; else return 0;
652
	if (!strcmp(#tag,text)) return 1; else return 0;
656
}
653
}
657
>
654
>
658
>
655
>