2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   GoToSocial 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   Copyright  ( C )  2021  GoToSocial  Authors  admin @ gotosocial . org 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   This  program  is  free  software :  you  can  redistribute  it  and / or  modify 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   it  under  the  terms  of  the  GNU  Affero  General  Public  License  as  published  by 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   the  Free  Software  Foundation ,  either  version  3  of  the  License ,  or 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   ( at  your  option )  any  later  version . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   This  program  is  distributed  in  the  hope  that  it  will  be  useful , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   but  WITHOUT  ANY  WARRANTY ;  without  even  the  implied  warranty  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   MERCHANTABILITY  or  FITNESS  FOR  A  PARTICULAR  PURPOSE .   See  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   GNU  Affero  General  Public  License  for  more  details . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   You  should  have  received  a  copy  of  the  GNU  Affero  General  Public  License 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   along  with  this  program .   If  not ,  see  < http : //www.gnu.org/licenses/>. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* /  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 13:12:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								package  processing  
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"net/http" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/sirupsen/logrus" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apimodel  "github.com/superseriousbusiness/gotosocial/internal/api/model" 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 13:12:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/blob" 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/config" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/db" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/federation" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/gtserror" 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/media" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/oauth" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/processing/synchronous/status" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 11:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/processing/synchronous/streaming" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/timeline" 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/typeutils" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-17 18:02:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/visibility" 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Processor should be passed to api modules (see internal/apimodule/...). It is used for  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// passing messages back and forth from the client API and the federating interface, via channels.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It also contains logic for filtering which messages should end up where.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It is designed to be used asynchronously: the client API and the federating API should just be able to  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// fire messages into the processor and not wait for a reply before proceeding with other work. This allows  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// for clean distribution of messages without slowing down the client API and harming the user experience.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  Processor  interface  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Start starts the Processor, reading from its channels and passing messages back and forth. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Start ( )  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Stop stops the processor cleanly, finishing handling any remaining messages before closing down. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Stop ( )  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/ * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CLIENT  API - FACING  PROCESSING  FUNCTIONS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										These  functions  are  intended  to  be  called  when  the  API  client  needs  an  immediate  ( ie . ,  synchronous )  reply 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										to  an  HTTP  request .  As  such ,  they  will  only  do  the  bare - minimum  of  work  necessary  to  give  a  properly 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										formed  reply .  For  more  intensive  ( and  time - consuming )  calls ,  where  you  don ' t  require  an  immediate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										response ,  pass  work  to  the  processor  using  a  channel  instead . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// AccountCreate processes the given form for creating a new account, returning an oauth token for that account if successful. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AccountCreate ( authed  * oauth . Auth ,  form  * apimodel . AccountCreateRequest )  ( * apimodel . Token ,  error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// AccountGet processes the given request for account information. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AccountGet ( authed  * oauth . Auth ,  targetAccountID  string )  ( * apimodel . Account ,  error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// AccountUpdate processes the update of an account with the given form 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AccountUpdate ( authed  * oauth . Auth ,  form  * apimodel . UpdateCredentialsRequest )  ( * apimodel . Account ,  error ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// AccountStatusesGet fetches a number of statuses (in time descending order) from the given account, filtered by visibility for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// the account given in authed. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AccountStatusesGet ( authed  * oauth . Auth ,  targetAccountID  string ,  limit  int ,  excludeReplies  bool ,  maxID  string ,  pinned  bool ,  mediaOnly  bool )  ( [ ] apimodel . Status ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// AccountFollowersGet fetches a list of the target account's followers. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AccountFollowersGet ( authed  * oauth . Auth ,  targetAccountID  string )  ( [ ] apimodel . Account ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// AccountFollowingGet fetches a list of the accounts that target account is following. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AccountFollowingGet ( authed  * oauth . Auth ,  targetAccountID  string )  ( [ ] apimodel . Account ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// AccountRelationshipGet returns a relationship model describing the relationship of the targetAccount to the Authed account. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AccountRelationshipGet ( authed  * oauth . Auth ,  targetAccountID  string )  ( * apimodel . Relationship ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// AccountFollowCreate handles a follow request to an account, either remote or local. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AccountFollowCreate ( authed  * oauth . Auth ,  form  * apimodel . AccountFollowRequest )  ( * apimodel . Relationship ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// AccountFollowRemove handles the removal of a follow/follow request to an account, either remote or local. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AccountFollowRemove ( authed  * oauth . Auth ,  targetAccountID  string )  ( * apimodel . Relationship ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 14:06:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// AdminEmojiCreate handles the creation of a new instance emoji by an admin, using the given form. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AdminEmojiCreate ( authed  * oauth . Auth ,  form  * apimodel . EmojiCreateRequest )  ( * apimodel . Emoji ,  error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// AppCreate processes the creation of a new API application 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AppCreate ( authed  * oauth . Auth ,  form  * apimodel . ApplicationCreateRequest )  ( * apimodel . Application ,  error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-10 16:29:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// FileGet handles the fetching of a media attachment file via the fileserver. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FileGet ( authed  * oauth . Auth ,  form  * apimodel . GetContentRequestForm )  ( * apimodel . Content ,  error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// FollowRequestsGet handles the getting of the authed account's incoming follow requests 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									FollowRequestsGet ( auth  * oauth . Auth )  ( [ ] apimodel . Account ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// FollowRequestAccept handles the acceptance of a follow request from the given account ID 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									FollowRequestAccept ( auth  * oauth . Auth ,  accountID  string )  ( * apimodel . Relationship ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 14:06:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// InstanceGet retrieves instance information for serving at api/v1/instance 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									InstanceGet ( domain  string )  ( * apimodel . Instance ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-23 16:35:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// InstancePatch updates this instance according to the given form. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// It should already be ascertained that the requesting account is authenticated and an admin. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									InstancePatch ( form  * apimodel . InstanceSettingsUpdateRequest )  ( * apimodel . Instance ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 14:06:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// MediaCreate handles the creation of a media attachment, using the given form. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MediaCreate ( authed  * oauth . Auth ,  form  * apimodel . AttachmentRequest )  ( * apimodel . Attachment ,  error ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-10 16:29:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// MediaGet handles the GET of a media attachment with the given ID 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									MediaGet ( authed  * oauth . Auth ,  attachmentID  string )  ( * apimodel . Attachment ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-10 16:29:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// MediaUpdate handles the PUT of a media attachment with the given ID and form 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									MediaUpdate ( authed  * oauth . Auth ,  attachmentID  string ,  form  * apimodel . AttachmentUpdateRequest )  ( * apimodel . Attachment ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 14:06:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-27 16:06:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// NotificationsGet 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									NotificationsGet ( authed  * oauth . Auth ,  limit  int ,  maxID  string ,  sinceID  string )  ( [ ] * apimodel . Notification ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-27 16:06:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 19:36:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// SearchGet performs a search with the given params, resolving/dereferencing remotely as desired 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									SearchGet ( authed  * oauth . Auth ,  searchQuery  * apimodel . SearchQuery )  ( * apimodel . SearchResult ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 19:36:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// StatusCreate processes the given form to create a new status, returning the api model representation of that status if it's OK. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StatusCreate ( authed  * oauth . Auth ,  form  * apimodel . AdvancedStatusCreateForm )  ( * apimodel . Status ,  error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// StatusDelete processes the delete of a given status, returning the deleted status if the delete goes through. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StatusDelete ( authed  * oauth . Auth ,  targetStatusID  string )  ( * apimodel . Status ,  error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// StatusFave processes the faving of a given status, returning the updated status if the fave goes through. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StatusFave ( authed  * oauth . Auth ,  targetStatusID  string )  ( * apimodel . Status ,  error ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 15:16:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// StatusBoost processes the boost/reblog of a given status, returning the newly-created boost if all is well. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StatusBoost ( authed  * oauth . Auth ,  targetStatusID  string )  ( * apimodel . Status ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 15:56:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// StatusUnboost processes the unboost/unreblog of a given status, returning the status if all is well. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StatusUnboost ( authed  * oauth . Auth ,  targetStatusID  string )  ( * apimodel . Status ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 17:36:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// StatusBoostedBy returns a slice of accounts that have boosted the given status, filtered according to privacy settings. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StatusBoostedBy ( authed  * oauth . Auth ,  targetStatusID  string )  ( [ ] * apimodel . Account ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// StatusFavedBy returns a slice of accounts that have liked the given status, filtered according to privacy settings. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StatusFavedBy ( authed  * oauth . Auth ,  targetStatusID  string )  ( [ ] * apimodel . Account ,  error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// StatusGet gets the given status, taking account of privacy settings and blocks etc. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StatusGet ( authed  * oauth . Auth ,  targetStatusID  string )  ( * apimodel . Status ,  error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// StatusUnfave processes the unfaving of a given status, returning the updated status if the fave goes through. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StatusUnfave ( authed  * oauth . Auth ,  targetStatusID  string )  ( * apimodel . Status ,  error ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 17:36:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// StatusGetContext returns the context (previous and following posts) from the given status ID 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									StatusGetContext ( authed  * oauth . Auth ,  targetStatusID  string )  ( * apimodel . Context ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 23:04:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HomeTimelineGet returns statuses from the home timeline, with the given filters/parameters. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									HomeTimelineGet ( authed  * oauth . Auth ,  maxID  string ,  sinceID  string ,  minID  string ,  limit  int ,  local  bool )  ( * apimodel . StatusTimelineResponse ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 17:36:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// PublicTimelineGet returns statuses from the public/local timeline, with the given filters/parameters. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									PublicTimelineGet ( authed  * oauth . Auth ,  maxID  string ,  sinceID  string ,  minID  string ,  limit  int ,  local  bool )  ( [ ] * apimodel . Status ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 23:04:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 11:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// AuthorizeStreamingRequest returns a gotosocial account in exchange for an access token, or an error if the given token is not valid. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AuthorizeStreamingRequest ( accessToken  string )  ( * gtsmodel . Account ,  error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// OpenStreamForAccount opens a new stream for the given account, with the given stream type. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									OpenStreamForAccount ( account  * gtsmodel . Account ,  streamType  string )  ( * gtsmodel . Stream ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/ * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										FEDERATION  API - FACING  PROCESSING  FUNCTIONS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										These  functions  are  intended  to  be  called  when  the  federating  client  needs  an  immediate  ( ie . ,  synchronous )  reply 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										to  an  HTTP  request .  As  such ,  they  will  only  do  the  bare - minimum  of  work  necessary  to  give  a  properly 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										formed  reply .  For  more  intensive  ( and  time - consuming )  calls ,  where  you  don ' t  require  an  immediate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										response ,  pass  work  to  the  processor  using  a  channel  instead . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// GetFediUser handles the getting of a fedi/activitypub representation of a user/account, performing appropriate authentication 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// before returning a JSON serializable interface to the caller. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									GetFediUser ( requestedUsername  string ,  request  * http . Request )  ( interface { } ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 20:34:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// GetFediFollowers handles the getting of a fedi/activitypub representation of a user/account's followers, performing appropriate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// authentication before returning a JSON serializable interface to the caller. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									GetFediFollowers ( requestedUsername  string ,  request  * http . Request )  ( interface { } ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-23 18:07:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// GetFediFollowing handles the getting of a fedi/activitypub representation of a user/account's following, performing appropriate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// authentication before returning a JSON serializable interface to the caller. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									GetFediFollowing ( requestedUsername  string ,  request  * http . Request )  ( interface { } ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// GetFediStatus handles the getting of a fedi/activitypub representation of a particular status, performing appropriate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// authentication before returning a JSON serializable interface to the caller. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									GetFediStatus ( requestedUsername  string ,  requestedStatusID  string ,  request  * http . Request )  ( interface { } ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 20:34:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// GetWebfingerAccount handles the GET for a webfinger resource. Most commonly, it will be used for returning account lookups. 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									GetWebfingerAccount ( requestedUsername  string ,  request  * http . Request )  ( * apimodel . WebfingerAccountResponse ,  gtserror . WithCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// InboxPost handles POST requests to a user's inbox for new activitypub messages. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// InboxPost returns true if the request was handled as an ActivityPub POST to an actor's inbox. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If false, the request was not an ActivityPub request and may still be handled by the caller in another way, such as serving a web page. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If the error is nil, then the ResponseWriter's headers and response has already been written. If a non-nil error is returned, then no response has been written. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If the Actor was constructed with the Federated Protocol enabled, side effects will occur. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If the Federated Protocol is not enabled, writes the http.StatusMethodNotAllowed status code in the response. No side effects occur. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									InboxPost ( ctx  context . Context ,  w  http . ResponseWriter ,  r  * http . Request )  ( bool ,  error ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// processor just implements the Processor interface  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  processor  struct  {  
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									fromClientAPI    chan  gtsmodel . FromClientAPI 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fromFederator    chan  gtsmodel . FromFederator 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									federator        federation . Federator 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									stop             chan  interface { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									log              * logrus . Logger 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									config           * config . Config 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tc               typeutils . TypeConverter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									oauthServer      oauth . Server 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mediaHandler     media . Handler 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									storage          blob . Storage 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									timelineManager  timeline . Manager 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									db               db . DB 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-17 18:02:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									filter           visibility . Filter 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/ * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SUB - PROCESSORS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 11:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									statusProcessor     status . Processor 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									streamingProcessor  streaming . Processor 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// NewProcessor returns a new Processor that uses the given federator and logger  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewProcessor ( config  * config . Config ,  tc  typeutils . TypeConverter ,  federator  federation . Federator ,  oauthServer  oauth . Server ,  mediaHandler  media . Handler ,  storage  blob . Storage ,  timelineManager  timeline . Manager ,  db  db . DB ,  log  * logrus . Logger )  Processor  {  
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									fromClientAPI  :=  make ( chan  gtsmodel . FromClientAPI ,  1000 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fromFederator  :=  make ( chan  gtsmodel . FromFederator ,  1000 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									statusProcessor  :=  status . New ( db ,  tc ,  config ,  fromClientAPI ,  log ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 11:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									streamingProcessor  :=  streaming . New ( db ,  tc ,  oauthServer ,  config ,  log ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  & processor { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fromClientAPI :    fromClientAPI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fromFederator :    fromFederator , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										federator :        federator , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stop :             make ( chan  interface { } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log :              log , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										config :           config , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tc :               tc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										oauthServer :      oauthServer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mediaHandler :     mediaHandler , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										storage :          storage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										timelineManager :  timelineManager , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db :               db , 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-17 18:02:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										filter :           visibility . NewFilter ( db ,  log ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 11:18:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										statusProcessor :     statusProcessor , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										streamingProcessor :  streamingProcessor , 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Start starts the Processor, reading from its channels and passing messages back and forth.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( p  * processor )  Start ( )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									go  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DistLoop : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  clientMsg  :=  <- p . fromClientAPI : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p . log . Infof ( "received message FROM client API: %+v" ,  clientMsg ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  :=  p . processFromClientAPI ( clientMsg ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p . log . Error ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  federatorMsg  :=  <- p . fromFederator : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p . log . Infof ( "received message FROM federator: %+v" ,  federatorMsg ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  :=  p . processFromFederator ( federatorMsg ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p . log . Error ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  <- p . stop : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break  DistLoop 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-13 18:42:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  p . initTimelines ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Stop stops the processor cleanly, finishing handling any remaining messages before closing down.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// TODO: empty message buffer properly before stopping otherwise we'll lose federating messages.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( p  * processor )  Stop ( )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									close ( p . stop ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}