Commit | Line | Data |
---|---|---|
b311480e | 1 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 | 2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 3 | // |
973c2be1 | 4 | // This file is part of Open CASCADE Technology software library. |
b311480e | 5 | // |
d5f74e42 | 6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
10 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 11 | // |
973c2be1 | 12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. | |
7fd59977 | 14 | |
42cf5bc1 | 15 | |
7fd59977 | 16 | #include <ElCLib.hxx> |
42cf5bc1 | 17 | #include <GccAna_Circ2d3Tan.hxx> |
18 | #include <GccAna_Lin2dBisec.hxx> | |
19 | #include <GccEnt_BadQualifier.hxx> | |
20 | #include <GccEnt_QualifiedCirc.hxx> | |
21 | #include <GccEnt_QualifiedLin.hxx> | |
7fd59977 | 22 | #include <gp_Circ2d.hxx> |
23 | #include <gp_Dir2d.hxx> | |
42cf5bc1 | 24 | #include <gp_Lin2d.hxx> |
25 | #include <gp_Pnt2d.hxx> | |
26 | #include <IntAna2d_AnaIntersection.hxx> | |
27 | #include <IntAna2d_IntPoint.hxx> | |
28 | #include <Standard_OutOfRange.hxx> | |
29 | #include <StdFail_NotDone.hxx> | |
7fd59977 | 30 | #include <TColStd_Array1OfReal.hxx> |
7fd59977 | 31 | |
32 | //========================================================================= | |
0d969553 Y |
33 | // Creation of a circle tangent to three straight lines. + |
34 | // Create Bissectrices at Qualified1 and Qualified2 and + | |
35 | // Bissectrices at Qualified1 and Qualified3. + | |
36 | // Intersect bissectrices calculated in this way ==> Center points + | |
37 | // Choose the center point that corresponds to qualifiers and + | |
38 | // construct the solution of radius equal to the distance between the + | |
39 | // chosen center point and straight line Qualified1. + | |
7fd59977 | 40 | //========================================================================= |
7fd59977 | 41 | GccAna_Circ2d3Tan:: |
42 | GccAna_Circ2d3Tan (const GccEnt_QualifiedLin& Qualified1, | |
43 | const GccEnt_QualifiedLin& Qualified2, | |
44 | const GccEnt_QualifiedLin& Qualified3, | |
35e08fe8 | 45 | const Standard_Real |
7fd59977 | 46 | ): |
47 | ||
48 | //========================================================================= | |
0d969553 | 49 | // Initialization of fields. + |
7fd59977 | 50 | //========================================================================= |
51 | ||
52 | cirsol(1,4) , | |
53 | qualifier1(1,4) , | |
54 | qualifier2(1,4) , | |
55 | qualifier3(1,4) , | |
56 | TheSame1(1,4) , | |
57 | TheSame2(1,4) , | |
58 | TheSame3(1,4) , | |
59 | pnttg1sol(1,4) , | |
60 | pnttg2sol(1,4) , | |
61 | pnttg3sol(1,4) , | |
62 | par1sol(1,4) , | |
63 | par2sol(1,4) , | |
64 | par3sol(1,4) , | |
65 | pararg1(1,4) , | |
66 | pararg2(1,4) , | |
67 | pararg3(1,4) | |
68 | { | |
69 | ||
70 | TheSame1.Init(0); | |
71 | TheSame2.Init(0); | |
72 | TheSame3.Init(0); | |
73 | gp_Dir2d dirx(1.0,0.0); | |
7fd59977 | 74 | WellDone = Standard_False; |
75 | NbrSol = 0; | |
76 | if (!(Qualified1.IsEnclosed() || | |
77 | Qualified1.IsOutside() || Qualified1.IsUnqualified()) || | |
78 | !(Qualified2.IsEnclosed() || | |
79 | Qualified2.IsOutside() || Qualified2.IsUnqualified()) || | |
80 | !(Qualified3.IsEnclosed() || | |
81 | Qualified3.IsOutside() || Qualified3.IsUnqualified())) { | |
9775fa61 | 82 | throw GccEnt_BadQualifier(); |
7fd59977 | 83 | return; |
84 | } | |
85 | ||
86 | //========================================================================= | |
0d969553 | 87 | // Processing. + |
7fd59977 | 88 | //========================================================================= |
89 | ||
90 | gp_Lin2d L1(Qualified1.Qualified()); | |
91 | gp_Lin2d L2(Qualified2.Qualified()); | |
92 | gp_Lin2d L3(Qualified3.Qualified()); | |
93 | gp_Pnt2d origin1(L1.Location()); | |
94 | gp_Dir2d dir1(L1.Direction()); | |
95 | gp_Dir2d normL1(-dir1.Y(),dir1.X()); | |
96 | gp_Pnt2d origin2(L2.Location()); | |
97 | gp_Dir2d dir2(L2.Direction()); | |
98 | gp_Dir2d normL2(-dir2.Y(),dir2.X()); | |
99 | gp_Pnt2d origin3(L3.Location()); | |
100 | gp_Dir2d dir3(L3.Direction()); | |
101 | gp_Dir2d normL3(-dir3.Y(),dir3.X()); | |
102 | Standard_Real xloc1 = origin1.X(); | |
103 | Standard_Real xloc2 = origin2.X(); | |
104 | Standard_Real xloc3 = origin3.X(); | |
105 | Standard_Real yloc1 = origin1.Y(); | |
106 | Standard_Real yloc2 = origin2.Y(); | |
107 | Standard_Real yloc3 = origin3.Y(); | |
108 | Standard_Real xdir1 = dir1.X(); | |
109 | Standard_Real xdir2 = dir2.X(); | |
110 | Standard_Real xdir3 = dir3.X(); | |
111 | Standard_Real ydir1 = dir1.Y(); | |
112 | Standard_Real ydir2 = dir2.Y(); | |
113 | Standard_Real ydir3 = dir3.Y(); | |
114 | GccAna_Lin2dBisec Bisec1(L1,L2); | |
115 | GccAna_Lin2dBisec Bisec2(L1,L3); | |
116 | Standard_Integer ncote1=0; | |
117 | Standard_Integer ncote2=0; | |
118 | Standard_Integer ncote3=0; | |
119 | TColStd_Array1OfReal cote1(1,2); | |
120 | TColStd_Array1OfReal cote2(1,2); | |
121 | TColStd_Array1OfReal cote3(1,2); | |
122 | Standard_Integer nbsol = 0; | |
123 | if (Bisec1.IsDone() && Bisec2.IsDone()) { | |
124 | for (Standard_Integer i = 1 ; i <= Bisec1.NbSolutions() ; i++) { | |
125 | for (Standard_Integer j = 1 ; j <= Bisec2.NbSolutions() ; j++) { | |
126 | IntAna2d_AnaIntersection Intp(Bisec1.ThisSolution(i), | |
127 | Bisec2.ThisSolution(j)); | |
128 | if (Intp.IsDone()) { | |
129 | if (!Intp.IsEmpty()) { | |
130 | for (Standard_Integer k = 1 ; k <= Intp.NbPoints() ; k++) { | |
131 | nbsol++; | |
132 | Standard_Real Radius = (L1.Distance(Intp.Point(k).Value())+ | |
133 | L2.Distance(Intp.Point(k).Value())+ | |
134 | L3.Distance(Intp.Point(k).Value()))/3.0; | |
135 | gp_Pnt2d Center(Intp.Point(k).Value()); | |
136 | Standard_Real cx = Center.X(); | |
137 | Standard_Real cy = Center.Y(); | |
138 | cirsol(nbsol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); | |
139 | // ====================================================== | |
140 | gp_Dir2d dc1(origin1.XY()-Center.XY()); | |
141 | if (!Qualified1.IsUnqualified()) { | |
142 | qualifier1(nbsol) = Qualified1.Qualifier(); | |
143 | } | |
144 | else if (dc1.Dot(normL1) > 0.0) { | |
145 | qualifier1(nbsol) = GccEnt_outside; | |
146 | } | |
147 | else { qualifier1(nbsol) = GccEnt_enclosed; } | |
148 | gp_Dir2d dc2(origin2.XY()-Center.XY()); | |
149 | if (!Qualified2.IsUnqualified()) { | |
150 | qualifier2(nbsol) = Qualified2.Qualifier(); | |
151 | } | |
152 | else if (dc2.Dot(normL2) > 0.0) { | |
153 | qualifier2(nbsol) = GccEnt_outside; | |
154 | } | |
155 | else { qualifier2(nbsol) = GccEnt_enclosed; } | |
156 | gp_Dir2d dc3(origin3.XY()-Center.XY()); | |
157 | if (!Qualified3.IsUnqualified()) { | |
158 | qualifier3(nbsol) = Qualified3.Qualifier(); | |
159 | } | |
160 | else if (dc3.Dot(normL3) > 0.0) { | |
161 | qualifier3(nbsol) = GccEnt_outside; | |
162 | } | |
163 | else { qualifier3(nbsol) = GccEnt_enclosed; } | |
164 | ||
165 | Standard_Real cross1=gp_Dir2d(-ydir1,xdir1) | |
166 | .Dot(gp_Dir2d(xloc1-cx,yloc1-cy)); | |
167 | Standard_Real cross2=gp_Dir2d(-ydir2,xdir2) | |
168 | .Dot(gp_Dir2d(xloc2-cx,yloc2-cy)); | |
169 | Standard_Real cross3=gp_Dir2d(-ydir3,xdir3) | |
170 | .Dot(gp_Dir2d(xloc3-cx,yloc3-cy)); | |
171 | if (cross1 != 0.0) { | |
172 | cross1 = cross1/Abs(cross1); | |
173 | } | |
174 | pnttg1sol(nbsol) = gp_Pnt2d(gp_XY(cx,cy)+ | |
175 | cross1*Radius*gp_XY(-ydir1,xdir1)); | |
176 | if (cross2 != 0.0) { | |
177 | cross2 = cross2/Abs(cross2); | |
178 | } | |
179 | pnttg2sol(nbsol) = gp_Pnt2d(gp_XY(cx,cy)+ | |
180 | cross2*Radius*gp_XY(-ydir2,xdir2)); | |
181 | if (cross3 != 0.0) { | |
182 | cross3 = cross3/Abs(cross3); | |
183 | } | |
184 | pnttg3sol(nbsol) = gp_Pnt2d(gp_XY(cx,cy)+ | |
185 | cross3*Radius*gp_XY(-ydir3,xdir3)); | |
186 | par1sol(nbsol)=ElCLib::Parameter(cirsol(nbsol), | |
187 | pnttg1sol(nbsol)); | |
188 | pararg1(nbsol)=ElCLib::Parameter(L1,pnttg1sol(nbsol)); | |
189 | par2sol(nbsol)=ElCLib::Parameter(cirsol(nbsol), | |
190 | pnttg2sol(nbsol)); | |
191 | pararg2(nbsol)=ElCLib::Parameter(L2,pnttg2sol(nbsol)); | |
192 | par3sol(nbsol)=ElCLib::Parameter(cirsol(nbsol), | |
193 | pnttg3sol(nbsol)); | |
194 | pararg3(nbsol)=ElCLib::Parameter(L3,pnttg3sol(nbsol)); | |
195 | } | |
196 | } | |
197 | WellDone = Standard_True; | |
198 | } | |
199 | } | |
200 | } | |
201 | } | |
202 | if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed() && | |
203 | // ========================================================= | |
204 | Qualified3.IsEnclosed()) { | |
205 | // ======================== | |
206 | ncote1 = 1; | |
207 | ncote2 = 1; | |
208 | ncote3 = 1; | |
209 | cote1(1) = 1.0; | |
210 | cote2(1) = 1.0; | |
211 | cote3(1) = 1.0; | |
212 | } | |
213 | else if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed() && | |
214 | // ============================================================== | |
215 | Qualified3.IsOutside()) { | |
216 | // ======================= | |
217 | ncote1 = 1; | |
218 | ncote2 = 1; | |
219 | ncote3 = 1; | |
220 | cote1(1) = 1.0; | |
221 | cote2(1) = 1.0; | |
222 | cote3(1) = -1.0; | |
223 | } | |
224 | else if (Qualified1.IsEnclosed() && Qualified2.IsOutside() && | |
225 | // ============================================================= | |
226 | Qualified3.IsEnclosed()) { | |
227 | // ======================== | |
228 | ncote1 = 1; | |
229 | ncote2 = 1; | |
230 | ncote3 = 1; | |
231 | cote1(1) = 1.0; | |
232 | cote2(1) = -1.0; | |
233 | cote3(1) = 1.0; | |
234 | } | |
235 | else if (Qualified1.IsEnclosed() && Qualified2.IsOutside() && | |
236 | // ============================================================= | |
237 | Qualified3.IsOutside()) { | |
238 | // ======================= | |
239 | ncote1 = 1; | |
240 | ncote2 = 1; | |
241 | ncote3 = 1; | |
242 | cote1(1) = 1.0; | |
243 | cote2(1) = -1.0; | |
244 | cote3(1) = -1.0; | |
245 | } | |
246 | else if (Qualified1.IsOutside() && Qualified2.IsEnclosed() && | |
247 | // ============================================================= | |
248 | Qualified3.IsEnclosed()) { | |
249 | // ======================== | |
250 | ncote1 = 1; | |
251 | ncote2 = 1; | |
252 | ncote3 = 1; | |
253 | cote1(1) = -1.0; | |
254 | cote2(1) = 1.0; | |
255 | cote3(1) = 1.0; | |
256 | } | |
257 | else if (Qualified1.IsOutside() && Qualified2.IsEnclosed() && | |
258 | // ============================================================= | |
259 | Qualified3.IsOutside()) { | |
260 | // ======================= | |
261 | ncote1 = 1; | |
262 | ncote2 = 1; | |
263 | ncote3 = 1; | |
264 | cote1(1) = -1.0; | |
265 | cote2(1) = 1.0; | |
266 | cote3(1) = -1.0; | |
267 | } | |
268 | else if (Qualified1.IsOutside() && Qualified2.IsOutside() && | |
269 | // ============================================================ | |
270 | Qualified3.IsEnclosed()) { | |
271 | // ======================== | |
272 | ncote1 = 1; | |
273 | ncote2 = 1; | |
274 | ncote3 = 1; | |
275 | cote1(1) = -1.0; | |
276 | cote2(1) = -1.0; | |
277 | cote3(1) = 1.0; | |
278 | } | |
279 | else if (Qualified1.IsOutside() && Qualified2.IsOutside() && | |
280 | // ============================================================ | |
281 | Qualified3.IsOutside()) { | |
282 | // ======================= | |
283 | ncote1 = 1; | |
284 | ncote2 = 1; | |
285 | ncote3 = 1; | |
286 | cote1(1) = -1.0; | |
287 | cote2(1) = -1.0; | |
288 | cote3(1) = -1.0; | |
289 | } | |
290 | else { | |
291 | if (Qualified1.IsUnqualified()) { | |
292 | // ==================================== | |
293 | ncote1 = 2; | |
294 | cote1(1) = 1.0; | |
295 | cote1(2) = -1.0; | |
296 | if (Qualified2.IsUnqualified()) { | |
297 | // =============================== | |
298 | ncote2 = 2; | |
299 | cote2(1) = 1.0; | |
300 | cote2(2) = -1.0; | |
301 | if (Qualified3.IsUnqualified()) { | |
302 | // =============================== | |
303 | ncote3 = 2; | |
304 | cote2(1) = 1.0; | |
305 | cote2(2) = -1.0; | |
306 | NbrSol = nbsol; | |
307 | WellDone = Standard_True; | |
308 | } | |
309 | else if (Qualified3.IsEnclosed()) { | |
310 | // =============================== | |
311 | ncote3 = 1; | |
312 | cote3(1) = 1.0; | |
313 | } | |
314 | else if (Qualified3.IsOutside()) { | |
315 | // ================================ | |
316 | ncote3 = 1; | |
317 | cote3(1) = -1.0; | |
318 | } | |
319 | } | |
320 | else if (Qualified2.IsEnclosed()) { | |
321 | // ================================= | |
322 | ncote2 = 1; | |
323 | cote2(1) = 1.0; | |
324 | if (Qualified3.IsUnqualified()) { | |
325 | // =============================== | |
326 | ncote3 = 2; | |
327 | cote3(1) = 1.0; | |
328 | cote3(1) = -1.0; | |
329 | } | |
330 | else if (Qualified3.IsEnclosed()) { | |
331 | // ================================= | |
332 | ncote3 = 1; | |
333 | cote3(1) = 1.0; | |
334 | } | |
335 | else if (Qualified3.IsOutside()) { | |
336 | // ================================ | |
337 | ncote3 = 1; | |
338 | cote3(1) = -1.0; | |
339 | } | |
340 | } | |
341 | else if (Qualified2.IsOutside()) { | |
342 | // ================================ | |
343 | ncote2 = 1; | |
344 | cote2(1) = -1.0; | |
345 | if (Qualified3.IsUnqualified()) { | |
346 | // =============================== | |
347 | ncote3 = 2; | |
348 | cote3(1) = 1.0; | |
349 | cote3(2) = -1.0; | |
350 | } | |
351 | else if (Qualified3.IsEnclosed()) { | |
352 | // ================================= | |
353 | ncote3 = 1; | |
354 | cote3(1) = 1.0; | |
355 | } | |
356 | else if (Qualified3.IsOutside()) { | |
357 | // ================================ | |
358 | ncote3 = 1; | |
359 | cote3(1) = -1.0; | |
360 | } | |
361 | } | |
362 | } | |
363 | else if (Qualified2.IsUnqualified()) { | |
364 | // =================================== | |
365 | ncote2 = 2; | |
366 | cote2(1) = 1.0; | |
367 | cote2(2) = -1.0; | |
368 | if (Qualified1.IsEnclosed()) { | |
369 | // ============================ | |
370 | ncote1 = 1; | |
371 | cote1(1) = 1.0; | |
372 | if (Qualified3.IsUnqualified()) { | |
373 | // =============================== | |
374 | ncote3 = 2; | |
375 | cote3(1) = -1.0; | |
376 | cote3(1) = -1.0; | |
377 | } | |
378 | else if (Qualified3.IsEnclosed()) { | |
379 | // ================================= | |
380 | ncote3 = 1; | |
381 | cote3(1) = 1.0; | |
382 | } | |
383 | else if (Qualified3.IsOutside()) { | |
384 | // ================================ | |
385 | ncote3 = 1; | |
386 | cote3(1) = -1.0; | |
387 | } | |
388 | } | |
389 | else if (Qualified1.IsOutside()) { | |
390 | // ================================ | |
391 | ncote1 = 1; | |
392 | cote1(1) = 1.0; | |
393 | if (Qualified3.IsUnqualified()) { | |
394 | // =============================== | |
395 | ncote3 = 2; | |
396 | cote3(1) = 1.0; | |
397 | cote3(2) = -1.0; | |
398 | } | |
399 | else if (Qualified3.IsEnclosed()) { | |
400 | // ================================= | |
401 | ncote3 = 1; | |
402 | cote3(1) = 1.0; | |
403 | } | |
404 | else if (Qualified3.IsOutside()) { | |
405 | // ================================ | |
406 | ncote3 = 1; | |
407 | cote3(1) = -1.0; | |
408 | } | |
409 | } | |
410 | } | |
411 | else if (Qualified3.IsUnqualified()) { | |
412 | // =================================== | |
413 | ncote3 = 2; | |
414 | cote3(1) = 1.0; | |
415 | cote3(2) = -1.0; | |
416 | if (Qualified1.IsEnclosed()) { | |
417 | // ============================ | |
418 | ncote1 = 1; | |
419 | cote1(1) = 1.0; | |
420 | if (Qualified2.IsEnclosed()) { | |
421 | // ============================ | |
422 | ncote2 = 1; | |
423 | cote2(1) = 1.0; | |
424 | } | |
425 | else if (Qualified2.IsOutside()) { | |
426 | // =============================== | |
427 | ncote2 = 1; | |
428 | cote2(1) = -1.0; | |
429 | } | |
430 | } | |
431 | else if (Qualified1.IsOutside()) { | |
432 | // ================================ | |
433 | ncote1 = 1; | |
434 | cote1(1) = -1.0; | |
435 | if (Qualified2.IsEnclosed()) { | |
436 | // ============================ | |
437 | ncote2 = 1; | |
438 | cote2(1) = 1.0; | |
439 | } | |
440 | else if (Qualified2.IsOutside()) { | |
441 | // =============================== | |
442 | ncote2 = 1; | |
443 | cote2(1) = -1.0; | |
444 | } | |
445 | } | |
446 | } | |
447 | } | |
448 | if (NbrSol > 0) { return; } | |
449 | for (Standard_Integer i = 1 ; i <= nbsol ; i++) { | |
450 | for (Standard_Integer j1 = 1 ; j1 <= ncote1 ; j1++) { | |
451 | for (Standard_Integer j2 = 1 ; j2 <= ncote2 ; j2++) { | |
452 | for (Standard_Integer j3 = 1 ; j3 <= ncote3 ; j3++) { | |
453 | if ((cote2(j2)*((cirsol(i).Location().X()-origin2.X())* | |
454 | (-dir2.Y())+(cirsol(i).Location().Y()- | |
455 | origin2.Y())*(dir2.X())) > 0.0) && | |
456 | (cote3(j3)*((cirsol(i).Location().X()-origin3.X())* | |
457 | (-dir3.Y())+(cirsol(i).Location().Y()- | |
458 | origin3.Y())*(dir3.X())) > 0.0) && | |
459 | (cote1(j1)*((cirsol(i).Location().X()-origin1.X())* | |
460 | (-dir1.Y())+(cirsol(i).Location().Y()- | |
461 | origin1.Y())*(dir1.X())) > 0.0)) { | |
462 | NbrSol++; | |
463 | cirsol(NbrSol) = gp_Circ2d(cirsol(i)); | |
464 | // ===================================== | |
465 | Standard_Real Radius = cirsol(NbrSol).Radius(); | |
466 | gp_Pnt2d Center(cirsol(NbrSol).Location()); | |
467 | gp_Dir2d dc(origin1.XY()-Center.XY()); | |
468 | Standard_Real sign = dc.Dot(gp_Dir2d(-dir1.Y(),dir1.X())); | |
469 | dc = gp_Dir2d(sign*gp_XY(-dir1.Y(),dir1.X())); | |
470 | pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY()); | |
471 | dc = gp_Dir2d(origin2.XY()-Center.XY()); | |
472 | sign = dc.Dot(gp_Dir2d(-dir2.Y(),dir2.X())); | |
473 | dc = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X())); | |
474 | pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY()); | |
475 | dc = gp_Dir2d(origin3.XY()-Center.XY()); | |
476 | sign = dc.Dot(gp_Dir2d(-dir3.Y(),dir3.X())); | |
477 | dc = gp_Dir2d(sign*gp_XY(-dir3.Y(),dir3.X())); | |
478 | pnttg3sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY()); | |
479 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), | |
480 | pnttg1sol(NbrSol)); | |
481 | pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol)); | |
482 | par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), | |
483 | pnttg2sol(NbrSol)); | |
484 | pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol)); | |
485 | par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), | |
486 | pnttg3sol(NbrSol)); | |
487 | pararg3(NbrSol)=ElCLib::Parameter(L3,pnttg3sol(NbrSol)); | |
488 | } | |
489 | } | |
490 | } | |
491 | } | |
492 | } | |
493 | } |