>pEX/ddlmZddlZddlmZmZmZddlmZddl m Z m Z m Z m Z mZmZmZdZGddeeZd Zd ZGd d eeZed dZeGddZeGddeZeGddeZeGddeZeGddeZeGddeZeGddeZeGddeZGdd eeZ Gd!d"eeZ!Gd#d$eeZ"Gd%d&eeZ#Gd'd(eeZ$eGd)d*eZ%eGd+d,eZ&eGd-d.eZ'eGd/d0eZ(eGd1d2eZ)eGd3d4eZ*eGd5d6e Z+Gd7d8eeZ,Gd9d:eeZ-Gd;deZ/eGd?d@eZ0eGdAdBeZ1eGdCdDeZ2eGdEdFeZ3eGdGdHeZ4eGdIdJeZ5eGdKdLeZ6eGdMdNeZ7eGdOdPeZ8eGdQdReZ9eGdSdTeZ:eGdUdVeZ;eGdWdXeZdS)]) annotationsN) dataclassfieldsreplace)Enum)AnyDictIterableIteratorListOptionalTypeVariʚ;c>eZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd S)HeaderzNats-Consumer-Stalled DescriptionzNats-Expected-Last-Msg-IdzNats-Expected-Last-Sequencez#Nats-Expected-Last-Subject-SequencezNats-Expected-StreamzNats-Last-ConsumerzNats-Last-Streamz Nats-Msg-IdzNats-TTLz Nats-RollupStatusN)__name__ __module__ __qualname__CONSUMER_STALLED DESCRIPTIONEXPECTED_LAST_MSG_IDEXPECTED_LAST_SEQUENCEEXPECTED_LAST_SUBJECT_SEQUENCEEXPECTED_STREAM LAST_CONSUMER LAST_STREAMMSG_IDMSG_TTLROLLUPSTATUSk/builddir/build/BUILD/imunify360-venv-2.6.2/opt/imunify360/venv/lib/python3.11/site-packages/nats/js/api.pyrrsN.K6:%J",O(M$K FG F FFFr#rz$JS.APIs_INBOX.c"eZdZdZdZdZdZdZdS) StatusCode503404408409100N)rrrSERVICE_UNAVAILABLE NO_MESSAGESREQUEST_TIMEOUTCONFLICTCONTROL_MESSAGEr"r#r$r&r&,s(KOHOOOr#r&_BBase)boundceZdZdZedd Zed d Zed!dZed dZed"dZ ed#dZ e d$dZ d%dZ d&dZdS)'r2zA Helper dataclass to filter unknown fields from the API. respDict[str, Any]fieldstrtype type[Base]returnNonec||d}|d||<dSt|trfd|D||<dS|||<dS)z/Convert the field into the given type in place.Nc:g|]}|Sr") from_response).0itemr9s r$ z!Base._convert..Ds'EEE4--d33EEEr#)get isinstancelistr?)r5r7r9datas ` r$_convertz Base._convert=sxxxt$$ <DKKK d # # 3EEEEEEEDKKK,,T22DKKKr#cT||d}| |tz }|||<dS)z=Convert the given field from nanoseconds to seconds in place.N)rC _NANOSECONDr5r7vals r$_convert_nanosecondszBase._convert_nanosecondsHs3hhud## ? #CU r#rKOptional[float] Optional[int]c8|dSt|tzS)z.Convert the value from seconds to nanoseconds.Nr)intrI)rKs r$_to_nanosecondszBase._to_nanosecondsPs! ;13$%%%r#ct||d}|t|||<dSdS)zBConvert a ISO 8601/RFC 3339 string field into a datetime in place.N)rCr2_parse_utc_isorJs r$_convert_utc_isozBase._convert_utc_isoXs>hhud## ?--c22DKKK ?r#datedatetime.datetimec~t|tr|S|j&|tjj}n>|jtjjkr$|tjj}|ddddS)zConvert a datetime into an ISO 8601/RFC 3339 formatted string. If datetime does not have timezone information, datetime is assumed to be in UTC timezone. Strings are passed through as-is for backwards compatibility. N)tzinfo+00:00Zz.000000) rDr8rXrdatetimetimezoneutc astimezone isoformat)rUs r$ _to_utc_isozBase._to_utc_iso_s dC  K ; <>y"MMMr# time_stringc:|dd}|dd\}}|d\}}|dd}|d|d|}tj|tjjS)zCParse an ISO 8601 timestamp (with nanoseconds) into a UTC datetime.rZrY.+N)rsplitr\ fromisoformatr_r]r^)rbs date_partfrac_tzfractzs r$rSzBase._parse_utc_isoos   X . .WWS!__ 7==%%bBQBx & &4 & &" & & ..q11<Return a copy of the instance with the passed values replaced.)r)rtrss r$evolvez Base.evolvest&&v&&&r#Dict[str, object]cbi}t|D]}t||j}|t|tr|}t|t r:t|dkr't|dtr d|D}|||j<|S)z6Return the object converted into an API-friendly dict.Nrc`g|]+}t|t|,Sr")rDr2as_dict)r@vs r$rBz Base.as_dict..s/KKK1z!T7J7JK199;;KKKr#)rgetattrrrrDr2rzrElen)rtresultr7rKs r$rzz Base.as_dictsD\\ % %E$ ++C{#t$$ $kkmm#t$$ Ls88a<.s +[+[+[RBJJLL+[+[+[r#rr)rrzrrrars r$rzzStreamSource.as_dictsh""  " \+[+[4CZ+[+[+[F' (   *'+'7'78K'L'LF# $ r#r5r6r) rrrrrrrrrrr?rzrrs@r$rrs III#'M''''26N6666$(N(((()-H----;?????+++++[+ r#rcDeZdZUded<dZded<dZded<dZded<dS) StreamSourceInfor8rrNrNlagactivezOptional[Dict[str, Any]]error)rrrrrrrr"r#r$rrsN IIIC F    &*E******r#rc,eZdZUdZded<dZded<dS)LostStreamDataNOptional[List[int]]msgsrNbytes)rrrrrrr"r#r$rrs4 $D$$$$Er#rceZdZUded<ded<ded<ded<ded<dZded <dZd ed <dZd ed <dZded<edfd Z xZ S) StreamStaterPmessagesr first_seqlast_seqconsumer_countNrdeletedrN num_deletedzOptional[LostStreamData]lostzOptional[Dict[str, int]]subjectsr5r6c~||dtt|S)Nr)rGrrr?rs r$r?zStreamState.from_responses1 T6>222ww$$T***r#r) rrrrrrrrrr?rrs@r$rrsMMMJJJNNNMMM#'G''''!%K%%%%%)D)))))-H----+++++[+++++r#rceZdZdZdZdZdZdS)RetentionPolicyz#How message retention is consideredlimitsinterest workqueueN)rrrrLIMITSINTEREST WORK_QUEUEr"r#r$rrs#-- FHJJJr#rceZdZdZdZdZdS) StorageTypezThe type of storage backendfilememoryN)rrrrFILEMEMORYr"r#r$rrs%% D FFFr#rceZdZdZdZdZdS) DiscardPolicyz/Discard policy when a stream reaches its limitsoldnewN)rrrrOLDNEWr"r#r$rrs99 C CCCr#rceZdZdZdZdZdS)StoreCompressionz If stream is file-based and a compression algorithm is specified, the stream data will be compressed on disk. Valid options are none or s2 for Snappy compression. Introduced in nats-server 2.10.0. nones2N)rrrrNONES2r"r#r$rrs$ D BBBr#rceZdZdZdZdZdS) PersistModea1 PersistMode defines the consistency and durability guarantees for stream persistence. See ADR-56 for details: https://github.com/nats-io/nats-architecture-and-design/blob/main/adr/ADR-56.md Currently only applicable to R1 (single replica) streams. Introduced in nats-server 2.12.0. defaultasyncN)rrrrDEFAULTASYNCr"r#r$rrs&G EEEr#rc>eZdZUdZdZded<dZded<dZded<dS) RePublishz RePublish is for republishing messages once committed to a stream. The original subject cis remapped from the subject pattern to the destination pattern. Nrsrcdestr headers_only)rrrrrrrrr"r#r$rr+sQ CD#'L''''''r#rc:eZdZUdZded<ded<dfd ZxZS) rz0Subject transform to apply to matching messages.r8rrr;rwcHt}|Srrrs r$rzzSubjectTransform.as_dict>rr#r)rrrrrrzrrs@r$rr7sW:: HHH IIIr#rc6eZdZUdZdZded<dZded<dZded<dZded <dZ d ed <dZ d ed <dZ d ed <e j Zded<dZded<dZded<dZded<dZd ed<dZded<dZd ed<dZded<dZded<dZded <dZd!ed"<dZd#ed$<dZd%ed&<dZded'<dZded(<dZded)<dZded*<dZd+ed,<dZ d-ed.<dZ!d/ed0<dZ"d/ed1<dZ#d2ed3<dZ$d/ed4<dZ%d/ed5<dZ&d/ed6<dZ'd/ed7<dZ(d8ed9<dZ)d:ed;<e*dBfd> Z+dCfdA Z,xZ-S)D StreamConfigz@ StreamConfig represents the configuration of a stream. Nrrr descriptionrrzOptional[RetentionPolicy] retentionrN max_consumersmax_msgs max_byteszOptional[DiscardPolicy]discardFbooldiscard_new_per_subjectrMmax_agerPmax_msgs_per_subject max_msg_sizeOptional[StorageType]storage num_replicasno_acktemplate_ownerrfloatduplicate_windowOptional[Placement] placementzOptional[StreamSource]mirrorzOptional[List[StreamSource]]sourcessealed deny_delete deny_purgeallow_rollup_hdrsOptional[RePublish] republishzOptional[SubjectTransform]subject_transformr allow_direct mirror_directzOptional[StoreCompression] compression allow_msg_ttlallow_msg_schedules allow_atomic allow_batchedzOptional[PersistMode] persist_modeOptional[Dict[str, str]]metadatar5r6c||d||d||dt||dt||dt||dt||dt t |S)Nrrrrrrr )rLrGrrrrrr?rs r$r?zStreamConfig.from_responses   y111   '9::: T; 222 T8\222 T9l333 T; 222 T.0@AAAww$$T***r#r;rwct}||j|d<||j|d<|jrd|jD|d<|jrA|jtjkr,|jtj krtd|jz|j r)t|j tstd|S)Nrrc6g|]}|Sr"r)r@rs r$rBz(StreamConfig.as_dict..s G G G3 G G Gr#rz(nats: invalid store compression type: %sznats: invalid metadata format)rrzrQrrrr rrr ValueErrorrrDdictrs r$rzzStreamConfig.as_dicts""%)%9%9$:O%P%P!" 00>>y < H G G$, G G GF9    \!15E5J!J!JtO_cscvOvOvG$JZZ[[ [ = >DM4!@!@ ><== = r#rr).rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr r r r r rrrrrrr?rzrrs@r$rrCsD!%K%%%%$(H((((+/I////#'M''''"H""""#I####'4'8G8888$)))))#G#### """"""$L$$$$%)G))))"&L&&&&F$(N((((%)I))))%)F)))),0G0000FKJ#####&*I))))488888$(L''''%)M((((/3K2222%)M((((+/....$(L''''%)M((((+/L....*.H----+++++[+          r#rcVeZdZUdZded<dZded<dZded<dZded<dZded <dS) PeerInfoNrrrrcurrentofflinerNrr) rrrrrrrrrrr"r#r$rrsgD"G"""""G"""" F    Cr#rceZdZUdZded<dZded<dZded<dZded<dZded <dZ ded <e dfd Z xZ S) ClusterInfoNrleaderrrzOptional[List[PeerInfo]]replicas raft_groupr leader_since traffic_accr5r6c||dtd|vr&|dr||d|d<t|S)Nr r")rGrrSrr?rs r$r?zClusterInfo.from_responsesc T:x000 T ! !d>&: !##5d>6J#K#KD ww$$T***r#r) rrrrrrrr r!r"r#rr?rrs@r$rrs F    D)-H---- $J$$$$04L4444!%K%%%%+++++[+++++r#rceZdZUdZded<ded<dZded<dZd ed <dZd ed <dZd ed<e dfd Z xZ S) StreamInfozM StreamInfo is the latest information about a stream from JetStream. rconfigrstateNzOptional[StreamSourceInfo]rz Optional[List[StreamSourceInfo]]rOptional[ClusterInfo]rr did_creater5r6c^||dt||dt||dt||dt||dtt |S)Nr'r(rrr)rGrrrrrr?rs r$r?zStreamInfo.from_responses T8\222 T7K000 T8%5666 T9&6777 T9k222ww$$T***r#r) rrrrrrrrr*rr?rrs@r$r&r&s)-F----04G4444%)G))))!%J%%%%+++++[+++++r#r&c*eZdZdZdd Zdd Zdd ZdS)StreamsListIteratorzW StreamsListIterator is an iterator for streams list responses from JetStream. offsetrPtotalstreamsList[Dict[str, any]]r;r<c>||_||_||_d|_dS)Nr)r.r/r0_index)rtr.r/r0s r$__init__zStreamsListIterator.__init__s"    r#Iterator[StreamInfo]c|Srr"rts r$__iter__zStreamsListIterator.__iter__s r#r&c|jt|jkr`_ rallexplicitN)rrrrrALLEXPLICITr"r#r$r>r>s) D CHHHr#r>c*eZdZdZdZdZdZdZdZdZ dS) DeliverPolicyagWhen a consumer is first created, it can specify where in the stream it wants to start receiving messages. This is the DeliverPolicy, and this enumeration defines allowed values. References: * `Consumers, DeliverPolicy/OptStartSeq/OptStartTime `_ r?lastrby_start_sequence by_start_timelast_per_subjectN) rrrrrALASTrBY_START_SEQUENCE BY_START_TIMELAST_PER_SUBJECTr"r#r$rDrDs< C D C+#M)r#rDceZdZdZdZdZdS) ReplayPolicyaUThe replay policy applies when the DeliverPolicy is one of: * all * by_start_sequence * by_start_time since those deliver policies begin reading the stream at a position other than the end. References: * `Consumers, ReplayPolicy `_ instantoriginalN)rrrrINSTANTORIGINALr"r#r$rNrNs$GHHHr#rNceZdZUdZdZded<dZded<dZded<ej Z ded<dZ d ed <dZ d ed <e jZd ed<dZded<dZd ed<dZded<dZded<dZded<ejZded<dZd ed<dZded<dZd ed<dZd ed<dZded<dZded<dZded <dZded!<dZ ded"<dZ!ded#<dZ"d ed$<dZ#ded%<dZ$d&ed'<dZ%ded(<e&d/fd+ Z'd0fd. Z(xZ)S)1ConsumerConfigzxConsumer configuration. References: * `Consumers `_ Nrrr durable_namerzOptional[DeliverPolicy]deliver_policyrNrrrzOptional[AckPolicy] ack_policyrMack_wait max_deliverzOptional[List[float]]backoffrrfilter_subjectszOptional[ReplayPolicy] replay_policyrate_limit_bps sample_freq max_waitingmax_ack_pendingr flow_controlidle_heartbeatrdeliver_subject deliver_groupinactive_thresholdr mem_storagerr pause_untilr5r6c(||d||d||d||dd|vrd|dD|d<t|S)NrXrbrerrZc"g|] }|tz  Sr")rI)r@rKs r$rBz0ConsumerConfig.from_response..LsLLLSs[0LLLr#)rLrTrr?rs r$r?zConsumerConfig.from_responseEs   z222   '7888   ';<<< T#3444   LLDOLLLDOww$$T***r#r;rwczt}jj|d<j|d<j|d<j|d<jrfdjD|d<|S)NrrXrbrec:g|]}|Sr")rQ)r@irts r$rBz*ConsumerConfig.as_dict..Ws' O O OQ!5!5a!8!8 O O Or#rZ) rrzrrarQrXrbrerZrs` r$rzzConsumerConfig.as_dictOs""   *'+'7'78K'L'LF# $!11$-@@z#'#7#78K#L#L '+';';DrBrWrXrYrZrr[rNrQr\r]r^r_r`rarbrrcrdrerrfrrgrr?rzrrs@r$rTrTsT D"&L&&&&!%K%%%%.;.?N????#'M''''26N6666&/&8J8888 $H$$$$!%K%%%%%)G))))$(N((((+/O////,8,@M@@@@$(N((((!%K%%%%!%K%%%%%)O))))#'L''''&*N****#'L''''&*O))))#'M''''+/....#'L&&&&#'K&&&&*.H---- "&K%%%%+++++[+          r#rTc`eZdZUded<ded<dZded<ed fd Zdfd ZxZS) SequenceInforP consumer_seq stream_seqNr last_activer5r6cr||dt|SNrq)rTrr?rs r$r?zSequenceInfo.from_responseas1 T=111ww$$T***r#r;rwct}|j||j|d<|Srs)rrzrqrars r$rzzSequenceInfo.as_dictfs?""   '$($4$4T5E$F$FF= ! r#rr) rrrrrqrr?rzrrs@r$rnrn[sOOO/3K3333+++++[+r#rnceZdZUdZded<ded<ded<ded<d Zd ed <d Zd ed <d Zd ed<d Zd ed<d Z d ed<d Z d ed<d Z ded<d Z ded<d Z ded<d Zded<edfd Zd fd ZxZS)! ConsumerInfoz> ConsumerInfo represents the info about the consumer. r8rr stream_namerTr'rVcreatedNzOptional[SequenceInfo] delivered ack_floorrNnum_ack_pendingnum_redelivered num_waiting num_pendingr)rr push_boundpausedrpause_remainingr5r6cR||dt||dt||dt||dt||dt |S)Nryrzr'rrx)rGrnrTrrTrr?rs r$r?zConsumerInfo.from_responses T; 555 T; 555 T8^444 T9k222 T9---ww$$T***r#r;rwct}||j|d<|S)Nrx)rrzrarxrs r$rzzConsumerInfo.as_dicts5"" ,,T\::y r#rr)rrrrrryrzr{r|r}r~rrrrrr?rzrrs@r$rvrvmsNIII(,I,,,,(,I,,,,%)O))))%)O))))!%K%%%%!%K%%%%%)G))))!%J%%%%"F!!!!&*O))))+++++[+r#rvc:eZdZUdZded<dZded<dZded<dS) ConsumerPausez{ ConsumerPause represents the pause state after a pause or resume operation. Introduced in nats-server 2.11.0. rrNrrgr)rrrrrrgrr"r#r$rrsI LLL!%K%%%%%)O))))))r#rcdeZdZUdZded<ded<ded<ded<ded<ded<ded <d ed <d S) AccountLimitszAccount limits References: * `Multi-tenancy & Resource Mgmt `_ rP max_memory max_storage max_streamsrr`memory_max_stream_bytesstorage_max_stream_bytesrmax_bytes_requiredNrrrrrr"r#r$rrs{ OOO    !!!!r#rcdeZdZUded<ded<ded<ded<ded<ed fd ZxZS) TierrPrrr0 consumersrrr5r6c~||dtt|S)Nr)rGrrr?rs r$r?zTier.from_responses1 T8]333ww$$T***r#r)rrrrrr?rrs@r$rrsyKKKLLLLLLNNN+++++[+++++r#rc(eZdZUdZded<ded<dS)APIStatsz API statsrPr/errorsNrr"r#r$rrs'OJJJKKKKKr#rceZdZUdZded<ded<ded<ded<ded<d ed <d Zd ed <d Zded<edfd ZxZ S) AccountInfozAccount information References: * `Account Information `_ rPrrr0rrrrrNrrzOptional[Dict[str, Tier]]tiersr5r6cj||dt||dtt|}|dd}|r@i}|D]"\}}t|||<#||_|S)Nrrr) rGrrrr?rCitemsrr)ror5inforr~kr{rs r$r?zAccountInfo.from_responses T8]333 T5(+++ww$$T**$''  F  2 21 ..q11q DJ r#r) rrrrrrrrr?rrs@r$rrsKKKLLLLLLNNNMMM F    '+E++++     [     r#rceZdZUdZded<dZded<dZded<dZded<dZd ed <dZ ded <dZ d ed <e ddZ e ddZ edfd ZxZS) RawStreamMsgNrsubjectrNrzOptional[bytes]rFhdrsOptional[Dict]headersrrtimer;c|jSr)rr7s r$sequencezRawStreamMsg.sequences xr#c|jS)z< header returns the headers from a message. )rr7s r$headerzRawStreamMsg.headers |r#r5r6c||d|d<t|S)Nr)rSrr?rs r$r?zRawStreamMsg.from_responses6))$v,77V ww$$T***r#)r;rN)r;rr)rrrrrrrFrrrrpropertyrrrr?rrs@r$rrs!G!!!!C D     D    "G"""" F    (,D,,,, XX +++++[+++++r#rceZdZUdZded<dZded<dZded<d Zd ed <dZd ed <dZ ded<dZ ded<d Z d ed<dZ ded<dZ ded<dZded<dfd ZxZS)KeyValueConfigzB KeyValueConfig is the configuration of a KeyValue store. r8bucketNrrrNmax_value_sizererPhistoryrMttlrrrr rrrrrdirectr;rwct}||j|d<|SNrrrzrQrrs r$rzzKeyValueConfig.as_dict4"",,TX66u  r#r)rrrrrrrrrrrr rrrrzrrs@r$rrsKKK!%K%%%%$(N((((GC#I####%)G))))H%)I))))%)I))))!F!!!!r#rc>eZdZUdZdZded<dZded<dZded<dS)StreamPurgeRequestzN StreamPurgeRequest is optional request information to the purge API. NrNrrfilterkeep)rrrrrrrrr"r#r$rrsQ C F    Dr#rceZdZUdZdZded<dZded<dZded<dZded <dZ d ed <d Z d ed<dZ ded<dfd Z xZ S)ObjectStoreConfigzE ObjectStoreConfig is the configurigation of an ObjectStore. NrrrrMrrNrrrrerPr rrr;rwct}||j|d<|Srrrs r$rzzObjectStoreConfig.as_dict9rr#r)rrrrrrrrrrr rrzrrs@r$rr+s!F    !%K%%%%C#I####%)G))))H%)I))))r#rcNeZdZUdZded<dZded<ed fd ZxZS) ObjectLinkzI ObjectLink is used to embed links to other buckets and objects. r8rNrrrr5r6cFt|Sr)rr?rs r$r?zObjectLink.from_responseKsww$$T***r#r) rrrrrrrrr?rrs@r$rr?sq KKKD+++++[+++++r#rcNeZdZUdZded<dZded<ed fd ZxZS) ObjectMetaOptionsNzOptional[ObjectLink]linkrNmax_chunk_sizer5r6c~||dtt|S)Nr)rGrrr?rs r$r?zObjectMetaOptions.from_responseUs1 T6:...ww$$T***r#r) rrrrrrrr?rrs@r$rrPsk!%D%%%%$(N((((+++++[+++++r#rcneZdZUdZdZded<dZded<dZded<dZded <e d fd Z xZ S) ObjectMetaz? ObjectMeta is high level information about an object. NrrrrOptional[dict]rOptional[ObjectMetaOptions]optionsr5r6c~||dtt|SNrrGrrr?rs r$r?zObjectMeta.from_responseg2 T9&7888ww$$T***r#r) rrrrrrrrrrrr?rrs@r$rr[sD!%K%%%%"G""""+/G////+++++[+++++r#rceZdZUdZded<ded<ded<dZded<dZd ed <dZded <dZd ed <d Z ded<dZ d ed<dZ ded<dZ ded<e ddZddZedfd ZxZS) ObjectInfoz7 ObjectInfo is meta plus instance information. r8rrrnuidNrNsizermtimechunksdigestFrrrrrrrr;rcPt|j|j|j|jS)N)rrrrr)rrrrrrr7s r$metazObjectInfo.metas.(LL     r#rc0|jduo |jjduSr)rrr7s r$is_linkzObjectInfo.is_links|4'IDL,=T,IIr#r5r6c~||dtt|Srrrs r$r?zObjectInfo.from_responserr#)r;r)r;rr)rrrrrrrrrrrrrrrrrr?rrs@r$rrms2IIIKKK IIIDE F     F    #G####!%K%%%%"G""""+/G////   X JJJJ+++++[+++++r#r)? __future__rr\ dataclassesrrrenumrtypingrr r r r r rrIr8rDEFAULT_PREFIX INBOX_PREFIXr&r1r2rrrrrrrrrrrrrrrrrr&r-r>rDrNrTrnrvrrrrrrrrrrrrrr"r#r$rs #"""""2222222222IIIIIIIIIIIIIIIIII      S$    d WT    ``````` `F %%%%%T%% % %%%%%%% % T  4 0 +++++t++ +      T     +++++$++ +"c4#tC     sD   #t, ((((((( ( t  SSSSS4SS Sl t   + + + + +$ + +  +  +++++++ +,      (    .     T   *****C***"     3    FFFFFTFF FR 4 " $$$$$4$$ $N *****D** * D "  + + + + +4 + +  + t  $ @ +++++4++ +4 T .            &  + + + + + + +  +  +++++++ + +++++++ +" #+#+#+#+#+#+#+ #+#+#+r#