ingest.pb.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. // Code generated by protoc-gen-go. DO NOT EDIT.
  2. // versions:
  3. // protoc-gen-go v1.36.11
  4. // protoc (unknown)
  5. // source: broadannounce/v1/ingest.proto
  6. package broadannouncev1
  7. import (
  8. protoreflect "google.golang.org/protobuf/reflect/protoreflect"
  9. protoimpl "google.golang.org/protobuf/runtime/protoimpl"
  10. reflect "reflect"
  11. sync "sync"
  12. unsafe "unsafe"
  13. )
  14. const (
  15. // Verify that this generated code is sufficiently up-to-date.
  16. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  17. // Verify that runtime/protoimpl is sufficiently up-to-date.
  18. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  19. )
  20. // Code classifies the error so the client can act programmatically.
  21. type Error_Code int32
  22. const (
  23. Error_UNKNOWN Error_Code = 0 // catch-all; include message
  24. Error_UNAUTHENTICATED Error_Code = 1 // API key missing or invalid
  25. Error_RATE_LIMITED Error_Code = 2 // per-source or per-company rate limit hit
  26. Error_INVALID Error_Code = 3 // schema validation failed;修复 check message
  27. Error_INTERNAL Error_Code = 4 // server-side error; do not retry immediately
  28. )
  29. // Enum value maps for Error_Code.
  30. var (
  31. Error_Code_name = map[int32]string{
  32. 0: "UNKNOWN",
  33. 1: "UNAUTHENTICATED",
  34. 2: "RATE_LIMITED",
  35. 3: "INVALID",
  36. 4: "INTERNAL",
  37. }
  38. Error_Code_value = map[string]int32{
  39. "UNKNOWN": 0,
  40. "UNAUTHENTICATED": 1,
  41. "RATE_LIMITED": 2,
  42. "INVALID": 3,
  43. "INTERNAL": 4,
  44. }
  45. )
  46. func (x Error_Code) Enum() *Error_Code {
  47. p := new(Error_Code)
  48. *p = x
  49. return p
  50. }
  51. func (x Error_Code) String() string {
  52. return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
  53. }
  54. func (Error_Code) Descriptor() protoreflect.EnumDescriptor {
  55. return file_broadannounce_v1_ingest_proto_enumTypes[0].Descriptor()
  56. }
  57. func (Error_Code) Type() protoreflect.EnumType {
  58. return &file_broadannounce_v1_ingest_proto_enumTypes[0]
  59. }
  60. func (x Error_Code) Number() protoreflect.EnumNumber {
  61. return protoreflect.EnumNumber(x)
  62. }
  63. // Deprecated: Use Error_Code.Descriptor instead.
  64. func (Error_Code) EnumDescriptor() ([]byte, []int) {
  65. return file_broadannounce_v1_ingest_proto_rawDescGZIP(), []int{3, 0}
  66. }
  67. // Alert is what a first-party service sends to BroadAnnounce.
  68. type Alert struct {
  69. state protoimpl.MessageState `protogen:"open.v1"`
  70. CompanyId string `protobuf:"bytes,1,opt,name=company_id,json=companyId,proto3" json:"company_id,omitempty"` // required; maps to sources.company_id
  71. SourceId string `protobuf:"bytes,2,opt,name=source_id,json=sourceId,proto3" json:"source_id,omitempty"` // required; maps to sources.source_id
  72. Severity string `protobuf:"bytes,3,opt,name=severity,proto3" json:"severity,omitempty"` // "info" | "warning" | "critical" | "inminent_colapse"
  73. Category string `protobuf:"bytes,4,opt,name=category,proto3" json:"category,omitempty"` // arbitrary category tag
  74. Title string `protobuf:"bytes,5,opt,name=title,proto3" json:"title,omitempty"` // pre-localized alert title
  75. Body string `protobuf:"bytes,6,opt,name=body,proto3" json:"body,omitempty"` // pre-localized alert body
  76. Data map[string]string `protobuf:"bytes,7,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // arbitrary key-value metadata
  77. DedupeKey string `protobuf:"bytes,8,opt,name=dedupe_key,json=dedupeKey,proto3" json:"dedupe_key,omitempty"` // opaque string; if set, dedupe applies within the window
  78. ClientTsMs int64 `protobuf:"varint,9,opt,name=client_ts_ms,json=clientTsMs,proto3" json:"client_ts_ms,omitempty"` // Unix-ms timestamp set by the client; used for skew detection
  79. unknownFields protoimpl.UnknownFields
  80. sizeCache protoimpl.SizeCache
  81. }
  82. func (x *Alert) Reset() {
  83. *x = Alert{}
  84. mi := &file_broadannounce_v1_ingest_proto_msgTypes[0]
  85. ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  86. ms.StoreMessageInfo(mi)
  87. }
  88. func (x *Alert) String() string {
  89. return protoimpl.X.MessageStringOf(x)
  90. }
  91. func (*Alert) ProtoMessage() {}
  92. func (x *Alert) ProtoReflect() protoreflect.Message {
  93. mi := &file_broadannounce_v1_ingest_proto_msgTypes[0]
  94. if x != nil {
  95. ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  96. if ms.LoadMessageInfo() == nil {
  97. ms.StoreMessageInfo(mi)
  98. }
  99. return ms
  100. }
  101. return mi.MessageOf(x)
  102. }
  103. // Deprecated: Use Alert.ProtoReflect.Descriptor instead.
  104. func (*Alert) Descriptor() ([]byte, []int) {
  105. return file_broadannounce_v1_ingest_proto_rawDescGZIP(), []int{0}
  106. }
  107. func (x *Alert) GetCompanyId() string {
  108. if x != nil {
  109. return x.CompanyId
  110. }
  111. return ""
  112. }
  113. func (x *Alert) GetSourceId() string {
  114. if x != nil {
  115. return x.SourceId
  116. }
  117. return ""
  118. }
  119. func (x *Alert) GetSeverity() string {
  120. if x != nil {
  121. return x.Severity
  122. }
  123. return ""
  124. }
  125. func (x *Alert) GetCategory() string {
  126. if x != nil {
  127. return x.Category
  128. }
  129. return ""
  130. }
  131. func (x *Alert) GetTitle() string {
  132. if x != nil {
  133. return x.Title
  134. }
  135. return ""
  136. }
  137. func (x *Alert) GetBody() string {
  138. if x != nil {
  139. return x.Body
  140. }
  141. return ""
  142. }
  143. func (x *Alert) GetData() map[string]string {
  144. if x != nil {
  145. return x.Data
  146. }
  147. return nil
  148. }
  149. func (x *Alert) GetDedupeKey() string {
  150. if x != nil {
  151. return x.DedupeKey
  152. }
  153. return ""
  154. }
  155. func (x *Alert) GetClientTsMs() int64 {
  156. if x != nil {
  157. return x.ClientTsMs
  158. }
  159. return 0
  160. }
  161. // Ack is what the server sends back after processing an Alert.
  162. type Ack struct {
  163. state protoimpl.MessageState `protogen:"open.v1"`
  164. // alert_id is an opaque server-assigned identifier for the alert.
  165. // It may be empty if the alert was rejected before NATS publish.
  166. AlertId string `protobuf:"bytes,1,opt,name=alert_id,json=alertId,proto3" json:"alert_id,omitempty"`
  167. // dedupe_key echoes back the client's dedupe_key.
  168. DedupeKey string `protobuf:"bytes,2,opt,name=dedupe_key,json=dedupeKey,proto3" json:"dedupe_key,omitempty"`
  169. // dedupe_count is 1 on first arrival; >1 when the server collapsed a
  170. // burst of identical dedupe_keys within the dedupe window.
  171. DedupeCount uint32 `protobuf:"varint,3,opt,name=dedupe_count,json=dedupeCount,proto3" json:"dedupe_count,omitempty"`
  172. // accepted_at_ms is the server-side Unix-ms timestamp at which the alert
  173. // was accepted (i.e. after all protection layers passed).
  174. AcceptedAtMs int64 `protobuf:"varint,4,opt,name=accepted_at_ms,json=acceptedAtMs,proto3" json:"accepted_at_ms,omitempty"`
  175. // result is the processing outcome.
  176. //
  177. // Types that are valid to be assigned to Result:
  178. //
  179. // *Ack_Ok
  180. // *Ack_Error
  181. Result isAck_Result `protobuf_oneof:"result"`
  182. unknownFields protoimpl.UnknownFields
  183. sizeCache protoimpl.SizeCache
  184. }
  185. func (x *Ack) Reset() {
  186. *x = Ack{}
  187. mi := &file_broadannounce_v1_ingest_proto_msgTypes[1]
  188. ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  189. ms.StoreMessageInfo(mi)
  190. }
  191. func (x *Ack) String() string {
  192. return protoimpl.X.MessageStringOf(x)
  193. }
  194. func (*Ack) ProtoMessage() {}
  195. func (x *Ack) ProtoReflect() protoreflect.Message {
  196. mi := &file_broadannounce_v1_ingest_proto_msgTypes[1]
  197. if x != nil {
  198. ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  199. if ms.LoadMessageInfo() == nil {
  200. ms.StoreMessageInfo(mi)
  201. }
  202. return ms
  203. }
  204. return mi.MessageOf(x)
  205. }
  206. // Deprecated: Use Ack.ProtoReflect.Descriptor instead.
  207. func (*Ack) Descriptor() ([]byte, []int) {
  208. return file_broadannounce_v1_ingest_proto_rawDescGZIP(), []int{1}
  209. }
  210. func (x *Ack) GetAlertId() string {
  211. if x != nil {
  212. return x.AlertId
  213. }
  214. return ""
  215. }
  216. func (x *Ack) GetDedupeKey() string {
  217. if x != nil {
  218. return x.DedupeKey
  219. }
  220. return ""
  221. }
  222. func (x *Ack) GetDedupeCount() uint32 {
  223. if x != nil {
  224. return x.DedupeCount
  225. }
  226. return 0
  227. }
  228. func (x *Ack) GetAcceptedAtMs() int64 {
  229. if x != nil {
  230. return x.AcceptedAtMs
  231. }
  232. return 0
  233. }
  234. func (x *Ack) GetResult() isAck_Result {
  235. if x != nil {
  236. return x.Result
  237. }
  238. return nil
  239. }
  240. func (x *Ack) GetOk() *Ok {
  241. if x != nil {
  242. if x, ok := x.Result.(*Ack_Ok); ok {
  243. return x.Ok
  244. }
  245. }
  246. return nil
  247. }
  248. func (x *Ack) GetError() *Error {
  249. if x != nil {
  250. if x, ok := x.Result.(*Ack_Error); ok {
  251. return x.Error
  252. }
  253. }
  254. return nil
  255. }
  256. type isAck_Result interface {
  257. isAck_Result()
  258. }
  259. type Ack_Ok struct {
  260. Ok *Ok `protobuf:"bytes,10,opt,name=ok,proto3,oneof"` // alert accepted
  261. }
  262. type Ack_Error struct {
  263. Error *Error `protobuf:"bytes,11,opt,name=error,proto3,oneof"` // alert rejected or rate-limited
  264. }
  265. func (*Ack_Ok) isAck_Result() {}
  266. func (*Ack_Error) isAck_Result() {}
  267. // Ok is returned when an Alert was accepted.
  268. type Ok struct {
  269. state protoimpl.MessageState `protogen:"open.v1"`
  270. unknownFields protoimpl.UnknownFields
  271. sizeCache protoimpl.SizeCache
  272. }
  273. func (x *Ok) Reset() {
  274. *x = Ok{}
  275. mi := &file_broadannounce_v1_ingest_proto_msgTypes[2]
  276. ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  277. ms.StoreMessageInfo(mi)
  278. }
  279. func (x *Ok) String() string {
  280. return protoimpl.X.MessageStringOf(x)
  281. }
  282. func (*Ok) ProtoMessage() {}
  283. func (x *Ok) ProtoReflect() protoreflect.Message {
  284. mi := &file_broadannounce_v1_ingest_proto_msgTypes[2]
  285. if x != nil {
  286. ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  287. if ms.LoadMessageInfo() == nil {
  288. ms.StoreMessageInfo(mi)
  289. }
  290. return ms
  291. }
  292. return mi.MessageOf(x)
  293. }
  294. // Deprecated: Use Ok.ProtoReflect.Descriptor instead.
  295. func (*Ok) Descriptor() ([]byte, []int) {
  296. return file_broadannounce_v1_ingest_proto_rawDescGZIP(), []int{2}
  297. }
  298. // Error is returned when an Alert was rejected.
  299. type Error struct {
  300. state protoimpl.MessageState `protogen:"open.v1"`
  301. Code Error_Code `protobuf:"varint,1,opt,name=code,proto3,enum=broadannounce.v1.Error_Code" json:"code,omitempty"`
  302. Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` // human-readable; never parse this
  303. // retry_after_ms is non-zero when Code == RATE_LIMITED.
  304. // The client MUST wait at least this long before sending the next message.
  305. // A value of 0 means "do not retry" (permanent failure).
  306. RetryAfterMs int32 `protobuf:"varint,3,opt,name=retry_after_ms,json=retryAfterMs,proto3" json:"retry_after_ms,omitempty"`
  307. unknownFields protoimpl.UnknownFields
  308. sizeCache protoimpl.SizeCache
  309. }
  310. func (x *Error) Reset() {
  311. *x = Error{}
  312. mi := &file_broadannounce_v1_ingest_proto_msgTypes[3]
  313. ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  314. ms.StoreMessageInfo(mi)
  315. }
  316. func (x *Error) String() string {
  317. return protoimpl.X.MessageStringOf(x)
  318. }
  319. func (*Error) ProtoMessage() {}
  320. func (x *Error) ProtoReflect() protoreflect.Message {
  321. mi := &file_broadannounce_v1_ingest_proto_msgTypes[3]
  322. if x != nil {
  323. ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  324. if ms.LoadMessageInfo() == nil {
  325. ms.StoreMessageInfo(mi)
  326. }
  327. return ms
  328. }
  329. return mi.MessageOf(x)
  330. }
  331. // Deprecated: Use Error.ProtoReflect.Descriptor instead.
  332. func (*Error) Descriptor() ([]byte, []int) {
  333. return file_broadannounce_v1_ingest_proto_rawDescGZIP(), []int{3}
  334. }
  335. func (x *Error) GetCode() Error_Code {
  336. if x != nil {
  337. return x.Code
  338. }
  339. return Error_UNKNOWN
  340. }
  341. func (x *Error) GetMessage() string {
  342. if x != nil {
  343. return x.Message
  344. }
  345. return ""
  346. }
  347. func (x *Error) GetRetryAfterMs() int32 {
  348. if x != nil {
  349. return x.RetryAfterMs
  350. }
  351. return 0
  352. }
  353. var File_broadannounce_v1_ingest_proto protoreflect.FileDescriptor
  354. const file_broadannounce_v1_ingest_proto_rawDesc = "" +
  355. "\n" +
  356. "\x1dbroadannounce/v1/ingest.proto\x12\x10broadannounce.v1\"\xd6\x02\n" +
  357. "\x05Alert\x12\x1d\n" +
  358. "\n" +
  359. "company_id\x18\x01 \x01(\tR\tcompanyId\x12\x1b\n" +
  360. "\tsource_id\x18\x02 \x01(\tR\bsourceId\x12\x1a\n" +
  361. "\bseverity\x18\x03 \x01(\tR\bseverity\x12\x1a\n" +
  362. "\bcategory\x18\x04 \x01(\tR\bcategory\x12\x14\n" +
  363. "\x05title\x18\x05 \x01(\tR\x05title\x12\x12\n" +
  364. "\x04body\x18\x06 \x01(\tR\x04body\x125\n" +
  365. "\x04data\x18\a \x03(\v2!.broadannounce.v1.Alert.DataEntryR\x04data\x12\x1d\n" +
  366. "\n" +
  367. "dedupe_key\x18\b \x01(\tR\tdedupeKey\x12 \n" +
  368. "\fclient_ts_ms\x18\t \x01(\x03R\n" +
  369. "clientTsMs\x1a7\n" +
  370. "\tDataEntry\x12\x10\n" +
  371. "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
  372. "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xeb\x01\n" +
  373. "\x03Ack\x12\x19\n" +
  374. "\balert_id\x18\x01 \x01(\tR\aalertId\x12\x1d\n" +
  375. "\n" +
  376. "dedupe_key\x18\x02 \x01(\tR\tdedupeKey\x12!\n" +
  377. "\fdedupe_count\x18\x03 \x01(\rR\vdedupeCount\x12$\n" +
  378. "\x0eaccepted_at_ms\x18\x04 \x01(\x03R\facceptedAtMs\x12&\n" +
  379. "\x02ok\x18\n" +
  380. " \x01(\v2\x14.broadannounce.v1.OkH\x00R\x02ok\x12/\n" +
  381. "\x05error\x18\v \x01(\v2\x17.broadannounce.v1.ErrorH\x00R\x05errorB\b\n" +
  382. "\x06result\"\x04\n" +
  383. "\x02Ok\"\xd0\x01\n" +
  384. "\x05Error\x120\n" +
  385. "\x04code\x18\x01 \x01(\x0e2\x1c.broadannounce.v1.Error.CodeR\x04code\x12\x18\n" +
  386. "\amessage\x18\x02 \x01(\tR\amessage\x12$\n" +
  387. "\x0eretry_after_ms\x18\x03 \x01(\x05R\fretryAfterMs\"U\n" +
  388. "\x04Code\x12\v\n" +
  389. "\aUNKNOWN\x10\x00\x12\x13\n" +
  390. "\x0fUNAUTHENTICATED\x10\x01\x12\x10\n" +
  391. "\fRATE_LIMITED\x10\x02\x12\v\n" +
  392. "\aINVALID\x10\x03\x12\f\n" +
  393. "\bINTERNAL\x10\x042L\n" +
  394. "\x06Ingest\x12B\n" +
  395. "\fStreamAlerts\x12\x17.broadannounce.v1.Alert\x1a\x15.broadannounce.v1.Ack(\x010\x01B\xdb\x01\n" +
  396. "\x14com.broadannounce.v1B\vIngestProtoP\x01ZUgit3.techno-world.net/lrosales/broad-announce/gen/go/broadannounce/v1;broadannouncev1\xa2\x02\x03BXX\xaa\x02\x10Broadannounce.V1\xca\x02\x10Broadannounce\\V1\xe2\x02\x1cBroadannounce\\V1\\GPBMetadata\xea\x02\x11Broadannounce::V1b\x06proto3"
  397. var (
  398. file_broadannounce_v1_ingest_proto_rawDescOnce sync.Once
  399. file_broadannounce_v1_ingest_proto_rawDescData []byte
  400. )
  401. func file_broadannounce_v1_ingest_proto_rawDescGZIP() []byte {
  402. file_broadannounce_v1_ingest_proto_rawDescOnce.Do(func() {
  403. file_broadannounce_v1_ingest_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_broadannounce_v1_ingest_proto_rawDesc), len(file_broadannounce_v1_ingest_proto_rawDesc)))
  404. })
  405. return file_broadannounce_v1_ingest_proto_rawDescData
  406. }
  407. var file_broadannounce_v1_ingest_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
  408. var file_broadannounce_v1_ingest_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
  409. var file_broadannounce_v1_ingest_proto_goTypes = []any{
  410. (Error_Code)(0), // 0: broadannounce.v1.Error.Code
  411. (*Alert)(nil), // 1: broadannounce.v1.Alert
  412. (*Ack)(nil), // 2: broadannounce.v1.Ack
  413. (*Ok)(nil), // 3: broadannounce.v1.Ok
  414. (*Error)(nil), // 4: broadannounce.v1.Error
  415. nil, // 5: broadannounce.v1.Alert.DataEntry
  416. }
  417. var file_broadannounce_v1_ingest_proto_depIdxs = []int32{
  418. 5, // 0: broadannounce.v1.Alert.data:type_name -> broadannounce.v1.Alert.DataEntry
  419. 3, // 1: broadannounce.v1.Ack.ok:type_name -> broadannounce.v1.Ok
  420. 4, // 2: broadannounce.v1.Ack.error:type_name -> broadannounce.v1.Error
  421. 0, // 3: broadannounce.v1.Error.code:type_name -> broadannounce.v1.Error.Code
  422. 1, // 4: broadannounce.v1.Ingest.StreamAlerts:input_type -> broadannounce.v1.Alert
  423. 2, // 5: broadannounce.v1.Ingest.StreamAlerts:output_type -> broadannounce.v1.Ack
  424. 5, // [5:6] is the sub-list for method output_type
  425. 4, // [4:5] is the sub-list for method input_type
  426. 4, // [4:4] is the sub-list for extension type_name
  427. 4, // [4:4] is the sub-list for extension extendee
  428. 0, // [0:4] is the sub-list for field type_name
  429. }
  430. func init() { file_broadannounce_v1_ingest_proto_init() }
  431. func file_broadannounce_v1_ingest_proto_init() {
  432. if File_broadannounce_v1_ingest_proto != nil {
  433. return
  434. }
  435. file_broadannounce_v1_ingest_proto_msgTypes[1].OneofWrappers = []any{
  436. (*Ack_Ok)(nil),
  437. (*Ack_Error)(nil),
  438. }
  439. type x struct{}
  440. out := protoimpl.TypeBuilder{
  441. File: protoimpl.DescBuilder{
  442. GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
  443. RawDescriptor: unsafe.Slice(unsafe.StringData(file_broadannounce_v1_ingest_proto_rawDesc), len(file_broadannounce_v1_ingest_proto_rawDesc)),
  444. NumEnums: 1,
  445. NumMessages: 5,
  446. NumExtensions: 0,
  447. NumServices: 1,
  448. },
  449. GoTypes: file_broadannounce_v1_ingest_proto_goTypes,
  450. DependencyIndexes: file_broadannounce_v1_ingest_proto_depIdxs,
  451. EnumInfos: file_broadannounce_v1_ingest_proto_enumTypes,
  452. MessageInfos: file_broadannounce_v1_ingest_proto_msgTypes,
  453. }.Build()
  454. File_broadannounce_v1_ingest_proto = out.File
  455. file_broadannounce_v1_ingest_proto_goTypes = nil
  456. file_broadannounce_v1_ingest_proto_depIdxs = nil
  457. }