| //! HTTP status codes |
| //! |
| //! This module contains HTTP-status code related structs an errors. The main |
| //! type in this module is `StatusCode` which is not intended to be used through |
| //! this module but rather the `http::StatusCode` type. |
| //! |
| //! # Examples |
| //! |
| //! ``` |
| //! use http::StatusCode; |
| //! |
| //! assert_eq!(StatusCode::from_u16(200).unwrap(), StatusCode::OK); |
| //! assert_eq!(StatusCode::NOT_FOUND, 404); |
| //! assert!(StatusCode::OK.is_success()); |
| //! ``` |
| |
| use std::convert::TryFrom; |
| use std::num::NonZeroU16; |
| use std::error::Error; |
| use std::fmt; |
| use std::str::FromStr; |
| |
| /// An HTTP status code (`status-code` in RFC 7230 et al.). |
| /// |
| /// Constants are provided for known status codes, including those in the IANA |
| /// [HTTP Status Code Registry]( |
| /// https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml). |
| /// |
| /// Status code values in the range 100-999 (inclusive) are supported by this |
| /// type. Values in the range 100-599 are semantically classified by the most |
| /// significant digit. See [`StatusCode::is_success`], etc. Values above 599 |
| /// are unclassified but allowed for legacy compatibility, though their use is |
| /// discouraged. Applications may interpret such values as protocol errors. |
| /// |
| /// # Examples |
| /// |
| /// ``` |
| /// use http::StatusCode; |
| /// |
| /// assert_eq!(StatusCode::from_u16(200).unwrap(), StatusCode::OK); |
| /// assert_eq!(StatusCode::NOT_FOUND.as_u16(), 404); |
| /// assert!(StatusCode::OK.is_success()); |
| /// ``` |
| #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| pub struct StatusCode(NonZeroU16); |
| |
| /// A possible error value when converting a `StatusCode` from a `u16` or `&str` |
| /// |
| /// This error indicates that the supplied input was not a valid number, was less |
| /// than 100, or was greater than 999. |
| pub struct InvalidStatusCode { |
| _priv: (), |
| } |
| |
| impl StatusCode { |
| /// Converts a u16 to a status code. |
| /// |
| /// The function validates the correctness of the supplied u16. It must be |
| /// greater or equal to 100 and less than 1000. |
| /// |
| /// # Example |
| /// |
| /// ``` |
| /// use http::StatusCode; |
| /// |
| /// let ok = StatusCode::from_u16(200).unwrap(); |
| /// assert_eq!(ok, StatusCode::OK); |
| /// |
| /// let err = StatusCode::from_u16(99); |
| /// assert!(err.is_err()); |
| /// ``` |
| #[inline] |
| pub fn from_u16(src: u16) -> Result<StatusCode, InvalidStatusCode> { |
| if src < 100 || src >= 1000 { |
| return Err(InvalidStatusCode::new()); |
| } |
| |
| NonZeroU16::new(src) |
| .map(StatusCode) |
| .ok_or_else(InvalidStatusCode::new) |
| } |
| |
| /// Converts a &[u8] to a status code |
| pub fn from_bytes(src: &[u8]) -> Result<StatusCode, InvalidStatusCode> { |
| if src.len() != 3 { |
| return Err(InvalidStatusCode::new()); |
| } |
| |
| let a = src[0].wrapping_sub(b'0') as u16; |
| let b = src[1].wrapping_sub(b'0') as u16; |
| let c = src[2].wrapping_sub(b'0') as u16; |
| |
| if a == 0 || a > 9 || b > 9 || c > 9 { |
| return Err(InvalidStatusCode::new()); |
| } |
| |
| let status = (a * 100) + (b * 10) + c; |
| NonZeroU16::new(status) |
| .map(StatusCode) |
| .ok_or_else(InvalidStatusCode::new) |
| } |
| |
| /// Returns the `u16` corresponding to this `StatusCode`. |
| /// |
| /// # Note |
| /// |
| /// This is the same as the `From<StatusCode>` implementation, but |
| /// included as an inherent method because that implementation doesn't |
| /// appear in rustdocs, as well as a way to force the type instead of |
| /// relying on inference. |
| /// |
| /// # Example |
| /// |
| /// ``` |
| /// let status = http::StatusCode::OK; |
| /// assert_eq!(status.as_u16(), 200); |
| /// ``` |
| #[inline] |
| pub fn as_u16(&self) -> u16 { |
| (*self).into() |
| } |
| |
| /// Returns a &str representation of the `StatusCode` |
| /// |
| /// The return value only includes a numerical representation of the |
| /// status code. The canonical reason is not included. |
| /// |
| /// # Example |
| /// |
| /// ``` |
| /// let status = http::StatusCode::OK; |
| /// assert_eq!(status.as_str(), "200"); |
| /// ``` |
| #[inline] |
| pub fn as_str(&self) -> &str { |
| let offset = (self.0.get() - 100) as usize; |
| let offset = offset * 3; |
| |
| // Invariant: self has checked range [100, 999] and CODE_DIGITS is |
| // ASCII-only, of length 900 * 3 = 2700 bytes |
| |
| #[cfg(debug_assertions)] |
| { &CODE_DIGITS[offset..offset+3] } |
| |
| #[cfg(not(debug_assertions))] |
| unsafe { CODE_DIGITS.get_unchecked(offset..offset+3) } |
| } |
| |
| /// Get the standardised `reason-phrase` for this status code. |
| /// |
| /// This is mostly here for servers writing responses, but could potentially have application |
| /// at other times. |
| /// |
| /// The reason phrase is defined as being exclusively for human readers. You should avoid |
| /// deriving any meaning from it at all costs. |
| /// |
| /// Bear in mind also that in HTTP/2.0 and HTTP/3.0 the reason phrase is abolished from |
| /// transmission, and so this canonical reason phrase really is the only reason phrase you’ll |
| /// find. |
| /// |
| /// # Example |
| /// |
| /// ``` |
| /// let status = http::StatusCode::OK; |
| /// assert_eq!(status.canonical_reason(), Some("OK")); |
| /// ``` |
| pub fn canonical_reason(&self) -> Option<&'static str> { |
| canonical_reason(self.0.get()) |
| } |
| |
| /// Check if status is within 100-199. |
| #[inline] |
| pub fn is_informational(&self) -> bool { |
| 200 > self.0.get() && self.0.get() >= 100 |
| } |
| |
| /// Check if status is within 200-299. |
| #[inline] |
| pub fn is_success(&self) -> bool { |
| 300 > self.0.get() && self.0.get() >= 200 |
| } |
| |
| /// Check if status is within 300-399. |
| #[inline] |
| pub fn is_redirection(&self) -> bool { |
| 400 > self.0.get() && self.0.get() >= 300 |
| } |
| |
| /// Check if status is within 400-499. |
| #[inline] |
| pub fn is_client_error(&self) -> bool { |
| 500 > self.0.get() && self.0.get() >= 400 |
| } |
| |
| /// Check if status is within 500-599. |
| #[inline] |
| pub fn is_server_error(&self) -> bool { |
| 600 > self.0.get() && self.0.get() >= 500 |
| } |
| } |
| |
| impl fmt::Debug for StatusCode { |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt::Debug::fmt(&self.0, f) |
| } |
| } |
| |
| /// Formats the status code, *including* the canonical reason. |
| /// |
| /// # Example |
| /// |
| /// ``` |
| /// # use http::StatusCode; |
| /// assert_eq!(format!("{}", StatusCode::OK), "200 OK"); |
| /// ``` |
| impl fmt::Display for StatusCode { |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| write!( |
| f, |
| "{} {}", |
| u16::from(*self), |
| self.canonical_reason().unwrap_or("<unknown status code>") |
| ) |
| } |
| } |
| |
| impl Default for StatusCode { |
| #[inline] |
| fn default() -> StatusCode { |
| StatusCode::OK |
| } |
| } |
| |
| impl PartialEq<u16> for StatusCode { |
| #[inline] |
| fn eq(&self, other: &u16) -> bool { |
| self.as_u16() == *other |
| } |
| } |
| |
| impl PartialEq<StatusCode> for u16 { |
| #[inline] |
| fn eq(&self, other: &StatusCode) -> bool { |
| *self == other.as_u16() |
| } |
| } |
| |
| impl From<StatusCode> for u16 { |
| #[inline] |
| fn from(status: StatusCode) -> u16 { |
| status.0.get() |
| } |
| } |
| |
| impl FromStr for StatusCode { |
| type Err = InvalidStatusCode; |
| |
| fn from_str(s: &str) -> Result<StatusCode, InvalidStatusCode> { |
| StatusCode::from_bytes(s.as_ref()) |
| } |
| } |
| |
| impl<'a> From<&'a StatusCode> for StatusCode { |
| #[inline] |
| fn from(t: &'a StatusCode) -> Self { |
| t.clone() |
| } |
| } |
| |
| impl<'a> TryFrom<&'a [u8]> for StatusCode { |
| type Error = InvalidStatusCode; |
| |
| #[inline] |
| fn try_from(t: &'a [u8]) -> Result<Self, Self::Error> { |
| StatusCode::from_bytes(t) |
| } |
| } |
| |
| impl<'a> TryFrom<&'a str> for StatusCode { |
| type Error = InvalidStatusCode; |
| |
| #[inline] |
| fn try_from(t: &'a str) -> Result<Self, Self::Error> { |
| t.parse() |
| } |
| } |
| |
| impl TryFrom<u16> for StatusCode { |
| type Error = InvalidStatusCode; |
| |
| #[inline] |
| fn try_from(t: u16) -> Result<Self, Self::Error> { |
| StatusCode::from_u16(t) |
| } |
| } |
| |
| macro_rules! status_codes { |
| ( |
| $( |
| $(#[$docs:meta])* |
| ($num:expr, $konst:ident, $phrase:expr); |
| )+ |
| ) => { |
| impl StatusCode { |
| $( |
| $(#[$docs])* |
| pub const $konst: StatusCode = StatusCode(unsafe { NonZeroU16::new_unchecked($num) }); |
| )+ |
| |
| } |
| |
| fn canonical_reason(num: u16) -> Option<&'static str> { |
| match num { |
| $( |
| $num => Some($phrase), |
| )+ |
| _ => None |
| } |
| } |
| } |
| } |
| |
| status_codes! { |
| /// 100 Continue |
| /// [[RFC7231, Section 6.2.1](https://tools.ietf.org/html/rfc7231#section-6.2.1)] |
| (100, CONTINUE, "Continue"); |
| /// 101 Switching Protocols |
| /// [[RFC7231, Section 6.2.2](https://tools.ietf.org/html/rfc7231#section-6.2.2)] |
| (101, SWITCHING_PROTOCOLS, "Switching Protocols"); |
| /// 102 Processing |
| /// [[RFC2518](https://tools.ietf.org/html/rfc2518)] |
| (102, PROCESSING, "Processing"); |
| |
| /// 200 OK |
| /// [[RFC7231, Section 6.3.1](https://tools.ietf.org/html/rfc7231#section-6.3.1)] |
| (200, OK, "OK"); |
| /// 201 Created |
| /// [[RFC7231, Section 6.3.2](https://tools.ietf.org/html/rfc7231#section-6.3.2)] |
| (201, CREATED, "Created"); |
| /// 202 Accepted |
| /// [[RFC7231, Section 6.3.3](https://tools.ietf.org/html/rfc7231#section-6.3.3)] |
| (202, ACCEPTED, "Accepted"); |
| /// 203 Non-Authoritative Information |
| /// [[RFC7231, Section 6.3.4](https://tools.ietf.org/html/rfc7231#section-6.3.4)] |
| (203, NON_AUTHORITATIVE_INFORMATION, "Non Authoritative Information"); |
| /// 204 No Content |
| /// [[RFC7231, Section 6.3.5](https://tools.ietf.org/html/rfc7231#section-6.3.5)] |
| (204, NO_CONTENT, "No Content"); |
| /// 205 Reset Content |
| /// [[RFC7231, Section 6.3.6](https://tools.ietf.org/html/rfc7231#section-6.3.6)] |
| (205, RESET_CONTENT, "Reset Content"); |
| /// 206 Partial Content |
| /// [[RFC7233, Section 4.1](https://tools.ietf.org/html/rfc7233#section-4.1)] |
| (206, PARTIAL_CONTENT, "Partial Content"); |
| /// 207 Multi-Status |
| /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] |
| (207, MULTI_STATUS, "Multi-Status"); |
| /// 208 Already Reported |
| /// [[RFC5842](https://tools.ietf.org/html/rfc5842)] |
| (208, ALREADY_REPORTED, "Already Reported"); |
| |
| /// 226 IM Used |
| /// [[RFC3229](https://tools.ietf.org/html/rfc3229)] |
| (226, IM_USED, "IM Used"); |
| |
| /// 300 Multiple Choices |
| /// [[RFC7231, Section 6.4.1](https://tools.ietf.org/html/rfc7231#section-6.4.1)] |
| (300, MULTIPLE_CHOICES, "Multiple Choices"); |
| /// 301 Moved Permanently |
| /// [[RFC7231, Section 6.4.2](https://tools.ietf.org/html/rfc7231#section-6.4.2)] |
| (301, MOVED_PERMANENTLY, "Moved Permanently"); |
| /// 302 Found |
| /// [[RFC7231, Section 6.4.3](https://tools.ietf.org/html/rfc7231#section-6.4.3)] |
| (302, FOUND, "Found"); |
| /// 303 See Other |
| /// [[RFC7231, Section 6.4.4](https://tools.ietf.org/html/rfc7231#section-6.4.4)] |
| (303, SEE_OTHER, "See Other"); |
| /// 304 Not Modified |
| /// [[RFC7232, Section 4.1](https://tools.ietf.org/html/rfc7232#section-4.1)] |
| (304, NOT_MODIFIED, "Not Modified"); |
| /// 305 Use Proxy |
| /// [[RFC7231, Section 6.4.5](https://tools.ietf.org/html/rfc7231#section-6.4.5)] |
| (305, USE_PROXY, "Use Proxy"); |
| /// 307 Temporary Redirect |
| /// [[RFC7231, Section 6.4.7](https://tools.ietf.org/html/rfc7231#section-6.4.7)] |
| (307, TEMPORARY_REDIRECT, "Temporary Redirect"); |
| /// 308 Permanent Redirect |
| /// [[RFC7238](https://tools.ietf.org/html/rfc7238)] |
| (308, PERMANENT_REDIRECT, "Permanent Redirect"); |
| |
| /// 400 Bad Request |
| /// [[RFC7231, Section 6.5.1](https://tools.ietf.org/html/rfc7231#section-6.5.1)] |
| (400, BAD_REQUEST, "Bad Request"); |
| /// 401 Unauthorized |
| /// [[RFC7235, Section 3.1](https://tools.ietf.org/html/rfc7235#section-3.1)] |
| (401, UNAUTHORIZED, "Unauthorized"); |
| /// 402 Payment Required |
| /// [[RFC7231, Section 6.5.2](https://tools.ietf.org/html/rfc7231#section-6.5.2)] |
| (402, PAYMENT_REQUIRED, "Payment Required"); |
| /// 403 Forbidden |
| /// [[RFC7231, Section 6.5.3](https://tools.ietf.org/html/rfc7231#section-6.5.3)] |
| (403, FORBIDDEN, "Forbidden"); |
| /// 404 Not Found |
| /// [[RFC7231, Section 6.5.4](https://tools.ietf.org/html/rfc7231#section-6.5.4)] |
| (404, NOT_FOUND, "Not Found"); |
| /// 405 Method Not Allowed |
| /// [[RFC7231, Section 6.5.5](https://tools.ietf.org/html/rfc7231#section-6.5.5)] |
| (405, METHOD_NOT_ALLOWED, "Method Not Allowed"); |
| /// 406 Not Acceptable |
| /// [[RFC7231, Section 6.5.6](https://tools.ietf.org/html/rfc7231#section-6.5.6)] |
| (406, NOT_ACCEPTABLE, "Not Acceptable"); |
| /// 407 Proxy Authentication Required |
| /// [[RFC7235, Section 3.2](https://tools.ietf.org/html/rfc7235#section-3.2)] |
| (407, PROXY_AUTHENTICATION_REQUIRED, "Proxy Authentication Required"); |
| /// 408 Request Timeout |
| /// [[RFC7231, Section 6.5.7](https://tools.ietf.org/html/rfc7231#section-6.5.7)] |
| (408, REQUEST_TIMEOUT, "Request Timeout"); |
| /// 409 Conflict |
| /// [[RFC7231, Section 6.5.8](https://tools.ietf.org/html/rfc7231#section-6.5.8)] |
| (409, CONFLICT, "Conflict"); |
| /// 410 Gone |
| /// [[RFC7231, Section 6.5.9](https://tools.ietf.org/html/rfc7231#section-6.5.9)] |
| (410, GONE, "Gone"); |
| /// 411 Length Required |
| /// [[RFC7231, Section 6.5.10](https://tools.ietf.org/html/rfc7231#section-6.5.10)] |
| (411, LENGTH_REQUIRED, "Length Required"); |
| /// 412 Precondition Failed |
| /// [[RFC7232, Section 4.2](https://tools.ietf.org/html/rfc7232#section-4.2)] |
| (412, PRECONDITION_FAILED, "Precondition Failed"); |
| /// 413 Payload Too Large |
| /// [[RFC7231, Section 6.5.11](https://tools.ietf.org/html/rfc7231#section-6.5.11)] |
| (413, PAYLOAD_TOO_LARGE, "Payload Too Large"); |
| /// 414 URI Too Long |
| /// [[RFC7231, Section 6.5.12](https://tools.ietf.org/html/rfc7231#section-6.5.12)] |
| (414, URI_TOO_LONG, "URI Too Long"); |
| /// 415 Unsupported Media Type |
| /// [[RFC7231, Section 6.5.13](https://tools.ietf.org/html/rfc7231#section-6.5.13)] |
| (415, UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type"); |
| /// 416 Range Not Satisfiable |
| /// [[RFC7233, Section 4.4](https://tools.ietf.org/html/rfc7233#section-4.4)] |
| (416, RANGE_NOT_SATISFIABLE, "Range Not Satisfiable"); |
| /// 417 Expectation Failed |
| /// [[RFC7231, Section 6.5.14](https://tools.ietf.org/html/rfc7231#section-6.5.14)] |
| (417, EXPECTATION_FAILED, "Expectation Failed"); |
| /// 418 I'm a teapot |
| /// [curiously not registered by IANA but [RFC2324](https://tools.ietf.org/html/rfc2324)] |
| (418, IM_A_TEAPOT, "I'm a teapot"); |
| |
| /// 421 Misdirected Request |
| /// [RFC7540, Section 9.1.2](http://tools.ietf.org/html/rfc7540#section-9.1.2) |
| (421, MISDIRECTED_REQUEST, "Misdirected Request"); |
| /// 422 Unprocessable Entity |
| /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] |
| (422, UNPROCESSABLE_ENTITY, "Unprocessable Entity"); |
| /// 423 Locked |
| /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] |
| (423, LOCKED, "Locked"); |
| /// 424 Failed Dependency |
| /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] |
| (424, FAILED_DEPENDENCY, "Failed Dependency"); |
| |
| /// 426 Upgrade Required |
| /// [[RFC7231, Section 6.5.15](https://tools.ietf.org/html/rfc7231#section-6.5.15)] |
| (426, UPGRADE_REQUIRED, "Upgrade Required"); |
| |
| /// 428 Precondition Required |
| /// [[RFC6585](https://tools.ietf.org/html/rfc6585)] |
| (428, PRECONDITION_REQUIRED, "Precondition Required"); |
| /// 429 Too Many Requests |
| /// [[RFC6585](https://tools.ietf.org/html/rfc6585)] |
| (429, TOO_MANY_REQUESTS, "Too Many Requests"); |
| |
| /// 431 Request Header Fields Too Large |
| /// [[RFC6585](https://tools.ietf.org/html/rfc6585)] |
| (431, REQUEST_HEADER_FIELDS_TOO_LARGE, "Request Header Fields Too Large"); |
| |
| /// 451 Unavailable For Legal Reasons |
| /// [[RFC7725](http://tools.ietf.org/html/rfc7725)] |
| (451, UNAVAILABLE_FOR_LEGAL_REASONS, "Unavailable For Legal Reasons"); |
| |
| /// 500 Internal Server Error |
| /// [[RFC7231, Section 6.6.1](https://tools.ietf.org/html/rfc7231#section-6.6.1)] |
| (500, INTERNAL_SERVER_ERROR, "Internal Server Error"); |
| /// 501 Not Implemented |
| /// [[RFC7231, Section 6.6.2](https://tools.ietf.org/html/rfc7231#section-6.6.2)] |
| (501, NOT_IMPLEMENTED, "Not Implemented"); |
| /// 502 Bad Gateway |
| /// [[RFC7231, Section 6.6.3](https://tools.ietf.org/html/rfc7231#section-6.6.3)] |
| (502, BAD_GATEWAY, "Bad Gateway"); |
| /// 503 Service Unavailable |
| /// [[RFC7231, Section 6.6.4](https://tools.ietf.org/html/rfc7231#section-6.6.4)] |
| (503, SERVICE_UNAVAILABLE, "Service Unavailable"); |
| /// 504 Gateway Timeout |
| /// [[RFC7231, Section 6.6.5](https://tools.ietf.org/html/rfc7231#section-6.6.5)] |
| (504, GATEWAY_TIMEOUT, "Gateway Timeout"); |
| /// 505 HTTP Version Not Supported |
| /// [[RFC7231, Section 6.6.6](https://tools.ietf.org/html/rfc7231#section-6.6.6)] |
| (505, HTTP_VERSION_NOT_SUPPORTED, "HTTP Version Not Supported"); |
| /// 506 Variant Also Negotiates |
| /// [[RFC2295](https://tools.ietf.org/html/rfc2295)] |
| (506, VARIANT_ALSO_NEGOTIATES, "Variant Also Negotiates"); |
| /// 507 Insufficient Storage |
| /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] |
| (507, INSUFFICIENT_STORAGE, "Insufficient Storage"); |
| /// 508 Loop Detected |
| /// [[RFC5842](https://tools.ietf.org/html/rfc5842)] |
| (508, LOOP_DETECTED, "Loop Detected"); |
| |
| /// 510 Not Extended |
| /// [[RFC2774](https://tools.ietf.org/html/rfc2774)] |
| (510, NOT_EXTENDED, "Not Extended"); |
| /// 511 Network Authentication Required |
| /// [[RFC6585](https://tools.ietf.org/html/rfc6585)] |
| (511, NETWORK_AUTHENTICATION_REQUIRED, "Network Authentication Required"); |
| } |
| |
| impl InvalidStatusCode { |
| fn new() -> InvalidStatusCode { |
| InvalidStatusCode { |
| _priv: (), |
| } |
| } |
| } |
| |
| impl fmt::Debug for InvalidStatusCode { |
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| f.debug_struct("InvalidStatusCode") |
| // skip _priv noise |
| .finish() |
| } |
| } |
| |
| impl fmt::Display for InvalidStatusCode { |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| f.write_str("invalid status code") |
| } |
| } |
| |
| impl Error for InvalidStatusCode {} |
| |
| // A string of packed 3-ASCII-digit status code values for the supported range |
| // of [100, 999] (900 codes, 2700 bytes). |
| const CODE_DIGITS: &'static str = "\ |
| 100101102103104105106107108109110111112113114115116117118119\ |
| 120121122123124125126127128129130131132133134135136137138139\ |
| 140141142143144145146147148149150151152153154155156157158159\ |
| 160161162163164165166167168169170171172173174175176177178179\ |
| 180181182183184185186187188189190191192193194195196197198199\ |
| 200201202203204205206207208209210211212213214215216217218219\ |
| 220221222223224225226227228229230231232233234235236237238239\ |
| 240241242243244245246247248249250251252253254255256257258259\ |
| 260261262263264265266267268269270271272273274275276277278279\ |
| 280281282283284285286287288289290291292293294295296297298299\ |
| 300301302303304305306307308309310311312313314315316317318319\ |
| 320321322323324325326327328329330331332333334335336337338339\ |
| 340341342343344345346347348349350351352353354355356357358359\ |
| 360361362363364365366367368369370371372373374375376377378379\ |
| 380381382383384385386387388389390391392393394395396397398399\ |
| 400401402403404405406407408409410411412413414415416417418419\ |
| 420421422423424425426427428429430431432433434435436437438439\ |
| 440441442443444445446447448449450451452453454455456457458459\ |
| 460461462463464465466467468469470471472473474475476477478479\ |
| 480481482483484485486487488489490491492493494495496497498499\ |
| 500501502503504505506507508509510511512513514515516517518519\ |
| 520521522523524525526527528529530531532533534535536537538539\ |
| 540541542543544545546547548549550551552553554555556557558559\ |
| 560561562563564565566567568569570571572573574575576577578579\ |
| 580581582583584585586587588589590591592593594595596597598599\ |
| 600601602603604605606607608609610611612613614615616617618619\ |
| 620621622623624625626627628629630631632633634635636637638639\ |
| 640641642643644645646647648649650651652653654655656657658659\ |
| 660661662663664665666667668669670671672673674675676677678679\ |
| 680681682683684685686687688689690691692693694695696697698699\ |
| 700701702703704705706707708709710711712713714715716717718719\ |
| 720721722723724725726727728729730731732733734735736737738739\ |
| 740741742743744745746747748749750751752753754755756757758759\ |
| 760761762763764765766767768769770771772773774775776777778779\ |
| 780781782783784785786787788789790791792793794795796797798799\ |
| 800801802803804805806807808809810811812813814815816817818819\ |
| 820821822823824825826827828829830831832833834835836837838839\ |
| 840841842843844845846847848849850851852853854855856857858859\ |
| 860861862863864865866867868869870871872873874875876877878879\ |
| 880881882883884885886887888889890891892893894895896897898899\ |
| 900901902903904905906907908909910911912913914915916917918919\ |
| 920921922923924925926927928929930931932933934935936937938939\ |
| 940941942943944945946947948949950951952953954955956957958959\ |
| 960961962963964965966967968969970971972973974975976977978979\ |
| 980981982983984985986987988989990991992993994995996997998999"; |