diff options
author | Melanie Thielker | 2010-07-14 19:58:23 +0200 |
---|---|---|
committer | Melanie Thielker | 2010-07-14 19:58:23 +0200 |
commit | bebbe407ee166a0aa22f0ec8d14ada780924f9af (patch) | |
tree | 79e38927939a6e95ff4ff105b357a8d3888a67b8 /OpenSim | |
parent | Remove useless quaternion parameter from AttachObject sig (diff) | |
download | opensim-SC_OLD-bebbe407ee166a0aa22f0ec8d14ada780924f9af.zip opensim-SC_OLD-bebbe407ee166a0aa22f0ec8d14ada780924f9af.tar.gz opensim-SC_OLD-bebbe407ee166a0aa22f0ec8d14ada780924f9af.tar.bz2 opensim-SC_OLD-bebbe407ee166a0aa22f0ec8d14ada780924f9af.tar.xz |
Major attachments cleanup. Remove unused AttachObject ClientView method
Clean up use of AttachObject throughout, reduce number of overloads
and number of parameters
Diffstat (limited to 'OpenSim')
13 files changed, 49 insertions, 123 deletions
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 5798a64..ce2e9a1 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs | |||
@@ -1047,11 +1047,6 @@ namespace OpenSim.Client.MXP.ClientStack | |||
1047 | // Minimap function, not used. | 1047 | // Minimap function, not used. |
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||
1051 | { | ||
1052 | // Need to translate to MXP somehow | ||
1053 | } | ||
1054 | |||
1055 | public void SetChildAgentThrottle(byte[] throttle) | 1050 | public void SetChildAgentThrottle(byte[] throttle) |
1056 | { | 1051 | { |
1057 | // Need to translate to MXP somehow | 1052 | // Need to translate to MXP somehow |
diff --git a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs index 906947e..2063616 100644 --- a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs +++ b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs | |||
@@ -602,11 +602,6 @@ namespace OpenSim.Client.Sirikata.ClientStack | |||
602 | throw new System.NotImplementedException(); | 602 | throw new System.NotImplementedException(); |
603 | } | 603 | } |
604 | 604 | ||
605 | public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||
606 | { | ||
607 | throw new System.NotImplementedException(); | ||
608 | } | ||
609 | |||
610 | public void SetChildAgentThrottle(byte[] throttle) | 605 | public void SetChildAgentThrottle(byte[] throttle) |
611 | { | 606 | { |
612 | throw new System.NotImplementedException(); | 607 | throw new System.NotImplementedException(); |
diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index 13a27f5..841f9a4 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs | |||
@@ -608,11 +608,6 @@ namespace OpenSim.Client.VWoHTTP.ClientStack | |||
608 | throw new System.NotImplementedException(); | 608 | throw new System.NotImplementedException(); |
609 | } | 609 | } |
610 | 610 | ||
611 | public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||
612 | { | ||
613 | throw new System.NotImplementedException(); | ||
614 | } | ||
615 | |||
616 | public void SetChildAgentThrottle(byte[] throttle) | 611 | public void SetChildAgentThrottle(byte[] throttle) |
617 | { | 612 | { |
618 | throw new System.NotImplementedException(); | 613 | throw new System.NotImplementedException(); |
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 100c861..95aec94 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -1019,7 +1019,6 @@ namespace OpenSim.Framework | |||
1019 | 1019 | ||
1020 | void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations); | 1020 | void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations); |
1021 | 1021 | ||
1022 | void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID); | ||
1023 | void SetChildAgentThrottle(byte[] throttle); | 1022 | void SetChildAgentThrottle(byte[] throttle); |
1024 | 1023 | ||
1025 | void SendAvatarDataImmediate(ISceneEntity avatar); | 1024 | void SendAvatarDataImmediate(ISceneEntity avatar); |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 82b9958..754127d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -3687,30 +3687,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3687 | 3687 | ||
3688 | #endregion Primitive Packet/Data Sending Methods | 3688 | #endregion Primitive Packet/Data Sending Methods |
3689 | 3689 | ||
3690 | /// <summary> | ||
3691 | /// | ||
3692 | /// </summary> | ||
3693 | /// <param name="localID"></param> | ||
3694 | /// <param name="rotation"></param> | ||
3695 | /// <param name="attachPoint"></param> | ||
3696 | public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||
3697 | { | ||
3698 | if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD | ||
3699 | return; | ||
3700 | |||
3701 | ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach); | ||
3702 | // TODO: don't create new blocks if recycling an old packet | ||
3703 | attach.AgentData.AgentID = AgentId; | ||
3704 | attach.AgentData.SessionID = m_sessionId; | ||
3705 | attach.AgentData.AttachmentPoint = attachPoint; | ||
3706 | attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1]; | ||
3707 | attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock(); | ||
3708 | attach.ObjectData[0].ObjectLocalID = localID; | ||
3709 | attach.ObjectData[0].Rotation = rotation; | ||
3710 | attach.Header.Zerocoded = true; | ||
3711 | OutPacket(attach, ThrottleOutPacketType.Task); | ||
3712 | } | ||
3713 | |||
3714 | void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) | 3690 | void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) |
3715 | { | 3691 | { |
3716 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) | 3692 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 08b2315..902fb88 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -71,6 +71,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
71 | get { return false; } | 71 | get { return false; } |
72 | } | 72 | } |
73 | 73 | ||
74 | // Called by client | ||
75 | // | ||
74 | public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) | 76 | public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) |
75 | { | 77 | { |
76 | m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); | 78 | m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); |
@@ -86,7 +88,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
86 | return; | 88 | return; |
87 | 89 | ||
88 | // Calls attach with a Zero position | 90 | // Calls attach with a Zero position |
89 | if (AttachObject(remoteClient, objectLocalID, AttachmentPt, Vector3.Zero, false)) | 91 | if (AttachObject(remoteClient, part.ParentGroup, AttachmentPt, false)) |
90 | { | 92 | { |
91 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); | 93 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); |
92 | 94 | ||
@@ -108,72 +110,64 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
108 | } | 110 | } |
109 | } | 111 | } |
110 | 112 | ||
111 | public bool AttachObject( | 113 | public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent) |
112 | IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Vector3 attachPos, bool silent) | ||
113 | { | 114 | { |
114 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); | 115 | Vector3 attachPos = group.AbsolutePosition; |
115 | if (group != null) | 116 | |
117 | if (m_scene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) | ||
116 | { | 118 | { |
117 | if (m_scene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) | 119 | // If the attachment point isn't the same as the one previously used |
120 | // set it's offset position = 0 so that it appears on the attachment point | ||
121 | // and not in a weird location somewhere unknown. | ||
122 | if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) | ||
118 | { | 123 | { |
119 | // If the attachment point isn't the same as the one previously used | 124 | attachPos = Vector3.Zero; |
120 | // set it's offset position = 0 so that it appears on the attachment point | 125 | } |
121 | // and not in a weird location somewhere unknown. | ||
122 | if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) | ||
123 | { | ||
124 | attachPos = Vector3.Zero; | ||
125 | } | ||
126 | |||
127 | // AttachmentPt 0 means the client chose to 'wear' the attachment. | ||
128 | if (AttachmentPt == 0) | ||
129 | { | ||
130 | // Check object for stored attachment point | ||
131 | AttachmentPt = (uint)group.GetAttachmentPoint(); | ||
132 | } | ||
133 | |||
134 | // if we still didn't find a suitable attachment point....... | ||
135 | if (AttachmentPt == 0) | ||
136 | { | ||
137 | // Stick it on left hand with Zero Offset from the attachment point. | ||
138 | AttachmentPt = (uint)AttachmentPoint.LeftHand; | ||
139 | attachPos = Vector3.Zero; | ||
140 | } | ||
141 | 126 | ||
142 | group.SetAttachmentPoint((byte)AttachmentPt); | 127 | // AttachmentPt 0 means the client chose to 'wear' the attachment. |
143 | group.AbsolutePosition = attachPos; | 128 | if (AttachmentPt == 0) |
129 | { | ||
130 | // Check object for stored attachment point | ||
131 | AttachmentPt = (uint)group.GetAttachmentPoint(); | ||
132 | } | ||
144 | 133 | ||
145 | // Saves and gets itemID | 134 | // if we still didn't find a suitable attachment point....... |
146 | UUID itemId; | 135 | if (AttachmentPt == 0) |
136 | { | ||
137 | // Stick it on left hand with Zero Offset from the attachment point. | ||
138 | AttachmentPt = (uint)AttachmentPoint.LeftHand; | ||
139 | attachPos = Vector3.Zero; | ||
140 | } | ||
147 | 141 | ||
148 | if (group.GetFromItemID() == UUID.Zero) | 142 | group.SetAttachmentPoint((byte)AttachmentPt); |
149 | { | 143 | group.AbsolutePosition = attachPos; |
150 | m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); | ||
151 | } | ||
152 | else | ||
153 | { | ||
154 | itemId = group.GetFromItemID(); | ||
155 | } | ||
156 | 144 | ||
157 | SetAttachmentInventoryStatus(remoteClient, AttachmentPt, itemId, group); | 145 | // Saves and gets itemID |
146 | UUID itemId; | ||
158 | 147 | ||
159 | group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); | 148 | if (group.GetFromItemID() == UUID.Zero) |
160 | 149 | { | |
161 | // In case it is later dropped again, don't let | 150 | m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); |
162 | // it get cleaned up | ||
163 | group.RootPart.RemFlag(PrimFlags.TemporaryOnRez); | ||
164 | group.HasGroupChanged = false; | ||
165 | } | 151 | } |
166 | else | 152 | else |
167 | { | 153 | { |
168 | remoteClient.SendAgentAlertMessage( | 154 | itemId = group.GetFromItemID(); |
169 | "You don't have sufficient permissions to attach this object", false); | ||
170 | |||
171 | return false; | ||
172 | } | 155 | } |
156 | |||
157 | SetAttachmentInventoryStatus(remoteClient, AttachmentPt, itemId, group); | ||
158 | |||
159 | group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); | ||
160 | |||
161 | // In case it is later dropped again, don't let | ||
162 | // it get cleaned up | ||
163 | group.RootPart.RemFlag(PrimFlags.TemporaryOnRez); | ||
164 | group.HasGroupChanged = false; | ||
173 | } | 165 | } |
174 | else | 166 | else |
175 | { | 167 | { |
176 | m_log.DebugFormat("[ATTACHMENTS MODULE]: AttachObject found no such scene object {0}", objectLocalID); | 168 | remoteClient.SendAgentAlertMessage( |
169 | "You don't have sufficient permissions to attach this object", false); | ||
170 | |||
177 | return false; | 171 | return false; |
178 | } | 172 | } |
179 | 173 | ||
@@ -245,8 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
245 | if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) | 239 | if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) |
246 | tainted = true; | 240 | tainted = true; |
247 | 241 | ||
248 | AttachObject( | 242 | AttachObject(remoteClient, objatt, AttachmentPt, false); |
249 | remoteClient, objatt.LocalId, AttachmentPt, objatt.AbsolutePosition, false); | ||
250 | //objatt.ScheduleGroupForFullUpdate(); | 243 | //objatt.ScheduleGroupForFullUpdate(); |
251 | 244 | ||
252 | if (tainted) | 245 | if (tainted) |
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 8ec5bb5..4db8f9e 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | |||
@@ -536,10 +536,6 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
536 | { | 536 | { |
537 | } | 537 | } |
538 | 538 | ||
539 | public virtual void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||
540 | { | ||
541 | } | ||
542 | |||
543 | public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) | 539 | public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) |
544 | { | 540 | { |
545 | } | 541 | } |
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 11887e6..9fe6d96 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs | |||
@@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Interfaces | |||
58 | /// <param name="silent"></param> | 58 | /// <param name="silent"></param> |
59 | /// <returns>true if the object was successfully attached, false otherwise</returns> | 59 | /// <returns>true if the object was successfully attached, false otherwise</returns> |
60 | bool AttachObject( | 60 | bool AttachObject( |
61 | IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Vector3 attachPos, bool silent); | 61 | IClientAPI remoteClient, SceneObjectGroup grp, uint AttachmentPt, bool silent); |
62 | 62 | ||
63 | /// <summary> | 63 | /// <summary> |
64 | /// Rez an attachment from user inventory and change inventory status to match. | 64 | /// Rez an attachment from user inventory and change inventory status to match. |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 873a11d..daad3d2 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -2632,8 +2632,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2632 | RootPrim.RemFlag(PrimFlags.TemporaryOnRez); | 2632 | RootPrim.RemFlag(PrimFlags.TemporaryOnRez); |
2633 | 2633 | ||
2634 | if (AttachmentsModule != null) | 2634 | if (AttachmentsModule != null) |
2635 | AttachmentsModule.AttachObject( | 2635 | AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false); |
2636 | sp.ControllingClient, grp.LocalId, (uint)0, grp.AbsolutePosition, false); | ||
2637 | 2636 | ||
2638 | } | 2637 | } |
2639 | else | 2638 | else |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index d72ee6f..c7a9484 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -1064,11 +1064,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1064 | 1064 | ||
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||
1068 | { | ||
1069 | |||
1070 | } | ||
1071 | |||
1072 | public void SendAvatarDataImmediate(ISceneEntity avatar) | 1067 | public void SendAvatarDataImmediate(ISceneEntity avatar) |
1073 | { | 1068 | { |
1074 | 1069 | ||
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index c3edba2..23255fb 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | |||
@@ -627,10 +627,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
627 | { | 627 | { |
628 | } | 628 | } |
629 | 629 | ||
630 | public virtual void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||
631 | { | ||
632 | } | ||
633 | |||
634 | public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) | 630 | public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) |
635 | { | 631 | { |
636 | } | 632 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 976a9ff..defe633 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -3160,15 +3160,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3160 | 3160 | ||
3161 | ScenePresence presence = World.GetScenePresence(m_host.OwnerID); | 3161 | ScenePresence presence = World.GetScenePresence(m_host.OwnerID); |
3162 | 3162 | ||
3163 | /* | ||
3164 | IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; | ||
3165 | if (attachmentsModule != null) | ||
3166 | { | ||
3167 | attachmentsModule.AttachObject( | ||
3168 | presence.ControllingClient, grp.LocalId, | ||
3169 | (uint)attachment, Quaternion.Identity, Vector3.Zero, false); | ||
3170 | } | ||
3171 | */ | ||
3172 | grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false); | 3163 | grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false); |
3173 | } | 3164 | } |
3174 | } | 3165 | } |
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index f8304c0..2993b46 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs | |||
@@ -630,10 +630,6 @@ namespace OpenSim.Tests.Common.Mock | |||
630 | { | 630 | { |
631 | } | 631 | } |
632 | 632 | ||
633 | public virtual void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||
634 | { | ||
635 | } | ||
636 | |||
637 | public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) | 633 | public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) |
638 | { | 634 | { |
639 | } | 635 | } |