That's it. I would like to make it very general in order to get rebounces that fit best depending on geometry of object. Good OO exercise as you've said.
Related to BasicCoder2 search for a reducing data method, I'm posting here this other version, that is not bouncing but colliding and sampling the horse of Roland Chastain.
Code: Select all
'"-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
''
''Addition over 'BasicCoder2&al per-color pixel collision code'
''
'"-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
' .----.
' | 00 |
' .----.
#Include "fbgfx.bi"
Using FB
' .----.
' | 01 |
' .----.
Enum _COLOR
_SP1 = RGB(0,0,0)
_SP2 = RGB(237,28,36)
_SP3 = RGB(255,255,255)
_SP4 = RGB(255,0,255)
_BKG = RGB(190,235,200)
_Black = RGB(0, 0, 0)
_White = RGB(255, 255, 255)
_DarkGreen = RGB(50,200,0)
_LemonGreen = RGB(150, 200, 50)
_DelightGreen = RGB(200,225,200)
End Enum '_COLOR
' .----.
' | 02 |
' .----.
Const As Double _PI = 4 * Atn(1)
Const As Double _RTOD = 180 / _PI ' Rad * RtoD = Deg
Const As Double _DTOR = _PI / 180 ' Deg * DtoR = Rad
Const As Long _SCRW = 700
Const As Long _SCRH = 500
Const As Double _RADIUS = ( _SCRW + _SCRH - Abs( _SCRW - _SCRH) )/4 - 10
''Radius formula related to screen minimum dimension
ScreenRes _SCRW, _SCRH, 32
Color , _COLOR._BKG : Cls
Dim Shared horseBuffer As Any Ptr
Dim Shared reducedHorseBuffer As Any Ptr
horseBuffer = ImageCreate( 700, 500 )
reducedHorseBuffer = ImageCreate( 700, 500 )
'Read Horse DATAS
Restore Chastain
Dim as integer x, y
For _i as integer = 0 to 2844
Read x,y
PSet horseBuffer, (x, y), _COLOR._SP2
Next _i
Restore Hitter
' .----.
' | 03 |
' .----.
Namespace PRG
Declare Function BasicLength(ByVal A As Double, _
ByVal B As Double) _
As Double
Function BasicLength(ByVal A As Double, _
ByVal B As Double) _
As Double
Return Sqr(A*A + B*B)
End Function ' DOUBLE := BasicLength(DOUBLE A, DOUBLE B)
End Namespace 'PRG
' .----.
' | 04 |
' .----.
Type POINT2D
Declare Function BasicLength() As Double
Declare Sub Show(ByVal Radius As UByte = 2, _
ByVal _Color As ULong = _COLOR._Black)
As String _name = "POINT2D"
As Double _x
As Double _y
End Type 'POINT2D
Function POINT2D.BasicLength() As Double
Return PRG.BasicLength(This._x, This._y)
End Function 'DOUBLE := POINT2D.BasicLength()
Sub POINT2D.Show(ByVal Radius As UByte = 2, _
ByVal _Color As ULong = _COLOR._Black)
Draw String (This._x, This._y), This._name, _Color
Circle (This._x, This._y), Radius, _Color
End Sub 'POINT2D.Show(UByte Radius=2, ULong _Color=RGB(0,0,0))
' .----.
' | 05 |
' .----.
Type LINE2D Extends Object
'' _xcoefficient*X + _xcoefficient * Y + _constant == 0
'' Useful reference :
'' http://mathinsight.org/tangent_normal_lines_refresher
Declare Virtual Function SetFromTangent(ByVal WayPoint As POINT2D, _
ByVal TangentXCoefficient As Double, _
ByVal TangentYCoefficient As Double, _
ByVal TangentConstant As Double) _
As LINE2D
Declare Virtual Function SetFromNormal(ByVal WayPoint As POINT2D, _
ByVal NormalXCoefficient As Double, _
ByVal NormalYCoefficient As Double, _
ByVal NormalConstant As Double) _
As LINE2D
Declare Virtual Function ReturnTangent() As LINE2D
Declare Virtual Function ReturnNormal() As LINE2D
Declare Virtual Function EvaluateAtPoint(ByVal _Point2D As POINT2D) As Double
Declare Virtual Sub Show(ByVal Length As ULong = 10)
As String _name = "LINE2D"
As Double _xCoefficient
As Double _yCoefficient
As Double _constant
As POINT2D _contactPoint
End Type 'LINE2D <-- OBJECT
Function LINE2D.SetFromTangent(ByVal WayPoint As POINT2D, _
ByVal TangentXCoefficient As Double, _
ByVal TangentYCoefficient As Double, _
ByVal TangentConstant As Double) _
As LINE2D
Dim As LINE2D line2DReturn
With line2DReturn
._contactPoint = WayPoint
._xCoefficient = TangentXCoefficient
._yCoefficient = TangentYCoefficient
._constant = TangentConstant
End With 'line2DReturn
Return line2DReturn
End Function 'LINE2D := LINE2D.SetFromTangent(POINT2D, LINE2D)
Function LINE2D.SetFromNormal(ByVal WayPoint As POINT2D, _
ByVal NormalXCoefficient As Double, _
ByVal NormalYCoefficient As Double, _
ByVal NormalConstant As Double) _
As LINE2D
Dim As LINE2D line2DReturn
With line2DReturn
._contactPoint = WayPoint
._xCoefficient = - NormalYCoefficient
._yCoefficient = NormalXCoefficient
._constant = NormalYCoefficient * WayPoint._x - NormalXCoefficient * WayPoint._y
End With 'line2DReturn
Return line2DReturn
End Function 'LINE2D := LINE2D.SetFromNormal(POINT2D, LINE2D)
Function LINE2D.ReturnTangent() As LINE2D
Dim As LINE2D tangent2DReturn
tangent2DReturn = This
Return tangent2DReturn
End Function 'LINE2D.ReturnTangent()
Function LINE2D.ReturnNormal() As LINE2D
Dim As LINE2D normal2DReturn
With normal2DReturn
._contactPoint = This._contactPoint
._xCoefficient = -This._yCoefficient
._yCoefficient = This._xCoefficient
End With 'line2DReturn
With This
normal2DReturn._constant = _
-(._xCoefficient*._contactPoint._x + ._yCoefficient*._contactPoint._y)
End With 'This
Return normal2DReturn
End Function 'LINE2D.ReturnNormal()
Function LINE2D.EvaluateAtPoint(ByVal _Point2D As POINT2D) As Double
With This
._constant = _
-(._xCoefficient*._contactPoint._x + ._yCoefficient*._contactPoint._y)
End With 'This
Return _
This._xCoefficient * _Point2D._x + _
This._yCoefficient * _Point2D._y + _
This._constant
End Function 'Double := LINE2D.ReturnNormal(POINT2D)
Sub LINE2D.Show(ByVal Length As ULong = 10)
Dim As Double directorLength
With This
directorLength = PRG.BasicLength(._xCoefficient,._yCoefficient)
For _t As ULong = 1 To Length
PSet (._contactPoint._x - _t * ._yCoefficient/directorLength, _
._contactPoint._y + _t * ._xCoefficient/directorLength ), _
_COLOR._Black
PSet (._contactPoint._x + _t * ._yCoefficient/directorLength, _
._contactPoint._y - _t * ._xCoefficient/directorLength ), _
_COLOR._Black
Next _t
Draw String (._contactPoint._x + 5, ._contactPoint._y + 5), This._name
End With 'This
End Sub ''LINE2D.Show(Long Length=10)
' .----.
' | 06 |
' .----.
Type CIRCLE2D
Declare Function ReturnTangent(ByVal _AtContactPoint As POINT2D) _
As LINE2D
Declare Sub Show(ByVal _Color As Long)
Declare Sub Show(ByVal _Color As Long, ByVal _Thickness As Long)
Declare Sub Show(ByVal _BorderColor As Long, _
ByVal _InnerColor As Long, _
ByVal _Thickness As Long)
As String _name = "CIRCLE2D"
As POINT2D _centerPoint
As Double _radius
End Type 'CIRCLE2D <-- CURVE2D
Function CIRCLE2D.ReturnTangent(ByVal _AtContactPoint As POINT2D) As LINE2D
''Normal equation
Dim As LINE2D normal
Dim As LINE2D tangent
With normal
._xCoefficient = _AtContactPoint._y - This._centerPoint._y
._yCoefficient = This._centerPoint._x - _AtContactPoint._x
._constant = _
-(._xCoefficient * This._centerPoint._x + ._yCoefficient * This._centerPoint._y)
._contactPoint = _AtContactPoint
End With 'normal
tangent = tangent.SetFromNormal(_AtContactPoint, _
normal._xcoefficient, _
normal._ycoefficient, _
normal._constant)
Return tangent
End Function 'LINE2D := CIRCLE2D.ReturnTangent(POINT2D _AtContactPoint)
Sub CIRCLE2D.Show(ByVal _Color As Long)
Dim As POINT2D namePosition
namePosition._x= This._centerPoint._x + This._radius * Cos(0.7)
namePosition._y= This._centerPoint._y + This._radius * Sin(0.7)
Draw String (namePosition._x, namePosition._y), This._name, _Color
With This
Circle (._centerPoint._x, _centerPoint._y), ._radius, _Color
End With 'This
End Sub 'CIRCLE2D.Show(_Color)
Sub CIRCLE2D.Show(ByVal _Color As Long, ByVal _Thickness As Long)
''This._name not displayed
With This
Select Case _Thickness
Case Is < 1
_Thickness = 1
Case Is > ._radius
_Thickness = ._radius
End Select '_Thickness
For _i As UByte = _Thickness To 1 Step -1
Circle (._centerPoint._x, _centerPoint._y), ._radius-_i+1, _Color
Next _i
End With 'This
End Sub ''CIRCLE2D.Show(_Color, _Thickness)
Sub CIRCLE2D.Show(ByVal _BorderColor As Long, _
ByVal _InnerColor As Long, _
ByVal _Thickness As Long)
''This._name not displayed
With This
Select Case _Thickness
Case Is < 1
_Thickness = 1
Case Is > ._radius
_Thickness = ._radius
End Select '_Thickness
Circle (._centerPoint._x, _centerPoint._y), ._radius, _BorderColor
Circle (._centerPoint._x, _centerPoint._y), ._radius-_Thickness, _BorderColor
For _i As UByte = (_Thickness-1) To 1 Step -1
Circle (._centerPoint._x, _centerPoint._y), ._radius-_i, _InnerColor
Next _i
End With 'This
End Sub ''CIRCLE2D.Show(_BorderColor, _InnerColor, _Thickness)
' .----.
' | 07 |
' .----.
Declare Sub Update()
' .----.
' | 08 |
' .----.
Type SPRITE
Declare Static Sub BitmapCreateFromDATA(ByVal This As SPRITE)
As Double _x 'Topleft XCoordinates
As Double _y 'Topleft XCoordinates
As Double _w 'Width
As Double _h 'Height
As Double _dx 'For movement over X_axis
As Double _dy 'For movement over Y_axis
As Long _show 'If shown = 1
As Long _color
Static As Long _frameNumber
As FB.Image Ptr _img(1 To _frameNumber)
End Type 'SPRITE
Dim As Long SPRITE._frameNumber = 1
Sub SPRITE.BitmapCreateFromDATA(ByVal This As SPRITE)
'===========================
' THIS CREATES SPRITE BITMAP
'===========================
With This
Dim As String c
Dim As UByte cc
For k As Long = 1 To ._frameNumber
Read c
For j As Long = 0 to 3
For i As Long = 0 to 3
cc = c[i]
Select Case As Const cc
Case Asc("#")
For h As Long = k To ._frameNumber
PSet ._img(h),(i,j),RGB(0,0,0)
Next h
Case Asc(".")
For h As Long = k To ._frameNumber
PSet ._img(h),(i,j),rgb(237,28,36)
Next h
Case Asc("+")
For h As Long = k To ._frameNumber
PSet ._img(h),(i,j),rgb(255,255,255)
Next h
Case Asc(" ")
For h As Long = k To ._frameNumber
PSet ._img(h),(i,j),rgb(255,0,255)
Next h
End Select 'cc
Next i
Next j
Next k
End With 'This
'=============================
End Sub 'SPRITE.BitmapCreateFromDATA()
' .----.
' | 09 |
' .----.
Randomize Timer
Dim Shared launcher As CIRCLE2D
Dim Shared hitter As SPRITE
Dim Shared sightAngle As Double
'* Initialize launcher *
With launcher ''hitter is a CIRCLE2D
._name = "TESTCIRCLE"
._centerPoint._x = _SCRW\2
._centerPoint._y = _SCRH\2
._radius = _RADIUS
End With 'launcher
'* Initialize hitter *
sightAngle = 225
With hitter ''hitter is a SPRITE
._x = (_RADIUS - 20) * Cos(sightAngle*_DTOR) + _SCRW\2
._y = (_RADIUS - 20) * Sin(sightAngle*_DTOR) + _SCRH\2
._w = 4
._h = 4
._color = RGBA(255, 0, 255, 0)
._show = 1
._dx = (launcher._centerPoint._x - ._x)/(2*_RADIUS) 'Not >1 for current hittest to work
._dy = (launcher._centerPoint._y - ._y)/(2*_RADIUS)
._frameNumber = 2
For _i As ULong = 1 To ._frameNumber
ReDim Preserve ._img(1 To ._frameNumber)
._img(_i) = ImageCreate(._w, ._h, RGBA(255, 0, 255, 0))
Next _i
.BitmapCreateFromDATA(hitter)
For j As Long = 0 to 3
For i As Long = 0 to 3
PSet ._img(2),(i,j), _COLOR._BKG
Next i
Next j
End With 'hitter
' .-----.
' | M@N |
' .-----.
''***************************************************************
Update()
'[MAIN LOOP..
Do
If hitter._x + hitter._dx < _SCRW - 10 And _
hitter._x + hitter._dx > 10 Then
hitter._x = hitter._x + hitter._dx
Else
hitter._dx = -hitter._dx
hitter._x = hitter._x + hitter._dx
EndIf
If hitter._y + hitter._dy < _SCRH - 10 And _
hitter._y + hitter._dy > 10 Then
hitter._y = hitter._y + hitter._dy
Else
hitter._dy = -hitter._dy
hitter._y = hitter._y + hitter._dy
EndIf
Update()
Sleep 10, 1 ' 0.01 seconds
Loop Until sightAngle = (225+360) Or MultiKey(&H01)
'..MAIN LOOP]
For i As Long = 1 To hitter._frameNumber
ImageDestroy hitter._img(i)
Next i
'Draw the result sample image
Color , _COLOR._Black : Cls
Draw string (16,16),"SAMPLED CHASTAIN's HORSE RESULT"
Put (120, 50), reducedHorseBuffer, Trans
launcher.Show(_COLOR._DarkGreen, _COLOR._DelightGreen, 12)
Sleep
ImageDestroy( horseBuffer )
ImageDestroy( reducedHorseBuffer )
''***************************************************************
' .-----.
' | END |
' .-----.
Sleep
End 0
' .-----.
' | SUB |
' .-----.
Sub Update()
Dim as Long px,py,xx,yy 'position of sprite
Dim as double dx,dy
Dim as double angle 'direction of travel
Dim as double angle2 'direction of hit
Dim as Long hitflag 'hitflag = 1 means collision
Dim as Long takenflag 'probably means caught by object?
' .-----.
' | A00 |
' .-----.
ScreenLock
'Erase the hitter
'Put (hitter._x - hitter._dx, hitter._y - hitter._dy), hitter._img(2), Trans
'Move the hitter
hitter._x = hitter._x + hitter._dx
hitter._y = hitter._y + hitter._dy
'Record the hitter's approaching angle
Dim As Double approachAngle
approachAngle = ATan2(hitter._dy, hitter._dx)*57.2958
' .-----.
' | A01 |
' .-----.
'ScreenLock
'Must draw background for hittest before the hitter is drawn
'Draw the background image
Color , _COLOR._BKG : Cls
Put (120, 50), horseBuffer, TRANS
launcher.Show(_COLOR._DarkGreen, _COLOR._Black, 8)
' .-----.
' | A02 |
' .-----.
'Perform hit Test
hitflag = 0
For y As Long = 0 To hitter._h-1
For x As Long = 0 To hitter._w-1
If Point(x, y, hitter._img(1)) <> _COLOR._BKG Then
If Point (x+hitter._x, y+hitter._y) <> _COLOR._BKG Then
hitflag = 1
'Rewind----------
hitter._x = hitter._x - hitter._dx
hitter._y = hitter._y - hitter._dy
xx = x + hitter._x
yy = y + hitter._y
End If
End If
Next x
Next y
' .-----.
' | A03 |
' .-----.
'Reflection---------------
Dim As POINT2D hitPoint
Dim As LINE2D tangent
Dim As LINE2D normal
Dim As Byte hitterRegion
Dim As Double normalOrientation
Dim As Double incidenceAngle
Dim As Double angleAfterRebounce
If hitflag = 1 Then
hitPoint._x = xx
hitPoint._y = yy
tangent = launcher.ReturnTangent( hitPoint )
normal = tangent.ReturnNormal()
'Compute hitter region relative to tangent
hitterRegion = Sgn(tangent.EvaluateAtPoint( hitPoint ))
If hitterRegion = 0 Then
'Fix this, since it could really be a problem
hitterRegion = +1 ''This is not a fix
EndIf
'Compute normal orientation angle
normalOrientation = ATan2(hitter._dy, hitter._dx) *57.2958
If hitterRegion = -1 Then
normalOrientation += 180
EndIf
'Compute angle between normal and approching hitter
incidenceAngle = approachAngle - normalOrientation
If Abs(incidenceAngle) > 90 Then incidenceAngle -= 90
'Find angle after rebounce
angleAfterRebounce = approachAngle - 2 * incidenceAngle
'Set dx, dy accordingly
hitter._dx = 0.5 * Cos(angleAfterRebounce)
hitter._dy = 0.5 * Sin(angleAfterRebounce)
EndIf
'-------------------------
' .-----.
' | A04 |
' .-----.
If hitflag = 1 Then 'compute angle2
PSet reducedHorseBuffer, (hitter._x - 120, hitter._y - 50), _COLOR._SP2
'Record hitpoint and reset
sightAngle += 10
With hitter
._x = (_RADIUS - 20) * Cos(sightAngle*_DTOR) + _SCRW\2
._y = (_RADIUS - 20) * Sin(sightAngle*_DTOR) + _SCRH\2
._dx = -(launcher._centerPoint._x - ._x)/(2*_RADIUS)
._dy = -(launcher._centerPoint._y - ._y)/(2*_RADIUS)
End With 'hitter
'(must be in a corner segment)
If takenflag = 0 Then
hitter._dx = -hitter._dx
hitter._dy = -hitter._dy
End If
End If
' .-----.
' | A05 |
' .-----.
Put (hitter._x, hitter._y), hitter._img(1),trans
Draw string (16,16),"PRESS ESC KEY TO EXIT DEMO"
Draw string (16,1), hitter._x & " " & hitter._y
ScreenUnLock
End Sub 'Update()
' .-----.
' | DAT |
' .-----.
'hitter DRAWING DATA
Hitter:
Data "####"
Data "####"
Data "####"
Data "####"
Data "####"
Data "#..#"
Data "#..#"
Data "####"
'Chastain's horse DRAWING DATA
Chastain:
Data 122,80,123,80,124,80,125,80,126,80,126,81,127,81,128,81,129,81,129,82,130,82
DATA 130,83,131,83,132,83,133,83,134,83,135,83,136,83,137,83,138,83,139,83,140,83
DATA 141,83,142,83,143,83,144,83,145,83,146,83,147,83,148,83,149,83,150,83,151,83
DATA 152,83,153,83,154,83,155,83,156,83,157,83,158,83,159,83,160,83,161,83,162,83
DATA 163,83,164,83,165,83,165,84,166,84,167,84,167,85,168,85,169,85,169,86,170,86
DATA 171,86,172,86,172,87,173,87,174,87,175,87,175,88,176,88,177,88,177,89,178,89
DATA 179,89,179,90,180,90,181,90,181,91,182,91,183,91,183,92,184,92,184,93,185,93
DATA 186,93,186,94,187,94,188,94,188,95,189,95,189,96,190,96,191,96,191,97,192,97
DATA 192,98,193,98,193,99,194,99,195,99,195,100,196,100,196,101,197,101,197,102,198,102
DATA 199,102,199,103,200,103,200,104,201,104,201,105,202,105,202,106,203,106,203,107,204,107
DATA 204,108,205,108,205,109,206,109,206,110,207,110,207,111,208,111,208,112,208,113,209,113
DATA 209,114,210,114,210,115,210,116,211,116,211,117,212,117,212,118,213,118,213,119,213,120
DATA 214,120,214,121,214,122,215,122,215,123,215,124,216,124,216,125,217,125,217,126,217,127
DATA 218,127,218,128,218,129,218,130,219,130,219,131,219,132,219,133,220,133,220,134,220,135
DATA 220,136,220,137,221,137,221,138,221,139,222,139,222,140,223,140,223,141,224,141,224,142
DATA 225,142,225,143,226,143,226,144,227,144,228,144,228,145,229,145,230,145,231,145,231,146
DATA 232,146,233,146,234,146,234,147,235,147,236,147,237,147,238,147,239,147,240,147,241,147
DATA 242,147,243,147,244,147,245,147,246,147,247,147,248,147,249,147,250,147,251,147,252,147
DATA 253,147,253,146,254,146,255,146,256,146,257,146,258,146,259,146,259,145,260,145,261,145
DATA 262,145,263,145,264,145,264,144,265,144,266,144,267,144,268,144,269,144,269,143,270,143
DATA 271,143,272,143,273,143,273,142,274,142,275,142,276,142,277,142,277,141,278,141,279,141
DATA 280,141,281,141,281,140,282,140,283,140,284,140,285,140,285,139,286,139,287,139,288,139
DATA 289,139,289,138,290,138,291,138,292,138,293,138,294,138,294,137,295,137,296,137,297,137
DATA 298,137,299,137,300,137,300,136,301,136,302,136,303,136,304,136,305,136,306,136,307,136
DATA 308,136,309,136,310,136,311,136,312,136,313,136,314,136,315,136,316,136,317,136,318,136
DATA 318,137,319,137,320,137,321,137,322,137,323,137,324,137,324,138,325,138,326,138,327,138
DATA 328,138,329,138,330,138,330,139,331,139,332,139,333,139,334,139,335,139,335,140,336,140
DATA 337,140,338,140,339,140,340,140,341,140,341,141,342,141,343,141,344,141,345,141,346,141
DATA 347,141,348,141,349,141,350,141,351,141,351,140,352,140,353,140,354,140,355,140,355,139
DATA 356,139,357,139,357,138,358,138,359,138,359,137,360,137,360,136,361,136,362,136,362,135
DATA 363,135,364,135,364,134,365,134,365,133,366,133,367,133,367,132,368,132,368,131,369,131
DATA 369,130,370,130,371,130,371,129,372,129,372,128,373,128,374,128,374,127,375,127,375,126
DATA 376,126,376,125,377,125,378,125,378,124,379,124,379,123,380,123,381,123,381,122,382,122
DATA 383,122,383,121,384,121,385,121,386,121,386,120,387,120,388,120,389,120,390,120,390,119
DATA 391,119,392,119,393,119,394,119,395,119,396,119,397,119,398,119,399,119,400,119,401,119
DATA 402,119,402,120,403,120,404,120,405,120,406,120,406,121,407,121,408,121,409,121,409,122
DATA 410,122,411,122,411,123,412,123,413,123,413,124,414,124,415,124,415,125,416,125,417,125
DATA 417,126,418,126,418,127,419,127,419,128,420,128,420,129,421,129,422,129,422,130,423,130
DATA 423,131,424,131,424,132,425,132,425,133,426,133,426,134,427,134,427,135,427,136,427,137
DATA 428,137,428,138,428,139,428,140,429,140,429,141,429,142,429,143,429,144,429,145,429,146
DATA 430,146,430,147,430,148,430,149,430,150,430,151,430,152,430,153,431,153,431,154,431,155
DATA 431,156,431,157,431,158,431,159,431,160,432,160,432,161,432,162,432,163,432,164,432,165
DATA 432,166,432,167,432,168,433,168,433,169,433,170,433,171,433,172,433,173,433,174,433,175
DATA 433,176,433,177,433,178,433,179,433,180,433,181,433,182,433,183,433,184,433,185,433,186
DATA 433,187,433,188,432,188,432,189,432,190,432,191,431,191,431,192,431,193,430,193,430,194
DATA 430,195,429,195,429,196,429,197,428,197,428,198,428,199,427,199,427,200,427,201,426,201
DATA 426,202,426,203,425,203,425,204,425,205,424,205,424,206,424,207,423,207,423,208,423,209
DATA 422,209,422,210,422,211,421,211,421,212,420,212,420,213,420,214,419,214,419,215,419,216
DATA 418,216,418,217,418,218,417,218,417,219,417,220,416,220,416,221,415,221,415,222,415,223
DATA 414,223,414,224,414,225,413,225,413,226,412,226,412,227,412,228,411,228,411,229,411,230
DATA 410,230,410,231,409,231,409,232,409,233,408,233,408,234,408,235,407,235,407,236,406,236
DATA 406,237,406,238,405,238,405,239,404,239,404,240,404,241,403,241,403,242,402,242,402,243
DATA 402,244,401,244,401,245,400,245,400,246,400,247,399,247,399,248,398,248,398,249,398,250
DATA 397,250,397,251,396,251,396,252,396,253,395,253,395,254,394,254,394,255,394,256,393,256
DATA 393,257,393,258,392,258,392,259,392,260,391,260,391,261,391,262,390,262,390,263,390,264
DATA 389,264,389,265,389,266,388,266,388,267,387,267,387,268,387,269,387,270,387,271,387,272
DATA 387,273,387,274,387,275,387,276,387,277,387,278,387,279,387,280,387,281,387,282,387,283
DATA 387,284,387,285,387,286,387,287,387,288,388,288,388,289,388,290,388,291,388,292,388,293
DATA 388,294,388,295,388,296,387,296,387,297,386,297,386,296,385,296,384,296,384,295,383,295
DATA 382,295,382,294,381,294,381,293,380,293,380,292,379,292,379,291,379,290,378,290,378,289
DATA 377,289,377,288,377,287,376,287,376,286,376,285,376,284,375,284,375,283,375,282,375,281
DATA 374,281,374,280,374,279,374,278,374,277,374,276,373,276,373,275,373,274,373,273,373,272
DATA 373,271,373,270,373,269,373,268,373,267,373,266,373,265,373,264,373,263,373,262,373,261
DATA 373,260,373,259,373,258,373,257,373,256,373,255,373,254,373,253,373,252,373,251,374,251
DATA 374,250,374,249,374,248,374,247,374,246,374,245,374,244,375,244,375,243,375,242,375,241
DATA 375,240,375,239,376,239,376,238,376,237,376,236,377,236,377,235,377,234,377,233,378,233
DATA 378,232,378,231,379,231,379,230,379,229,380,229,380,228,380,227,381,227,381,226,381,225
DATA 381,224,382,224,382,223,382,222,383,222,383,221,383,220,384,220,384,219,385,219,385,218
DATA 385,217,386,217,386,216,386,215,387,215,387,214,387,213,387,212,388,212,388,211,388,210
DATA 389,210,389,209,389,208,390,208,390,207,390,206,391,206,391,205,391,204,392,204,392,203
DATA 392,202,392,201,393,201,393,200,393,199,393,198,394,198,394,197,394,196,394,195,394,194
DATA 394,193,394,192,394,191,394,190,395,190,395,189,395,188,395,187,395,186,395,185,395,184
DATA 394,184,394,183,394,182,394,181,394,180,394,179,394,178,394,177,394,176,393,176,393,175
DATA 393,174,393,173,393,172,392,172,392,171,392,170,392,169,391,169,391,168,391,167,390,167
DATA 390,166,390,165,389,165,389,164,388,164,388,163,388,162,387,162,387,161,386,161,386,160
DATA 385,160,385,159,384,159,383,159,383,158,382,158,381,158,381,157,380,157,379,157,378,157
DATA 378,156,377,156,376,156,375,156,375,155,374,155,373,155,372,155,371,155,370,155,369,155
DATA 369,154,368,154,367,154,366,154,365,154,364,154,363,154,362,154,361,154,360,154,359,154
DATA 358,154,357,154,356,154,355,154,354,154,353,154,353,155,353,156,353,157,354,157,354,158
DATA 354,159,355,159,355,160,355,161,356,161,356,162,356,163,356,164,357,164,357,165,357,166
DATA 358,166,358,167,358,168,359,168,359,169,359,170,359,171,360,171,360,172,360,173,361,173
DATA 361,174,361,175,361,176,362,176,362,177,362,178,362,179,363,179,363,180,363,181,363,182
DATA 364,182,364,183,364,184,364,185,364,186,364,187,365,187,365,188,365,189,365,190,365,191
DATA 365,192,365,193,365,194,365,195,365,196,365,197,365,198,365,199,365,200,365,201,365,202
DATA 365,203,365,204,364,204,364,205,364,206,364,207,364,208,363,208,363,209,363,210,362,210
DATA 362,211,362,212,361,212,361,213,361,214,361,215,360,215,360,216,359,216,359,217,359,218
DATA 358,218,358,219,357,219,357,220,356,220,356,221,355,221,355,222,355,223,354,223,354,224
DATA 353,224,353,225,352,225,352,226,351,226,351,227,350,227,350,228,349,228,349,229,348,229
DATA 348,230,347,230,346,230,346,231,345,231,345,232,344,232,344,233,343,233,343,234,342,234
DATA 342,235,341,235,341,236,340,236,339,236,339,237,338,237,338,238,337,238,337,239,336,239
DATA 336,240,335,240,335,241,334,241,334,242,333,242,333,243,332,243,332,244,331,244,331,245
DATA 330,245,330,246,329,246,329,247,329,248,329,249,329,250,329,251,330,251,330,252,330,253
DATA 331,253,331,254,331,255,331,256,332,256,332,257,333,257,333,258,333,259,334,259,334,260
DATA 335,260,335,261,336,261,336,262,336,263,337,263,337,264,338,264,338,265,339,265,339,266
DATA 339,267,340,267,340,268,341,268,341,269,341,270,342,270,342,271,342,272,343,272,343,273
DATA 344,273,344,274,344,275,344,276,345,276,345,277,345,278,345,279,345,280,345,281,345,282
DATA 345,283,345,284,344,284,344,285,344,286,343,286,343,287,343,288,342,288,342,289,341,289
DATA 341,290,341,291,340,291,340,292,339,292,339,293,338,293,338,294,337,294,337,295,336,295
DATA 336,296,335,296,335,297,334,297,334,298,333,298,333,299,332,299,332,300,331,300,331,301
DATA 330,301,330,302,329,302,329,303,328,303,328,304,327,304,326,304,326,305,325,305,325,306
DATA 324,306,324,307,323,307,323,308,322,308,322,309,321,309,321,310,320,310,320,311,319,311
DATA 319,312,318,312,318,313,318,314,317,314,317,315,316,315,316,316,315,316,315,317,315,318
DATA 314,318,314,319,313,319,313,320,313,321,312,321,312,322,312,323,311,323,311,324,310,324
DATA 310,325,310,326,309,326,309,327,309,328,308,328,308,329,307,329,307,330,306,330,306,331
DATA 306,332,305,332,305,333,304,333,304,334,303,334,303,335,302,335,302,336,301,336,300,336
DATA 300,337,299,337,298,337,297,337,297,338,296,338,295,338,295,339,294,339,293,339,293,340
DATA 292,340,292,341,291,341,291,342,291,343,290,343,290,344,290,345,290,346,289,346,289,347
DATA 289,348,288,348,288,349,287,349,287,350,286,350,285,350,284,350,283,350,282,350,281,350
DATA 280,350,279,350,278,350,277,350,276,350,275,350,275,349,274,349,273,349,272,349,271,349
DATA 271,348,270,348,269,348,269,347,268,347,267,347,267,346,266,346,265,346,265,345,265,344
DATA 265,343,266,343,266,342,266,341,267,341,267,340,267,339,268,339,268,338,269,338,269,337
DATA 270,337,270,336,271,336,271,335,272,335,272,334,273,334,274,334,274,333,275,333,276,333
DATA 276,332,277,332,277,331,278,331,279,331,279,330,280,330,281,330,282,330,282,329,283,329
DATA 283,328,284,328,285,328,285,327,286,327,287,327,287,326,288,326,288,325,289,325,290,325
DATA 290,324,291,324,291,323,292,323,292,322,293,322,293,321,294,321,294,320,295,320,295,319
DATA 296,319,296,318,296,317,297,317,297,316,298,316,298,315,299,315,299,314,300,314,300,313
DATA 300,312,301,312,301,311,302,311,302,310,303,310,303,309,304,309,304,308,305,308,305,307
DATA 305,306,306,306,306,305,307,305,307,304,308,304,308,303,309,303,309,302,309,301,310,301
DATA 310,300,311,300,311,299,312,299,312,298,313,298,313,297,314,297,314,296,314,295,315,295
DATA 315,294,316,294,316,293,317,293,317,292,317,291,318,291,318,290,319,290,319,289,319,288
DATA 319,287,320,287,320,286,320,285,320,284,320,283,320,282,320,281,319,281,319,280,319,279
DATA 319,278,318,278,318,277,318,276,317,276,317,275,317,274,316,274,316,273,316,272,315,272
DATA 315,271,314,271,313,271,313,272,312,272,312,273,312,274,312,275,312,276,311,276,311,277
DATA 311,278,310,278,310,279,310,280,310,281,309,281,309,282,308,282,308,283,308,284,307,284
DATA 307,285,306,285,306,286,305,286,305,287,304,287,304,288,304,289,303,289,303,290,302,290
DATA 301,290,301,291,300,291,300,292,299,292,299,293,298,293,298,294,297,294,297,295,296,295
DATA 296,296,295,296,295,297,294,297,294,298,293,298,293,299,292,299,292,300,291,300,291,301
DATA 290,301,290,302,289,302,289,303,289,304,288,304,288,305,287,305,287,306,286,306,286,307
DATA 286,308,285,308,285,309,284,309,284,310,284,311,283,311,283,312,282,312,282,313,282,314
DATA 281,314,281,315,281,316,280,316,280,317,279,317,279,318,279,319,278,319,278,320,278,321
DATA 277,321,277,322,276,322,276,323,276,324,275,324,275,325,275,326,274,326,274,327,273,327
DATA 273,328,273,329,272,329,272,330,271,330,271,331,271,332,270,332,270,333,269,333,269,334
DATA 268,334,268,335,267,335,267,336,267,337,266,337,266,338,265,338,265,339,264,339,264,340
DATA 263,340,263,341,262,341,261,341,261,342,260,342,260,343,259,343,259,344,258,344,257,344
DATA 257,345,256,345,256,346,255,346,254,346,254,347,253,347,252,347,252,348,252,349,252,350
DATA 251,350,251,351,251,352,250,352,249,352,248,352,247,352,246,352,245,352,244,352,243,352
DATA 242,352,241,352,240,352,239,352,238,352,237,352,236,352,235,352,234,352,233,352,232,352
DATA 231,352,230,352,229,352,228,352,227,352,226,352,225,352,225,351,226,351,226,350,226,349
DATA 227,349,227,348,228,348,228,347,229,347,229,346,230,346,230,345,231,345,231,344,232,344
DATA 232,343,233,343,233,342,234,342,234,341,235,341,235,340,236,340,237,340,237,339,238,339
DATA 238,338,239,338,239,337,240,337,240,336,241,336,241,335,242,335,243,335,243,334,244,334
DATA 244,333,245,333,245,332,246,332,246,331,247,331,248,331,248,330,249,330,249,329,250,329
DATA 251,329,251,328,252,328,252,327,253,327,254,327,254,326,255,326,255,325,256,325,257,325
DATA 257,324,258,324,258,323,259,323,259,322,260,322,260,321,261,321,261,320,262,320,262,319
DATA 263,319,263,318,263,317,264,317,264,316,265,316,265,315,266,315,266,314,267,314,267,313
DATA 267,312,268,312,268,311,269,311,269,310,270,310,270,309,271,309,271,308,271,307,272,307
DATA 272,306,273,306,273,305,274,305,274,304,274,303,275,303,275,302,276,302,276,301,277,301
DATA 277,300,277,299,278,299,278,298,279,298,279,297,279,296,280,296,280,295,280,294,281,294
DATA 281,293,281,292,282,292,282,291,282,290,282,289,283,289,283,288,283,287,284,287,284,286
DATA 284,285,284,284,284,283,284,282,284,281,284,280,284,279,284,278,284,277,284,276,284,275
DATA 283,275,283,274,282,274,282,273,282,272,281,272,281,271,281,270,280,270,280,269,279,269
DATA 279,268,279,267,278,267,278,266,277,266,277,265,277,264,276,264,276,263,275,263,275,262
DATA 275,261,274,261,274,260,273,260,273,259,273,258,272,258,272,257,271,257,271,256,271,255
DATA 270,255,270,254,269,254,269,253,269,252,268,252,267,252,267,251,266,251,266,250,265,250
DATA 265,249,264,249,264,248,263,248,262,248,262,247,261,247,260,247,260,246,259,246,259,245
DATA 258,245,257,245,256,245,255,245,254,245,253,245,252,245,251,245,250,245,250,246,249,246
DATA 248,246,247,246,247,247,246,247,245,247,244,247,244,248,243,248,242,248,241,248,241,249
DATA 240,249,239,249,238,249,237,249,237,250,236,250,235,250,234,250,233,250,232,250,231,250
DATA 230,250,229,250,228,250,228,251,227,251,226,251,225,251,224,251,223,251,222,251,221,251
DATA 220,251,219,251,218,251,217,251,216,251,215,251,214,251,213,251,212,251,211,251,210,251
DATA 209,251,208,251,207,251,206,251,205,251,204,251,203,251,202,251,201,251,200,251,199,251
DATA 199,252,198,252,198,253,197,253,197,254,197,255,196,255,196,256,195,256,195,257,194,257
DATA 194,258,194,259,193,259,193,260,192,260,192,261,191,261,191,262,191,263,190,263,190,264
DATA 189,264,189,265,189,266,188,266,188,267,187,267,187,268,187,269,186,269,186,270,185,270
DATA 185,271,185,272,184,272,184,273,183,273,183,274,183,275,182,275,182,276,181,276,181,277
DATA 181,278,180,278,180,279,180,280,179,280,179,281,178,281,178,282,178,283,177,283,177,284
DATA 177,285,176,285,176,286,176,287,175,287,175,288,174,288,174,289,174,290,173,290,173,291
DATA 173,292,172,292,172,293,172,294,171,294,171,295,171,296,170,296,170,297,170,298,169,298
DATA 169,299,169,300,168,300,168,301,168,302,167,302,167,303,167,304,166,304,166,305,166,306
DATA 166,307,165,307,165,308,165,309,164,309,164,310,164,311,164,312,163,312,163,313,163,314
DATA 162,314,162,315,162,316,162,317,161,317,161,318,161,319,161,320,160,320,160,321,160,322
DATA 160,323,159,323,159,324,159,325,159,326,158,326,158,327,158,328,158,329,157,329,157,330
DATA 157,331,157,332,157,333,156,333,156,334,156,335,156,336,156,337,155,337,155,338,155,339
DATA 155,340,155,341,155,342,154,342,154,343,154,344,154,345,154,346,153,346,153,347,153,348
DATA 153,349,152,349,152,350,152,351,151,351,151,352,150,352,149,352,148,352,147,352,146,352
DATA 145,352,144,352,143,352,142,352,141,352,140,352,139,352,138,352,137,352,136,352,135,352
DATA 134,352,133,352,132,352,131,352,130,352,129,352,128,352,127,352,126,352,125,352,124,352
DATA 123,352,122,352,121,352,120,352,119,352,118,352,117,352,116,352,116,351,117,351,118,351
DATA 118,350,119,350,119,349,120,349,121,349,121,348,122,348,123,348,123,347,124,347,124,346
DATA 125,346,126,346,126,345,127,345,128,345,128,344,129,344,130,344,130,343,131,343,132,343
DATA 132,342,133,342,133,341,134,341,135,341,135,340,136,340,136,339,137,339,137,338,138,338
DATA 138,337,138,336,139,336,139,335,140,335,140,334,140,333,141,333,141,332,141,331,142,331
DATA 142,330,142,329,142,328,143,328,143,327,143,326,144,326,144,325,144,324,144,323,145,323
DATA 145,322,145,321,145,320,145,319,146,319,146,318,146,317,146,316,147,316,147,315,147,314
DATA 147,313,147,312,148,312,148,311,148,310,148,309,148,308,149,308,149,307,149,306,149,305
DATA 149,304,149,303,150,303,150,302,150,301,150,300,150,299,151,299,151,298,151,297,151,296
DATA 151,295,151,294,152,294,152,293,152,292,152,291,152,290,153,290,153,289,153,288,153,287
DATA 154,287,154,286,155,286,155,285,155,284,156,284,156,283,156,282,157,282,157,281,157,280
DATA 158,280,158,279,158,278,159,278,159,277,159,276,159,275,160,275,160,274,160,273,161,273
DATA 161,272,161,271,161,270,162,270,162,269,162,268,163,268,163,267,163,266,163,265,164,265
DATA 164,264,164,263,165,263,165,262,165,261,165,260,166,260,166,259,166,258,167,258,167,257
DATA 167,256,167,255,168,255,168,254,168,253,169,253,169,252,169,251,170,251,170,250,170,249
DATA 171,249,171,248,171,247,172,247,172,246,171,246,170,246,170,245,169,245,169,246,168,246
DATA 167,246,166,246,166,247,165,247,164,247,164,248,163,248,162,248,161,248,161,249,160,249
DATA 159,249,158,249,158,250,157,250,156,250,155,250,154,250,153,250,152,250,151,250,150,250
DATA 150,251,149,251,148,251,147,251,146,251,145,251,144,251,143,251,142,251,141,251,140,251
DATA 139,251,138,251,137,251,136,251,135,251,134,251,133,251,132,251,131,251,130,251,129,251
DATA 128,251,127,251,126,251,125,251,124,251,123,251,122,251,121,251,120,251,119,251,118,251
DATA 117,251,116,251,115,251,114,251,113,251,112,251,111,251,110,251,109,251,108,251,107,251
DATA 106,251,105,251,104,251,103,251,103,252,102,252,102,253,101,253,101,254,100,254,100,255
DATA 100,256,99,256,99,257,99,258,98,258,98,259,98,260,98,261,97,261,97,262,98,262
DATA 98,263,98,264,98,265,98,266,99,266,99,267,99,268,100,268,100,269,100,270,101,270
DATA 101,271,101,272,102,272,102,273,103,273,103,274,103,275,104,275,104,276,105,276,105,277
DATA 106,277,106,278,107,278,107,279,108,279,108,280,109,280,109,281,110,281,110,282,111,282
DATA 112,282,112,283,113,283,113,284,114,284,115,284,115,285,116,285,116,286,117,286,117,287
DATA 118,287,119,287,119,288,120,288,120,289,121,289,122,289,122,290,123,290,123,291,124,291
DATA 124,292,125,292,125,293,126,293,127,293,127,294,128,294,128,295,129,295,130,295,131,295
DATA 132,295,132,296,133,296,134,296,135,296,135,297,136,297,137,297,138,297,139,297,139,298
DATA 140,298,141,298,141,299,142,299,142,300,142,301,143,301,143,302,143,303,144,303,144,304
DATA 144,305,144,306,144,307,144,308,144,309,144,310,144,311,144,312,143,312,143,313,143,314
DATA 143,315,142,315,142,316,141,316,141,317,140,317,140,318,139,318,139,319,138,319,137,319
DATA 136,319,135,319,134,319,133,319,133,318,132,318,131,318,131,317,130,317,130,316,129,316
DATA 129,315,128,315,128,314,127,314,126,314,126,313,125,313,125,312,124,312,124,311,123,311
DATA 123,310,122,310,121,310,121,309,120,309,120,308,119,308,119,307,118,307,117,307,117,306
DATA 116,306,116,305,115,305,114,305,114,304,113,304,112,304,112,303,111,303,110,303,110,302
DATA 109,302,109,301,108,301,107,301,107,300,106,300,106,299,105,299,105,298,105,297,104,297
DATA 104,296,103,296,103,295,102,295,102,294,102,293,101,293,101,292,100,292,100,291,99,291
DATA 99,290,98,290,98,289,98,288,97,288,97,287,96,287,96,286,95,286,95,285,95,284
DATA 94,284,94,283,93,283,93,282,92,282,92,281,92,280,91,280,91,279,90,279,90,278
DATA 89,278,89,277,89,276,88,276,88,275,87,275,87,274,86,274,86,273,86,272,85,272
DATA 85,271,84,271,84,270,83,270,83,269,83,268,82,268,82,267,81,267,81,266,81,265
DATA 80,265,80,264,79,264,79,263,79,262,78,262,78,261,78,260,78,259,78,258,78,257
DATA 78,256,78,255,78,254,78,253,78,252,79,252,79,251,79,250,79,249,79,248,80,248
DATA 80,247,80,246,81,246,81,245,81,244,82,244,82,243,83,243,83,242,84,242,84,241
DATA 85,241,85,240,86,240,86,239,87,239,88,239,88,238,89,238,90,238,90,237,91,237
DATA 92,237,92,236,93,236,94,236,95,236,95,235,96,235,97,235,98,235,98,234,99,234
DATA 100,234,101,234,102,234,102,233,103,233,104,233,105,233,105,232,106,232,107,232,108,232
DATA 108,231,109,231,110,231,111,231,111,230,112,230,113,230,114,230,114,229,115,229,116,229
DATA 117,229,118,229,118,228,119,228,120,228,121,228,121,227,122,227,123,227,124,227,124,226
DATA 125,226,126,226,126,225,127,225,127,224,127,223,126,223,126,222,126,221,126,220,126,219
DATA 125,219,125,218,125,217,125,216,125,215,125,214,124,214,124,213,124,212,124,211,124,210
DATA 124,209,124,208,124,207,124,206,124,205,124,204,124,203,124,202,125,202,125,201,125,200
DATA 125,199,126,199,126,198,126,197,127,197,127,196,127,195,127,194,128,194,128,193,129,193
DATA 129,192,129,191,130,191,130,190,131,190,131,189,131,188,132,188,132,187,133,187,133,186
DATA 133,185,134,185,134,184,135,184,135,183,135,182,136,182,136,181,136,180,137,180,137,179
DATA 138,179,138,178,138,177,139,177,139,176,139,175,140,175,140,174,140,173,141,173,141,172
DATA 141,171,141,170,142,170,142,169,142,168,142,167,142,166,143,166,143,165,143,164,143,163
DATA 143,162,143,161,143,160,143,159,143,158,143,157,143,156,143,155,143,154,142,154,142,153
DATA 142,152,142,151,142,150,142,149,141,149,141,148,141,147,141,146,140,146,140,145,140,144
DATA 139,144,139,143,139,142,138,142,138,141,138,140,137,140,137,139,136,139,136,138,135,138
DATA 134,138,134,139,133,139,132,139,132,140,131,140,130,140,130,141,129,141,128,141,128,142
DATA 127,142,126,142,126,143,125,143,125,144,124,144,123,144,123,145,122,145,122,146,121,146
DATA 121,147,120,147,119,147,119,148,118,148,118,149,118,150,117,150,117,151,117,152,116,152
DATA 116,153,116,154,116,155,116,156,116,157,115,157,115,158,115,159,115,160,115,161,115,162
DATA 115,163,115,164,115,165,114,165,114,166,113,166,113,167,112,167,112,168,111,168,110,168
DATA 109,168,109,169,108,169,107,169,106,169,105,169,104,169,103,169,102,169,101,169,100,169
DATA 99,169,99,168,98,168,97,168,96,168,95,168,95,167,94,167,93,167,93,166,92,166
DATA 91,166,91,165,90,165,90,164,89,164,88,164,88,163,88,162,87,162,87,161,87,160
DATA 87,159,87,158,86,158,86,157,86,156,86,155,86,154,86,153,86,152,86,151,86,150
DATA 86,149,86,148,86,147,86,146,86,145,86,144,86,143,86,142,86,141,86,140,86,139
DATA 86,138,86,137,86,136,86,135,87,135,87,134,88,134,88,133,88,132,89,132,89,131
DATA 90,131,90,130,90,129,90,128,91,128,91,127,91,126,91,125,92,125,92,124,92,123
DATA 92,122,92,121,92,120,93,120,93,119,93,118,93,117,93,116,93,115,93,114,93,113
DATA 93,112,93,111,93,110,93,109,94,109,94,108,94,107,94,106,94,105,94,104,94,103
DATA 94,102,95,102,95,101,95,100,95,99,95,98,96,98,96,97,96,96,97,96,97,95
DATA 98,95,98,94,99,94,99,93,100,93,100,92,101,92,101,91,102,91,102,90,103,90
DATA 103,89,104,89,105,89,105,88,106,88,106,87,107,87,108,87,108,86,109,86,110,86
DATA 110,85,111,85,111,84,112,84,113,84,113,83,114,83,115,83,116,83,116,82,117,82
DATA 118,82,118,81,119,81,120,81,121,81,122,81,122,80
'"-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
'"-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-