feat: add video response
- started timeago_table
This commit is contained in:
parent
346406c1c8
commit
9da166304a
21 changed files with 41070 additions and 9244 deletions
|
|
@ -37,3 +37,5 @@ rstest = "0.15.0"
|
|||
temp_testdir = "0.2.3"
|
||||
insta = "1.17.1"
|
||||
velcro = "0.5.3"
|
||||
unic-langid = "0.9.0"
|
||||
intl_pluralrules = "7.0.1"
|
||||
|
|
|
|||
4790
notes/next/comment_replies.json
Normal file
4790
notes/next/comment_replies.json
Normal file
File diff suppressed because it is too large
Load diff
9699
notes/next/next_comments_latest.json
Normal file
9699
notes/next/next_comments_latest.json
Normal file
File diff suppressed because it is too large
Load diff
7184
notes/next/next_comments_latest_nouser.json
Normal file
7184
notes/next/next_comments_latest_nouser.json
Normal file
File diff suppressed because it is too large
Load diff
10899
notes/next/next_mv.json
Normal file
10899
notes/next/next_mv.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
41
src/client/channel.rs
Normal file
41
src/client/channel.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
use anyhow::Result;
|
||||
use reqwest::Method;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::{response, ClientType, ContextYT, RustyTube};
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct QChannel {
|
||||
context: ContextYT,
|
||||
browse_id: String,
|
||||
params: String,
|
||||
}
|
||||
|
||||
impl RustyTube {
|
||||
async fn get_channel_response(&self, channel_id: &str) -> Result<response::Channel> {
|
||||
let client = self.get_ytclient(ClientType::Desktop);
|
||||
let context = client.get_context(true).await;
|
||||
|
||||
let request_body = QChannel {
|
||||
context,
|
||||
browse_id: channel_id.to_owned(),
|
||||
params: "EgZ2aWRlb3PyBgQKAjoA".to_owned(),
|
||||
};
|
||||
|
||||
let resp = client
|
||||
.request_builder(Method::POST, "browse")
|
||||
.await
|
||||
.json(&request_body)
|
||||
.send()
|
||||
.await?
|
||||
.error_for_status()?;
|
||||
|
||||
Ok(resp.json::<response::Channel>().await?)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
pub mod player;
|
||||
pub mod playlist;
|
||||
pub mod video;
|
||||
|
||||
mod response;
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use serde::Deserialize;
|
|||
use serde_with::serde_as;
|
||||
use serde_with::VecSkipError;
|
||||
|
||||
use super::TimeOverlay;
|
||||
use super::{ContentRenderer, ContentsRenderer, Thumbnails, VideoListItem};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
|
|
@ -64,24 +65,10 @@ pub struct ChannelVideo {
|
|||
pub thumbnail: Thumbnails,
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub title: String,
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub published_time_text: String,
|
||||
#[serde_as(as = "Option<crate::serializer::text::Text>")]
|
||||
pub published_time_text: Option<String>,
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub view_count_text: String,
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub thumbnail_overlays: Vec<TimeOverlayWrap>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TimeOverlayWrap {
|
||||
pub thumbnail_overlay_time_status_renderer: TimeOverlay,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TimeOverlay {
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub text: String,
|
||||
pub thumbnail_overlays: Vec<TimeOverlay>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,15 @@ pub mod channel;
|
|||
pub mod player;
|
||||
pub mod playlist;
|
||||
pub mod playlist_music;
|
||||
pub mod video;
|
||||
|
||||
pub use channel::Channel;
|
||||
pub use player::Player;
|
||||
pub use playlist::Playlist;
|
||||
pub use playlist_music::PlaylistMusic;
|
||||
pub use video::Video;
|
||||
pub use video::VideoComments;
|
||||
pub use video::VideoRecommendations;
|
||||
|
||||
use serde::Deserialize;
|
||||
use serde_with::{serde_as, DefaultOnError, VecSkipError};
|
||||
|
|
@ -50,7 +54,7 @@ pub struct Thumbnail {
|
|||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum VideoListItem<T> {
|
||||
#[serde(alias = "playlistVideoRenderer")]
|
||||
#[serde(alias = "playlistVideoRenderer", alias = "compactVideoRenderer")]
|
||||
GridVideoRenderer {
|
||||
#[serde(flatten)]
|
||||
video: T,
|
||||
|
|
@ -73,6 +77,77 @@ pub struct ContinuationCommand {
|
|||
pub token: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Icon {
|
||||
pub icon_type: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct VideoOwner {
|
||||
pub video_owner_renderer: VideoOwnerRenderer,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct VideoOwnerRenderer {
|
||||
#[serde_as(as = "crate::serializer::text::TextLink")]
|
||||
pub title: TextLink,
|
||||
pub thumbnail: Thumbnails,
|
||||
#[serde_as(as = "Option<crate::serializer::text::Text>")]
|
||||
pub subscriber_count_text: Option<String>,
|
||||
#[serde(default)]
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub badges: Vec<UserBadge>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UserBadge {
|
||||
pub metadata_badge_renderer: UserBadgeRenderer,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UserBadgeRenderer {
|
||||
pub style: UserBadgeStyle,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
pub enum UserBadgeStyle {
|
||||
BadgeStyleTypeVerified,
|
||||
BadgeStyleTypeVerifiedArtist,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TimeOverlay {
|
||||
pub thumbnail_overlay_time_status_renderer: TimeOverlayRenderer,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TimeOverlayRenderer {
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub text: String,
|
||||
#[serde(default)]
|
||||
#[serde_as(deserialize_as = "DefaultOnError")]
|
||||
pub style: TimeOverlayStyle,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
pub enum TimeOverlayStyle {
|
||||
#[default]
|
||||
Default,
|
||||
Live,
|
||||
Shorts,
|
||||
}
|
||||
|
||||
// YouTube Music
|
||||
|
||||
#[serde_as]
|
||||
|
|
@ -80,13 +155,10 @@ pub struct ContinuationCommand {
|
|||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MusicItem {
|
||||
pub thumbnail: MusicThumbnailRenderer,
|
||||
#[serde(default)]
|
||||
#[serde_as(deserialize_as = "DefaultOnError")]
|
||||
pub playlist_item_data: Option<PlaylistItemData>,
|
||||
#[serde(default)]
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub flex_columns: Vec<MusicColumn>,
|
||||
#[serde(default)]
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub fixed_columns: Vec<MusicColumn>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ pub struct Format {
|
|||
#[serde_as(as = "JsonString")]
|
||||
pub content_length: u64,
|
||||
|
||||
#[serde(default)]
|
||||
#[serde_as(deserialize_as = "DefaultOnError")]
|
||||
pub quality: Option<Quality>,
|
||||
pub fps: Option<u8>,
|
||||
|
|
@ -90,7 +89,6 @@ pub struct Format {
|
|||
pub color_info: Option<ColorInfo>,
|
||||
|
||||
// Audio only
|
||||
#[serde(default)]
|
||||
#[serde_as(deserialize_as = "DefaultOnError")]
|
||||
pub audio_quality: Option<AudioQuality>,
|
||||
#[serde_as(as = "Option<JsonString>")]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ use serde_with::{json::JsonString, DefaultOnError, VecSkipError};
|
|||
|
||||
use crate::serializer::text::{Text, TextLink};
|
||||
|
||||
use super::{ContentRenderer, ContentsRenderer, Thumbnails, ThumbnailsWrap, VideoListItem};
|
||||
use super::{
|
||||
ContentRenderer, ContentsRenderer, Thumbnails, ThumbnailsWrap, VideoListItem, VideoOwner,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
|
@ -73,7 +75,6 @@ pub struct PlaylistVideo {
|
|||
pub channel: TextLink,
|
||||
#[serde_as(as = "JsonString")]
|
||||
pub length_seconds: u32,
|
||||
pub is_playable: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
|
|
@ -89,7 +90,6 @@ pub struct HeaderRenderer {
|
|||
pub playlist_id: String,
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub title: String,
|
||||
#[serde(default)]
|
||||
#[serde_as(as = "DefaultOnError<Option<crate::serializer::text::Text>>")]
|
||||
pub description_text: Option<String>,
|
||||
/// `"495", " videos"`
|
||||
|
|
@ -122,7 +122,7 @@ pub enum SidebarRendererItem {
|
|||
// stats: Vec<Text>,
|
||||
},
|
||||
#[serde(rename_all = "camelCase")]
|
||||
PlaylistSidebarSecondaryInfoRenderer { video_owner: VideoOwnerWrap },
|
||||
PlaylistSidebarSecondaryInfoRenderer { video_owner: VideoOwner },
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
|
|
@ -133,20 +133,6 @@ pub struct PlaylistThumbnailRenderer {
|
|||
pub playlist_video_thumbnail_renderer: ThumbnailsWrap,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct VideoOwnerWrap {
|
||||
pub video_owner_renderer: VideoOwner,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct VideoOwner {
|
||||
#[serde_as(as = "crate::serializer::text::TextLink")]
|
||||
pub title: TextLink,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct OnResponseReceivedAction {
|
||||
|
|
|
|||
435
src/client/response/video.rs
Normal file
435
src/client/response/video.rs
Normal file
|
|
@ -0,0 +1,435 @@
|
|||
use serde::Deserialize;
|
||||
use serde_with::serde_as;
|
||||
use serde_with::{DefaultOnError, VecSkipError};
|
||||
|
||||
use crate::serializer::text::TextLink;
|
||||
|
||||
use super::{ContinuationEndpoint, Icon, Thumbnails, VideoListItem, VideoOwner};
|
||||
|
||||
/// Video info response
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Video {
|
||||
pub contents: Contents,
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub engagement_panels: Vec<EngagementPanel>,
|
||||
}
|
||||
|
||||
/// Video recommendations response
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct VideoRecommendations {
|
||||
pub on_response_received_endpoints: Vec<RecommendationsContItem>,
|
||||
}
|
||||
|
||||
/// Video comments response
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct VideoComments {
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub on_response_received_endpoints: Vec<CommentsContItem>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Contents {
|
||||
pub two_column_watch_next_results: TwoColumnWatchNextResults,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TwoColumnWatchNextResults {
|
||||
pub results: VideoResultsWrap,
|
||||
pub secondary_results: RecommendationResultsWrap,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct VideoResultsWrap {
|
||||
pub results: VideoResults,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct VideoResults {
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub contents: Vec<VideoResultsItem>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum VideoResultsItem {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
VideoPrimaryInfoRenderer {
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
title: String,
|
||||
view_count: ViewCountWrap,
|
||||
video_actions: VideoActions,
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
date_text: String,
|
||||
},
|
||||
#[serde(rename_all = "camelCase")]
|
||||
VideoSecondaryInfoRenderer {
|
||||
owner: VideoOwner,
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
description: String,
|
||||
#[serde_as(deserialize_as = "DefaultOnError")]
|
||||
metadata_row_container: Option<MetadataRowContainer>,
|
||||
},
|
||||
#[serde(rename_all = "camelCase")]
|
||||
ItemSectionRenderer {
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
contents: Vec<ItemSection>,
|
||||
section_identifier: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ViewCountWrap {
|
||||
pub video_view_count_renderer: ViewCount,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ViewCount {
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub view_count: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct VideoActions {
|
||||
pub menu_renderer: VideoActionsMenu,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct VideoActionsMenu {
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub top_level_buttons: Vec<ToggleButtonWrap>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ToggleButtonWrap {
|
||||
pub toggle_button_renderer: ToggleButton,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ToggleButton {
|
||||
pub default_icon: Icon,
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub default_text: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MetadataRowContainer {
|
||||
pub metadata_row_container_renderer: MetadataRowContainerRenderer,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MetadataRowContainerRenderer {
|
||||
pub rows: Vec<MetadataRow>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MetadataRow {
|
||||
pub metadata_row_renderer: MetadataRowRenderer,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MetadataRowRenderer {
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub title: String,
|
||||
#[serde_as(as = "Vec<crate::serializer::text::TextLinks>")]
|
||||
pub contents: Vec<Vec<TextLink>>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum ItemSection {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
CommentsEntryPointHeaderRenderer {
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
header_text: String,
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
comment_count: String,
|
||||
},
|
||||
#[serde(rename_all = "camelCase")]
|
||||
ContinuationItemRenderer {
|
||||
continuation_endpoint: ContinuationEndpoint,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RecommendationResultsWrap {
|
||||
pub secondary_results: RecommendationResults,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RecommendationResults {
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub results: Vec<VideoListItem<RecommendedVideo>>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RecommendedVideo {
|
||||
pub video_id: String,
|
||||
pub thumbnail: Thumbnails,
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub title: String,
|
||||
#[serde(rename = "shortBylineText")]
|
||||
#[serde_as(as = "crate::serializer::text::TextLink")]
|
||||
pub channel: TextLink,
|
||||
#[serde_as(as = "Option<crate::serializer::text::Text>")]
|
||||
pub length_text: Option<String>,
|
||||
#[serde_as(as = "Option<crate::serializer::text::Text>")]
|
||||
pub published_time_text: Option<String>,
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub view_count_text: String,
|
||||
#[serde(default)]
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub badges: Vec<VideoBadge>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct VideoBadge {
|
||||
pub metadata_badge_renderer: VideoBadgeRenderer,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct VideoBadgeRenderer {
|
||||
pub style: VideoBadgeStyle,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
pub enum VideoBadgeStyle {
|
||||
BadgeStyleTypeLiveNow,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EngagementPanel {
|
||||
pub engagement_panel_section_list_renderer: EngagementPanelRenderer,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EngagementPanelRenderer {
|
||||
pub header: EngagementPanelHeader,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EngagementPanelHeader {
|
||||
pub engagement_panel_title_header_renderer: EngagementPanelHeaderRenderer,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EngagementPanelHeaderRenderer {
|
||||
pub menu: EngagementPanelMenu,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EngagementPanelMenu {
|
||||
pub sort_filter_sub_menu_renderer: EngagementPanelMenuRenderer,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EngagementPanelMenuRenderer {
|
||||
pub sub_menu_items: Vec<EngagementPanelMenuItem>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EngagementPanelMenuItem {
|
||||
pub service_endpoint: ContinuationEndpoint,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RecommendationsContItem {
|
||||
pub append_continuation_items_action: AppendRecommendations,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AppendRecommendations {
|
||||
pub continuation_items: Vec<VideoListItem<RecommendedVideo>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CommentsContItem {
|
||||
#[serde(alias = "reloadContinuationItemsCommand")]
|
||||
pub append_continuation_items_action: AppendComments,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AppendComments {
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub continuation_items: Vec<CommentListItem>,
|
||||
pub target_id: String,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum CommentListItem {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
CommentThreadRenderer {
|
||||
comment: Comment,
|
||||
#[serde(default)]
|
||||
replies: Replies,
|
||||
#[serde(default)]
|
||||
#[serde_as(deserialize_as = "DefaultOnError")]
|
||||
rendering_priority: CommentPriority,
|
||||
},
|
||||
CommentRenderer {
|
||||
#[serde(flatten)]
|
||||
comment: CommentRenderer,
|
||||
},
|
||||
#[serde(rename_all = "camelCase")]
|
||||
ContinuationItemRenderer {
|
||||
continuation_endpoint: ContinuationEndpoint,
|
||||
},
|
||||
|
||||
// TODO: TMP
|
||||
#[serde(rename_all = "camelCase")]
|
||||
CommentsHeaderRenderer { count_text: Option<String> },
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Comment {
|
||||
pub comment_renderer: CommentRenderer,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CommentRenderer {
|
||||
/*
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub author_text: String,
|
||||
pub author_thumbnail: Thumbnails,
|
||||
pub author_endpoint: AuthorEndpoint,
|
||||
*/
|
||||
// There may be comments with missing authors (possibly deleted users?)
|
||||
#[serde_as(as = "DefaultOnError<Option<crate::serializer::text::Text>>")]
|
||||
pub author_text: Option<String>,
|
||||
pub author_thumbnail: Thumbnails,
|
||||
#[serde_as(as = "DefaultOnError")]
|
||||
pub author_endpoint: Option<AuthorEndpoint>,
|
||||
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub content_text: String,
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
pub published_time_text: String,
|
||||
pub comment_id: String,
|
||||
pub author_is_channel_owner: bool,
|
||||
#[serde_as(as = "Option<crate::serializer::text::Text>")]
|
||||
pub vote_count: Option<String>,
|
||||
pub author_comment_badge: Option<AuthorCommentBadge>,
|
||||
#[serde(default)]
|
||||
pub reply_count: u32,
|
||||
pub action_buttons: CommentActionButtons,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AuthorEndpoint {
|
||||
pub browse_endpoint: BrowseEndpoint,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BrowseEndpoint {
|
||||
pub browse_id: String,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Copy, Debug, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
pub enum CommentPriority {
|
||||
#[default]
|
||||
RenderingPriorityUnknown,
|
||||
RenderingPriorityPinnedComment,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Replies {
|
||||
pub comment_replies_renderer: RepliesRenderer,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Default, Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RepliesRenderer {
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub contents: Vec<CommentListItem>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CommentActionButtons {
|
||||
pub comment_action_buttons_renderer: CommentActionButtonsRenderer,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CommentActionButtonsRenderer {
|
||||
pub creator_heart: Option<CreatorHeart>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreatorHeart {
|
||||
pub creator_heart_renderer: CreatorHeartRenderer,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreatorHeartRenderer {
|
||||
pub is_hearted: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AuthorCommentBadge {
|
||||
pub author_comment_badge_renderer: AuthorCommentBadgeRenderer,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AuthorCommentBadgeRenderer {
|
||||
pub icon: Icon,
|
||||
}
|
||||
|
|
@ -8,9 +8,8 @@ use serde::{Deserialize, Serialize};
|
|||
use serde_with::serde_as;
|
||||
use serde_with::VecSkipError;
|
||||
|
||||
use crate::client::ClientType;
|
||||
use crate::client::ContextYT;
|
||||
use crate::client::RustyTube;
|
||||
use crate::client::response::Icon;
|
||||
use crate::client::{ClientType, ContextYT, RustyTube};
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
|
@ -77,12 +76,6 @@ struct CompactLinkRenderer {
|
|||
service_endpoint: ServiceEndpoint<MenuAction>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Icon {
|
||||
icon_type: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct ServiceEndpoint<T> {
|
||||
|
|
@ -161,7 +154,7 @@ async fn generate_locales() {
|
|||
code.push_str(&format!(" /// {}\n ", n));
|
||||
|
||||
if c.contains('-') {
|
||||
code.push_str(&format!("#[serde(rename=\"{}\")]\n ", c));
|
||||
code.push_str(&format!("#[serde(rename = \"{}\")]\n ", c));
|
||||
}
|
||||
|
||||
c.split('-').for_each(|c| {
|
||||
|
|
|
|||
|
|
@ -3,17 +3,26 @@
|
|||
use std::{
|
||||
collections::{BTreeMap, HashSet},
|
||||
fs::File,
|
||||
io::BufReader,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use fancy_regex::Regex;
|
||||
use futures::{stream, StreamExt};
|
||||
use intl_pluralrules::{PluralCategory, PluralRuleType, PluralRules};
|
||||
use once_cell::sync::Lazy;
|
||||
use reqwest::Method;
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use unic_langid::LanguageIdentifier;
|
||||
|
||||
use crate::{
|
||||
client::{response, ClientType, ContextYT, RustyTube},
|
||||
client::{
|
||||
response::{self, video::CommentListItem},
|
||||
ClientType, ContextYT, RustyTube,
|
||||
},
|
||||
model::{Country, Language},
|
||||
timeago,
|
||||
timeago::{self, TimeAgo, TimeUnit, LANGUAGES},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
|
|
@ -61,13 +70,101 @@ async fn get_channel_datestrings(rp: &RustyTube, channel_id: &str) -> Vec<String
|
|||
.iter()
|
||||
.filter_map(|itm| match itm {
|
||||
response::VideoListItem::GridVideoRenderer { video } => {
|
||||
Some(video.published_time_text.to_owned())
|
||||
video.published_time_text.to_owned()
|
||||
}
|
||||
response::VideoListItem::ContinuationItemRenderer { .. } => None,
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
async fn get_comment_initial_ctoken(rp: &RustyTube, video_id: &str) -> (String, String) {
|
||||
let video_response = rp.get_video_response(video_id).await.unwrap();
|
||||
|
||||
let top = video_response
|
||||
.contents
|
||||
.two_column_watch_next_results
|
||||
.results
|
||||
.results
|
||||
.contents
|
||||
.iter()
|
||||
.find_map(|c| match c {
|
||||
response::video::VideoResultsItem::ItemSectionRenderer {
|
||||
contents,
|
||||
section_identifier,
|
||||
} => match section_identifier == "comment-item-section" {
|
||||
true => match &contents[0] {
|
||||
response::video::ItemSection::ContinuationItemRenderer {
|
||||
continuation_endpoint,
|
||||
} => Some(continuation_endpoint.continuation_command.token.to_owned()),
|
||||
_ => None,
|
||||
},
|
||||
false => None,
|
||||
},
|
||||
_ => None,
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let latest = video_response
|
||||
.engagement_panels
|
||||
.iter()
|
||||
.find_map(|p| {
|
||||
p.engagement_panel_section_list_renderer
|
||||
.header
|
||||
.engagement_panel_title_header_renderer
|
||||
.menu
|
||||
.sort_filter_sub_menu_renderer
|
||||
.sub_menu_items
|
||||
.get(1)
|
||||
.map(|i| i.service_endpoint.continuation_command.token.to_owned())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
(top, latest)
|
||||
}
|
||||
|
||||
async fn get_comment_datestrings(rp: &RustyTube, ctoken: &str) -> (Vec<String>, Option<String>) {
|
||||
let comments_response = rp.get_comments_response(ctoken).await.unwrap();
|
||||
|
||||
let mut next_ctoken: Option<String> = None;
|
||||
let datestrings = comments_response
|
||||
.on_response_received_endpoints
|
||||
/*
|
||||
.iter()
|
||||
.find(|e| {
|
||||
!e.append_continuation_items_action
|
||||
.continuation_items
|
||||
.is_empty()
|
||||
&& matches!(
|
||||
&e.append_continuation_items_action.continuation_items[0],
|
||||
CommentListItem::CommentsHeaderRenderer { count_text }
|
||||
)
|
||||
})
|
||||
.unwrap()
|
||||
*/
|
||||
.iter()
|
||||
.rev()
|
||||
.next()
|
||||
.unwrap()
|
||||
.append_continuation_items_action
|
||||
.continuation_items
|
||||
.iter()
|
||||
.filter_map(|itm| match itm {
|
||||
response::video::CommentListItem::CommentThreadRenderer { comment, .. } => {
|
||||
Some(comment.comment_renderer.published_time_text.to_owned())
|
||||
}
|
||||
response::video::CommentListItem::ContinuationItemRenderer {
|
||||
continuation_endpoint,
|
||||
} => {
|
||||
next_ctoken = Some(continuation_endpoint.continuation_command.token.to_owned());
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
(datestrings, next_ctoken)
|
||||
}
|
||||
|
||||
#[test_log::test(tokio::test)]
|
||||
async fn download_timeago_testfiles() {
|
||||
let json_path = Path::new("testfiles/date/timeago.json").to_path_buf();
|
||||
|
|
@ -128,3 +225,206 @@ async fn download_timeago_testfiles() {
|
|||
let file = File::create(json_path).unwrap();
|
||||
serde_json::to_writer_pretty(file, &strings_map).unwrap();
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
struct PluralRulesData {
|
||||
supplemental: PluralRulesInner,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
struct PluralRulesInner {
|
||||
plurals_type_cardinal: BTreeMap<String, Ruleset>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
struct Ruleset {
|
||||
#[serde(rename = "pluralRule-count-one")]
|
||||
one: Option<String>,
|
||||
#[serde(rename = "pluralRule-count-two")]
|
||||
two: Option<String>,
|
||||
#[serde(rename = "pluralRule-count-few")]
|
||||
few: Option<String>,
|
||||
#[serde(rename = "pluralRule-count-many")]
|
||||
many: Option<String>,
|
||||
#[serde(rename = "pluralRule-count-other")]
|
||||
other: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||
enum PluralCat {
|
||||
One,
|
||||
Two,
|
||||
Few,
|
||||
Many,
|
||||
Other,
|
||||
}
|
||||
|
||||
impl TryFrom<PluralCategory> for PluralCat {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: PluralCategory) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
PluralCategory::ZERO => Err(anyhow!("zero is not supported")),
|
||||
PluralCategory::ONE => Ok(Self::One),
|
||||
PluralCategory::TWO => Ok(Self::Two),
|
||||
PluralCategory::FEW => Ok(Self::Few),
|
||||
PluralCategory::MANY => Ok(Self::Many),
|
||||
PluralCategory::OTHER => Ok(Self::Other),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PLURAL_RULES: Lazy<BTreeMap<String, HashSet<PluralCat>>> = Lazy::new(|| {
|
||||
let json_path = Path::new("testfiles/date/cldr_pluralrules_cardinals.json");
|
||||
let json_file = File::open(json_path).unwrap();
|
||||
|
||||
serde_json::from_reader::<_, PluralRulesData>(BufReader::new(json_file))
|
||||
.unwrap()
|
||||
.supplemental
|
||||
.plurals_type_cardinal
|
||||
.iter()
|
||||
.map(|(lang, rules)| {
|
||||
let mut hs: HashSet<PluralCat> = HashSet::new();
|
||||
|
||||
if rules.one.is_some() {
|
||||
hs.insert(PluralCat::One);
|
||||
}
|
||||
if rules.two.is_some() {
|
||||
hs.insert(PluralCat::Two);
|
||||
}
|
||||
if rules.few.is_some() {
|
||||
hs.insert(PluralCat::Few);
|
||||
}
|
||||
if rules.many.is_some() {
|
||||
hs.insert(PluralCat::Many);
|
||||
}
|
||||
if rules.other.is_some() {
|
||||
hs.insert(PluralCat::Other);
|
||||
}
|
||||
|
||||
(lang.to_owned(), hs)
|
||||
})
|
||||
.collect::<BTreeMap<_, _>>()
|
||||
});
|
||||
|
||||
type TimeagoTable = BTreeMap<Language, BTreeMap<TimeUnit, TimeagoTableEntry>>;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct TimeagoTableEntry {
|
||||
cases: BTreeMap<String, TimeAgo>,
|
||||
missing_plurals: HashSet<PluralCat>,
|
||||
}
|
||||
|
||||
const TIME_UNITS: [TimeUnit; 7] = [
|
||||
TimeUnit::Second,
|
||||
TimeUnit::Minute,
|
||||
TimeUnit::Hour,
|
||||
TimeUnit::Day,
|
||||
TimeUnit::Week,
|
||||
TimeUnit::Month,
|
||||
TimeUnit::Year,
|
||||
];
|
||||
|
||||
fn new_timeago_table() -> TimeagoTable {
|
||||
LANGUAGES
|
||||
.iter()
|
||||
.filter_map(|lang| {
|
||||
// Check if language is redundant
|
||||
match lang {
|
||||
Language::EnGb
|
||||
| Language::EnIn
|
||||
| Language::FrCa
|
||||
| Language::EsUs
|
||||
| Language::Es419 => None,
|
||||
_ => {
|
||||
let cldr_lang_str = match lang {
|
||||
Language::SrLatn => "sr".to_owned(),
|
||||
Language::ZhCn | Language::ZhHk | Language::ZhTw => "zh".to_owned(),
|
||||
_ => lang.to_string(),
|
||||
};
|
||||
|
||||
let m = TIME_UNITS
|
||||
.iter()
|
||||
.map(|t| {
|
||||
let missing_plurals = if t == &TimeUnit::Week {
|
||||
// Week only has 3 valid values (1-3)
|
||||
let mut mp = HashSet::new();
|
||||
|
||||
let l_id = cldr_lang_str.parse::<LanguageIdentifier>().unwrap();
|
||||
let pr =
|
||||
PluralRules::create(l_id, PluralRuleType::CARDINAL).unwrap();
|
||||
|
||||
mp.insert(PluralCat::try_from(pr.select(1).unwrap()).unwrap());
|
||||
mp.insert(PluralCat::try_from(pr.select(2).unwrap()).unwrap());
|
||||
mp.insert(PluralCat::try_from(pr.select(3).unwrap()).unwrap());
|
||||
|
||||
mp
|
||||
} else {
|
||||
PLURAL_RULES.get(&cldr_lang_str).unwrap().clone()
|
||||
};
|
||||
|
||||
(
|
||||
t.to_owned(),
|
||||
TimeagoTableEntry {
|
||||
cases: BTreeMap::new(),
|
||||
missing_plurals,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Some((lang.to_owned(), m))
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn t_new_timeago_table() {
|
||||
let json_path = Path::new("testfiles/date/timeago_table.json").to_path_buf();
|
||||
if json_path.exists() {
|
||||
return;
|
||||
}
|
||||
|
||||
let file = File::create(json_path).unwrap();
|
||||
serde_json::to_writer_pretty(file, &new_timeago_table()).unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn t_tmp() {
|
||||
let rp = RustyTube::new();
|
||||
let (top, latest) = get_comment_initial_ctoken(&rp, "gQlMMD8auMs").await;
|
||||
// let (top, latest) = get_comment_initial_ctoken(&rp, "9bZkp7q19f0").await;
|
||||
let mut ctoken = latest;
|
||||
|
||||
let brace_pattern = Regex::new(r"\(.+\)").unwrap();
|
||||
|
||||
for _ in 0..100 {
|
||||
let (strings, new_ctoken) = get_comment_datestrings(&rp, &ctoken).await;
|
||||
|
||||
/*
|
||||
strings
|
||||
.iter()
|
||||
.map(|s| {
|
||||
// Remove zero-width space characters
|
||||
let s = s.replace('\u{200b}', "");
|
||||
|
||||
// Remove braces
|
||||
let s = brace_pattern.replace(&s, "");
|
||||
|
||||
let s = s.trim();
|
||||
s.to_owned()
|
||||
})
|
||||
.for_each(|s| println!("{}", s));
|
||||
*/
|
||||
println!("n: {}", strings.len());
|
||||
|
||||
if let Some(new_ctoken) = new_ctoken {
|
||||
ctoken = new_ctoken.to_owned();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
111
src/client/video.rs
Normal file
111
src/client/video.rs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
use anyhow::Result;
|
||||
use reqwest::Method;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::{response, ClientType, ContextYT, RustyTube};
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
struct QVideo {
|
||||
context: ContextYT,
|
||||
/// YouTube video ID
|
||||
video_id: String,
|
||||
/// Set to true to allow extraction of streams with sensitive content
|
||||
content_check_ok: bool,
|
||||
/// Probably refers to allowing sensitive content, too
|
||||
racy_check_ok: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
struct QVideoCont {
|
||||
context: ContextYT,
|
||||
continuation: String,
|
||||
}
|
||||
|
||||
impl RustyTube {
|
||||
pub async fn get_video_response(&self, video_id: &str) -> Result<response::Video> {
|
||||
let client = self.get_ytclient(ClientType::Desktop);
|
||||
let context = client.get_context(true).await;
|
||||
let request_body = QVideo {
|
||||
context,
|
||||
video_id: video_id.to_owned(),
|
||||
content_check_ok: true,
|
||||
racy_check_ok: true,
|
||||
};
|
||||
|
||||
let resp = client
|
||||
.request_builder(Method::POST, "next")
|
||||
.await
|
||||
.json(&request_body)
|
||||
.send()
|
||||
.await?
|
||||
.error_for_status()?;
|
||||
|
||||
Ok(resp.json::<response::Video>().await?)
|
||||
}
|
||||
|
||||
pub async fn get_comments_response(&self, ctoken: &str) -> Result<response::VideoComments> {
|
||||
let client = self.get_ytclient(ClientType::Desktop);
|
||||
let context = client.get_context(true).await;
|
||||
let request_body = QVideoCont {
|
||||
context,
|
||||
continuation: ctoken.to_owned(),
|
||||
};
|
||||
|
||||
let resp = client
|
||||
.request_builder(Method::POST, "next")
|
||||
.await
|
||||
.json(&request_body)
|
||||
.send()
|
||||
.await?
|
||||
.error_for_status()?;
|
||||
|
||||
Ok(resp.json::<response::VideoComments>().await?)
|
||||
}
|
||||
|
||||
pub async fn get_recommendations_response(
|
||||
&self,
|
||||
ctoken: &str,
|
||||
) -> Result<response::VideoRecommendations> {
|
||||
let client = self.get_ytclient(ClientType::Desktop);
|
||||
let context = client.get_context(true).await;
|
||||
let request_body = QVideoCont {
|
||||
context,
|
||||
continuation: ctoken.to_owned(),
|
||||
};
|
||||
|
||||
let resp = client
|
||||
.request_builder(Method::POST, "next")
|
||||
.await
|
||||
.json(&request_body)
|
||||
.send()
|
||||
.await?
|
||||
.error_for_status()?;
|
||||
|
||||
Ok(resp.json::<response::VideoRecommendations>().await?)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn t_get_video_response() {
|
||||
let rt = RustyTube::new();
|
||||
// rt.get_video("ZeerrnuLi5E").await.unwrap();
|
||||
dbg!(rt.get_video_response("iQfSvIgIs_M").await.unwrap());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn t_get_comments_response() {
|
||||
let rt = RustyTube::new();
|
||||
// rt.get_comments("Eg0SC2lRZlN2SWdJc19NGAYyJSIRIgtpUWZTdklnSXNfTTAAeAJCEGNvbW1lbnRzLXNlY3Rpb24%3D").await.unwrap();
|
||||
dbg!(rt.get_comments_response("Eg0SC2lRZlN2SWdJc19NGAYychpFEhRVZ2lnVGJVTEZ6Qk5FWGdDb0FFQyICCAAqGFVDWFgwUldPSUJqdDRvM3ppSHUtNmE1QTILaVFmU3ZJZ0lzX01AAUgKQiljb21tZW50LXJlcGxpZXMtaXRlbS1VZ2lnVGJVTEZ6Qk5FWGdDb0FFQw%3D%3D").await.unwrap());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn t_get_recommendations_response() {
|
||||
let rt = RustyTube::new();
|
||||
dbg!(rt.get_recommendations_response("CBQSExILaVFmU3ZJZ0lzX03AAQHIAQEYACqkBjJzNkw2d3pVQkFyUkJBb0Q4ajRBQ2c3Q1Bnc0lvWXlRejhLZnRZUGNBUW9EOGo0QUNnN0NQZ3NJeElEX2w0YjFtNnUtQVFvRDhqNEFDZzNDUGdvSXg5Ykx3WUNKenFwX0NnUHlQZ0FLRGNJLUNnaW83T2pqZzVPTHZEOEtBX0ktQUFvTndqNEtDTE9venZmQThybVhXd29EOGo0QUNnM0NQZ29JdzZETV9vSFk0cHRCQ2dQeVBnQUtEc0ktQ3dqbW9QbURpcHVPel80QkNnUHlQZ0FLRGNJLUNnalY4THpEazlfOTRCWUtBX0ktQUFvT3dqNExDTXVZNU9YZzE3ejV2d0VLQV9JLUFBb053ajRLQ1A3eHZiSGswTnVuYWdvRDhqNEFDZzdDUGdzSXFQYVU5ZGp2Ml96S0FRb0Q4ajRBQ2c3Q1Bnc0lfSW1acUtQOTlfQ09BUW9EOGo0QUNnM0NQZ29JeGRtNzlZS3prcUFqQ2dQeVBnQUtEY0ktQ2dpZ3FJMkg0UENRX2s0S0FfSS1BQW9Pd2o0TENQV0V5NV9ZeDhERl9nRUtBX0ktQUFvT3dqNExDTzJid3VuV3BPX3ppd0VLQV9JLUFBb2gwajRlQ2h4U1JFTk5WVU5ZV0RCU1YwOUpRbXAwTkc4emVtbElkUzAyWVRWQkNnUHlQZ0FLRGNJLUNnaXpqcXZwcDh5MWwwMEtBX0ktQUFvTndqNEtDTFhWbl83dHhfWDJOUW9EOGo0QUNnN0NQZ3NJNWR5ZWc1NjZyUGUwQVJJVUFBSUVCZ2dLREE0UUVoUVdHQm9jSGlBaUpDWWFCQWdBRUFFYUJBZ0NFQU1hQkFnRUVBVWFCQWdHRUFjYUJBZ0lFQWthQkFnS0VBc2FCQWdNRUEwYUJBZ09FQThhQkFnUUVCRWFCQWdTRUJNYUJBZ1VFQlVhQkFnV0VCY2FCQWdZRUJrYUJBZ2FFQnNhQkFnY0VCMGFCQWdlRUI4YUJBZ2dFQ0VhQkFnaUVDTWFCQWdrRUNVYUJBZ21FQ2NxRkFBQ0JBWUlDZ3dPRUJJVUZoZ2FIQjRnSWlRbWoPd2F0Y2gtbmV4dC1mZWVk").await.unwrap());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,2 @@
|
|||
pub mod range;
|
||||
pub mod text;
|
||||
// pub mod renderer;
|
||||
|
|
|
|||
|
|
@ -1,98 +0,0 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use serde::{de::Visitor, Deserialize, Deserializer};
|
||||
use serde_with::{serde_as, DeserializeAs, rust::maps_duplicate_key_is_error::deserialize};
|
||||
|
||||
/// ```json
|
||||
/// {
|
||||
/// itemSectionRenderer": {
|
||||
/// "contents": [
|
||||
/// {
|
||||
/// "playlistVideoListRenderer": {
|
||||
/// "contents": [
|
||||
/// {
|
||||
/// "playlistVideoRenderer": { ... }
|
||||
/// },
|
||||
/// {
|
||||
/// "playlistVideoRenderer": { ... }
|
||||
/// },
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ]
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Renderer names:
|
||||
///
|
||||
/// 1 content element:
|
||||
/// - tabRenderer > content
|
||||
///
|
||||
/// 1 content element (array):
|
||||
/// - twoColumnBrowseResultsRenderer > tabs
|
||||
/// - sectionListRenderer > contents
|
||||
/// - itemSectionRenderer > contents
|
||||
///
|
||||
/// n content elements:
|
||||
/// - playlistVideoListRenderer > contents
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged, bound = "for<'de2> T: Deserialize<'de2>")]
|
||||
pub enum Renderer<T> where for<'de2> T: Deserialize<'de2> {
|
||||
Single {
|
||||
#[serde_as(as = "crate::serializer::renderer::Renderer<T>")]
|
||||
content: T,
|
||||
},
|
||||
Multiple {
|
||||
#[serde(alias = "tabs")]
|
||||
#[serde_as(as = "crate::serializer::renderer::Renderer<T>")]
|
||||
contents: Vec<T>,
|
||||
},
|
||||
Content {
|
||||
#[serde(flatten)]
|
||||
inner: T,
|
||||
},
|
||||
}
|
||||
|
||||
// pub struct Renderer<T>(PhantomData<T>);
|
||||
|
||||
impl<'de, T> DeserializeAs<'de, T> for Renderer<T> {
|
||||
fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, T> DeserializeAs<'de, Vec<T>> for Renderer<T> {
|
||||
fn deserialize_as<D>(deserializer: D) -> Result<Vec<T>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
struct RendererVisitor<T, U>(PhantomData<T>, PhantomData<U>);
|
||||
|
||||
impl<'de, T, U> Visitor<'de> for RendererVisitor<T, U>
|
||||
where
|
||||
U: DeserializeAs<'de, T>,
|
||||
{
|
||||
type Value = T;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("a yt renderer")
|
||||
}
|
||||
|
||||
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>, {
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
@ -65,12 +65,16 @@ pub enum TextLink {
|
|||
page_type: PageType,
|
||||
browse_id: String,
|
||||
},
|
||||
Web {
|
||||
text: String,
|
||||
url: String,
|
||||
},
|
||||
None {
|
||||
text: String,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct TextLinks {}
|
||||
pub struct TextLinks;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct TextLinkInternal {
|
||||
|
|
@ -97,6 +101,9 @@ struct NavigationEndpoint {
|
|||
browse_endpoint: Option<BrowseEndpoint>,
|
||||
#[serde(default)]
|
||||
#[serde_as(deserialize_as = "DefaultOnError")]
|
||||
url_endpoint: Option<UrlEndpoint>,
|
||||
#[serde(default)]
|
||||
#[serde_as(deserialize_as = "DefaultOnError")]
|
||||
command_metadata: Option<CommandMetadata>,
|
||||
}
|
||||
|
||||
|
|
@ -113,6 +120,12 @@ struct BrowseEndpoint {
|
|||
browse_endpoint_context_supported_configs: Option<BrowseEndpointConfig>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct UrlEndpoint {
|
||||
url: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct BrowseEndpointConfig {
|
||||
|
|
@ -173,7 +186,13 @@ fn map_text_linkrun(lr: &TextLinkRun) -> Option<TextLink> {
|
|||
},
|
||||
browse_id: b.browse_id.to_owned(),
|
||||
},
|
||||
None => TextLink::None { text },
|
||||
None => match &nav.url_endpoint {
|
||||
Some(u) => TextLink::Web {
|
||||
text,
|
||||
url: u.url.to_owned(),
|
||||
},
|
||||
None => TextLink::None { text },
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
@ -398,6 +417,42 @@ mod tests {
|
|||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn t_link_web() {
|
||||
let test_json = r#"{
|
||||
"ln": {
|
||||
"runs": [
|
||||
{
|
||||
"text": "Creative Commons",
|
||||
"navigationEndpoint": {
|
||||
"clickTrackingParams": "CJsBEM2rARgBIhMImKz9y6Oc-QIVTJpVCh3VrAYM",
|
||||
"commandMetadata": {
|
||||
"webCommandMetadata": {
|
||||
"url": "https://www.youtube.com/t/creative_commons",
|
||||
"webPageType": "WEB_PAGE_TYPE_UNKNOWN",
|
||||
"rootVe": 83769
|
||||
}
|
||||
},
|
||||
"urlEndpoint": {
|
||||
"url": "https://www.youtube.com/t/creative_commons"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}"#;
|
||||
|
||||
let res = serde_json::from_str::<SLink>(&test_json).unwrap();
|
||||
insta::assert_debug_snapshot!(res, @r###"
|
||||
SLink {
|
||||
ln: Web {
|
||||
text: "Creative Commons",
|
||||
url: "https://www.youtube.com/t/creative_commons",
|
||||
},
|
||||
}
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn t_links_artists() {
|
||||
let test_json = r#"{
|
||||
|
|
|
|||
327
src/timeago.rs
327
src/timeago.rs
|
|
@ -2,6 +2,7 @@ use std::{borrow::Cow, str::FromStr, vec};
|
|||
|
||||
use anyhow::Result;
|
||||
use fancy_regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{model::Language, util};
|
||||
|
||||
|
|
@ -91,6 +92,24 @@ pub const LANGUAGES: [Language; 83] = [
|
|||
Language::Zu,
|
||||
];
|
||||
|
||||
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct TimeAgo {
|
||||
pub n: u32,
|
||||
pub unit: TimeUnit,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum TimeUnit {
|
||||
Second,
|
||||
Minute,
|
||||
Hour,
|
||||
Day,
|
||||
Week,
|
||||
Month,
|
||||
Year,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TimeagoPattern<'a> {
|
||||
word_separator: &'a str,
|
||||
|
|
@ -101,7 +120,7 @@ pub struct TimeagoPattern<'a> {
|
|||
weeks: Vec<&'a str>,
|
||||
months: Vec<&'a str>,
|
||||
years: Vec<&'a str>,
|
||||
special_cases: Vec<(&'a str, u64)>,
|
||||
special_cases: Vec<(&'a str, TimeAgo)>,
|
||||
}
|
||||
|
||||
impl From<Language> for TimeagoPattern<'_> {
|
||||
|
|
@ -140,11 +159,41 @@ impl From<Language> for TimeagoPattern<'_> {
|
|||
months: vec!["أشهر", "شهر", "شهرين", "شهرًا"],
|
||||
years: vec!["سنة", "سنتين", "سنوات"],
|
||||
special_cases: vec![
|
||||
("ساعتين", 2 * 3600),
|
||||
("يومين", 2 * 3600 * 24),
|
||||
("أسبوعين", 2 * 3600 * 24 * 7),
|
||||
("شهرين", 2 * 3600 * 24 * 30),
|
||||
("سنتين", 2 * 3600 * 24 * 365),
|
||||
(
|
||||
"ساعتين",
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
),
|
||||
(
|
||||
"يومين",
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Day,
|
||||
},
|
||||
),
|
||||
(
|
||||
"أسبوعين",
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Week,
|
||||
},
|
||||
),
|
||||
(
|
||||
"شهرين",
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Month,
|
||||
},
|
||||
),
|
||||
(
|
||||
"سنتين",
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Year,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
// INFO: newly added
|
||||
|
|
@ -472,11 +521,41 @@ impl From<Language> for TimeagoPattern<'_> {
|
|||
months: vec!["חודש", "חודשים"],
|
||||
years: vec!["שנה", "שנים"],
|
||||
special_cases: vec![
|
||||
("שעתיים", 2 * 3600),
|
||||
("יומיים", 2 * 3600 * 24),
|
||||
("שבועיים", 2 * 3600 * 24 * 7),
|
||||
("חודשיים", 2 * 3600 * 24 * 30),
|
||||
("שנתיים", 2 * 3600 * 24 * 365),
|
||||
(
|
||||
"שעתיים",
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
),
|
||||
(
|
||||
"יומיים",
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Day,
|
||||
},
|
||||
),
|
||||
(
|
||||
"שבועיים",
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Week,
|
||||
},
|
||||
),
|
||||
(
|
||||
"חודשיים",
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Month,
|
||||
},
|
||||
),
|
||||
(
|
||||
"שנתיים",
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Year,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
Language::Ja => TimeagoPattern {
|
||||
|
|
@ -513,7 +592,7 @@ impl From<Language> for TimeagoPattern<'_> {
|
|||
special_cases: vec![],
|
||||
},
|
||||
Language::Km => TimeagoPattern {
|
||||
word_separator: "",
|
||||
word_separator: " ",
|
||||
seconds: vec!["វិនាទីមុន"],
|
||||
minutes: vec!["នាទីមុន"],
|
||||
hours: vec!["ម៉ោងមុន"],
|
||||
|
|
@ -558,7 +637,7 @@ impl From<Language> for TimeagoPattern<'_> {
|
|||
special_cases: vec![],
|
||||
},
|
||||
Language::Lo => TimeagoPattern {
|
||||
word_separator: "",
|
||||
word_separator: " ",
|
||||
seconds: vec!["ວິນາທີກ່ອນ"],
|
||||
minutes: vec!["ນາທີກ່ອນ"],
|
||||
hours: vec!["ຊົ່ວໂມງກ່ອນ"],
|
||||
|
|
@ -604,7 +683,7 @@ impl From<Language> for TimeagoPattern<'_> {
|
|||
special_cases: vec![],
|
||||
},
|
||||
Language::Ml => TimeagoPattern {
|
||||
word_separator: "",
|
||||
word_separator: " ",
|
||||
seconds: vec!["സെക്കന്റ്", "സെക്കൻഡ്"],
|
||||
minutes: vec!["മിനിറ്റ്"],
|
||||
hours: vec!["മണിക്കൂർ"],
|
||||
|
|
@ -627,7 +706,7 @@ impl From<Language> for TimeagoPattern<'_> {
|
|||
special_cases: vec![],
|
||||
},
|
||||
Language::Mr => TimeagoPattern {
|
||||
word_separator: "",
|
||||
word_separator: " ",
|
||||
seconds: vec!["सेकंदांपूर्वी", "सेकंदापूर्वी"],
|
||||
minutes: vec!["मिनिटांपूर्वी", "मिनिटापूर्वी"],
|
||||
hours: vec!["तासांपूर्वी", "तासापूर्वी"],
|
||||
|
|
@ -1005,7 +1084,7 @@ impl TryFrom<&str> for TimeagoPattern<'_> {
|
|||
}
|
||||
|
||||
impl TimeagoPattern<'_> {
|
||||
pub fn parse(&self, textual_date: &str) -> Option<u64> {
|
||||
pub fn parse(&self, textual_date: &str) -> Option<TimeAgo> {
|
||||
self.special_cases
|
||||
.iter()
|
||||
.find_map(|case| {
|
||||
|
|
@ -1016,26 +1095,29 @@ impl TimeagoPattern<'_> {
|
|||
}
|
||||
})
|
||||
.or_else(|| match self.parse_time_unit(textual_date) {
|
||||
Some(tu) => Some(util::parse_numeric::<u64>(textual_date).unwrap_or(1) * tu),
|
||||
Some(tu) => Some(TimeAgo {
|
||||
n: util::parse_numeric(textual_date).unwrap_or(1),
|
||||
unit: tu,
|
||||
}),
|
||||
None => None,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_time_unit(&self, textual_date: &str) -> Option<u64> {
|
||||
fn parse_time_unit(&self, textual_date: &str) -> Option<TimeUnit> {
|
||||
match self.is_time_unit(textual_date, &self.seconds) {
|
||||
true => Some(1),
|
||||
true => Some(TimeUnit::Second),
|
||||
false => match self.is_time_unit(textual_date, &self.minutes) {
|
||||
true => Some(60),
|
||||
true => Some(TimeUnit::Minute),
|
||||
false => match self.is_time_unit(textual_date, &self.hours) {
|
||||
true => Some(3600),
|
||||
true => Some(TimeUnit::Hour),
|
||||
false => match self.is_time_unit(textual_date, &self.days) {
|
||||
true => Some(24 * 3600),
|
||||
true => Some(TimeUnit::Day),
|
||||
false => match self.is_time_unit(textual_date, &self.weeks) {
|
||||
true => Some(7 * 24 * 3600),
|
||||
true => Some(TimeUnit::Week),
|
||||
false => match self.is_time_unit(textual_date, &self.months) {
|
||||
true => Some(30 * 24 * 3600),
|
||||
true => Some(TimeUnit::Month),
|
||||
false => match self.is_time_unit(textual_date, &self.years) {
|
||||
true => Some(365 * 24 * 3600),
|
||||
true => Some(TimeUnit::Year),
|
||||
false => None,
|
||||
},
|
||||
},
|
||||
|
|
@ -1090,9 +1172,13 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[rstest]
|
||||
#[case(Language::De, "vor 1 Sekunde", Some(1))]
|
||||
#[case(Language::Ar, "قبل ساعة واحدة", Some(3600))]
|
||||
fn t_parse(#[case] lang: Language, #[case] textual_date: &str, #[case] expect: Option<u64>) {
|
||||
#[case(Language::De, "vor 1 Sekunde", Some(TimeAgo { n: 1, unit: TimeUnit::Second }))]
|
||||
#[case(Language::Ar, "قبل ساعة واحدة", Some(TimeAgo { n: 1, unit: TimeUnit::Hour }))]
|
||||
fn t_parse(
|
||||
#[case] lang: Language,
|
||||
#[case] textual_date: &str,
|
||||
#[case] expect: Option<TimeAgo>,
|
||||
) {
|
||||
let pat = TimeagoPattern::try_from(lang).unwrap();
|
||||
let secs_ago = pat.parse(textual_date);
|
||||
assert_eq!(secs_ago, expect);
|
||||
|
|
@ -1103,43 +1189,154 @@ mod tests {
|
|||
let json_path = Path::new("testfiles/date/timeago.json");
|
||||
|
||||
let expect = [
|
||||
10 * 60,
|
||||
20 * 60,
|
||||
1 * 3600,
|
||||
2 * 3600,
|
||||
7 * 3600,
|
||||
8 * 3600,
|
||||
9 * 3600,
|
||||
10 * 3600,
|
||||
11 * 3600,
|
||||
12 * 3600,
|
||||
13 * 3600,
|
||||
14 * 3600,
|
||||
15 * 3600,
|
||||
3 * 3600,
|
||||
4 * 3600,
|
||||
4 * 3600,
|
||||
5 * 3600,
|
||||
6 * 3600,
|
||||
6 * 3600,
|
||||
20 * 3600,
|
||||
2 * 3600 * 24,
|
||||
3 * 3600 * 24,
|
||||
5 * 3600 * 24,
|
||||
6 * 3600 * 24,
|
||||
8 * 3600 * 24,
|
||||
10 * 3600 * 24,
|
||||
12 * 3600 * 24,
|
||||
2 * 3600 * 24 * 7,
|
||||
3 * 3600 * 24 * 7,
|
||||
4 * 3600 * 24 * 7,
|
||||
1 * 3600 * 24 * 30,
|
||||
8 * 3600 * 24 * 30,
|
||||
11 * 3600 * 24 * 30,
|
||||
1 * 3600 * 24 * 365,
|
||||
2 * 3600 * 24 * 365,
|
||||
3 * 3600 * 24 * 365,
|
||||
4 * 3600 * 24 * 365,
|
||||
TimeAgo {
|
||||
n: 10,
|
||||
unit: TimeUnit::Minute,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 20,
|
||||
unit: TimeUnit::Minute,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 1,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 7,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 8,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 9,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 10,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 11,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 12,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 13,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 14,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 15,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 3,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 4,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 4,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 5,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 6,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 6,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 20,
|
||||
unit: TimeUnit::Hour,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Day,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 3,
|
||||
unit: TimeUnit::Day,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 5,
|
||||
unit: TimeUnit::Day,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 6,
|
||||
unit: TimeUnit::Day,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 8,
|
||||
unit: TimeUnit::Day,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 10,
|
||||
unit: TimeUnit::Day,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 12,
|
||||
unit: TimeUnit::Day,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Week,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 3,
|
||||
unit: TimeUnit::Week,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 4,
|
||||
unit: TimeUnit::Week,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 1,
|
||||
unit: TimeUnit::Month,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 8,
|
||||
unit: TimeUnit::Month,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 11,
|
||||
unit: TimeUnit::Month,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 1,
|
||||
unit: TimeUnit::Year,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 2,
|
||||
unit: TimeUnit::Year,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 3,
|
||||
unit: TimeUnit::Year,
|
||||
},
|
||||
TimeAgo {
|
||||
n: 4,
|
||||
unit: TimeUnit::Year,
|
||||
},
|
||||
];
|
||||
|
||||
let json_file = File::open(json_path).unwrap();
|
||||
|
|
|
|||
902
testfiles/date/cldr_pluralrules_cardinals.json
Normal file
902
testfiles/date/cldr_pluralrules_cardinals.json
Normal file
|
|
@ -0,0 +1,902 @@
|
|||
{
|
||||
"supplemental": {
|
||||
"version": {
|
||||
"_unicodeVersion": "13.0.0",
|
||||
"_cldrVersion": "37"
|
||||
},
|
||||
"plurals-type-cardinal": {
|
||||
"af": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ak": {
|
||||
"pluralRule-count-one": "n = 0..1 @integer 0, 1 @decimal 0.0, 1.0, 0.00, 1.00, 0.000, 1.000, 0.0000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"am": {
|
||||
"pluralRule-count-one": "i = 0 or n = 1 @integer 0, 1 @decimal 0.0~1.0, 0.00~0.04",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 1.1~2.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"an": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ar": {
|
||||
"pluralRule-count-zero": "n = 0 @integer 0 @decimal 0.0, 0.00, 0.000, 0.0000",
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-few": "n % 100 = 3..10 @integer 3~10, 103~110, 1003, … @decimal 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 103.0, 1003.0, …",
|
||||
"pluralRule-count-many": "n % 100 = 11..99 @integer 11~26, 111, 1011, … @decimal 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 111.0, 1011.0, …",
|
||||
"pluralRule-count-other": " @integer 100~102, 200~202, 300~302, 400~402, 500~502, 600, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.1, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ars": {
|
||||
"pluralRule-count-zero": "n = 0 @integer 0 @decimal 0.0, 0.00, 0.000, 0.0000",
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-few": "n % 100 = 3..10 @integer 3~10, 103~110, 1003, … @decimal 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 103.0, 1003.0, …",
|
||||
"pluralRule-count-many": "n % 100 = 11..99 @integer 11~26, 111, 1011, … @decimal 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 111.0, 1011.0, …",
|
||||
"pluralRule-count-other": " @integer 100~102, 200~202, 300~302, 400~402, 500~502, 600, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.1, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"as": {
|
||||
"pluralRule-count-one": "i = 0 or n = 1 @integer 0, 1 @decimal 0.0~1.0, 0.00~0.04",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 1.1~2.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"asa": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ast": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"az": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"be": {
|
||||
"pluralRule-count-one": "n % 10 = 1 and n % 100 != 11 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, … @decimal 1.0, 21.0, 31.0, 41.0, 51.0, 61.0, 71.0, 81.0, 101.0, 1001.0, …",
|
||||
"pluralRule-count-few": "n % 10 = 2..4 and n % 100 != 12..14 @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, … @decimal 2.0, 3.0, 4.0, 22.0, 23.0, 24.0, 32.0, 33.0, 102.0, 1002.0, …",
|
||||
"pluralRule-count-many": "n % 10 = 0 or n % 10 = 5..9 or n % 100 = 11..14 @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …",
|
||||
"pluralRule-count-other": " @decimal 0.1~0.9, 1.1~1.7, 10.1, 100.1, 1000.1, …"
|
||||
},
|
||||
"bem": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"bez": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"bg": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"bho": {
|
||||
"pluralRule-count-one": "n = 0..1 @integer 0, 1 @decimal 0.0, 1.0, 0.00, 1.00, 0.000, 1.000, 0.0000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"bm": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"bn": {
|
||||
"pluralRule-count-one": "i = 0 or n = 1 @integer 0, 1 @decimal 0.0~1.0, 0.00~0.04",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 1.1~2.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"bo": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"br": {
|
||||
"pluralRule-count-one": "n % 10 = 1 and n % 100 != 11,71,91 @integer 1, 21, 31, 41, 51, 61, 81, 101, 1001, … @decimal 1.0, 21.0, 31.0, 41.0, 51.0, 61.0, 81.0, 101.0, 1001.0, …",
|
||||
"pluralRule-count-two": "n % 10 = 2 and n % 100 != 12,72,92 @integer 2, 22, 32, 42, 52, 62, 82, 102, 1002, … @decimal 2.0, 22.0, 32.0, 42.0, 52.0, 62.0, 82.0, 102.0, 1002.0, …",
|
||||
"pluralRule-count-few": "n % 10 = 3..4,9 and n % 100 != 10..19,70..79,90..99 @integer 3, 4, 9, 23, 24, 29, 33, 34, 39, 43, 44, 49, 103, 1003, … @decimal 3.0, 4.0, 9.0, 23.0, 24.0, 29.0, 33.0, 34.0, 103.0, 1003.0, …",
|
||||
"pluralRule-count-many": "n != 0 and n % 1000000 = 0 @integer 1000000, … @decimal 1000000.0, 1000000.00, 1000000.000, …",
|
||||
"pluralRule-count-other": " @integer 0, 5~8, 10~20, 100, 1000, 10000, 100000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, …"
|
||||
},
|
||||
"brx": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"bs": {
|
||||
"pluralRule-count-one": "v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, … @decimal 0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 10.1, 100.1, 1000.1, …",
|
||||
"pluralRule-count-few": "v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14 @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, … @decimal 0.2~0.4, 1.2~1.4, 2.2~2.4, 3.2~3.4, 4.2~4.4, 5.2, 10.2, 100.2, 1000.2, …",
|
||||
"pluralRule-count-other": " @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 0.5~1.0, 1.5~2.0, 2.5~2.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ca": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ce": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ceb": {
|
||||
"pluralRule-count-one": "v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9 @integer 0~3, 5, 7, 8, 10~13, 15, 17, 18, 20, 21, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.3, 0.5, 0.7, 0.8, 1.0~1.3, 1.5, 1.7, 1.8, 2.0, 2.1, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …",
|
||||
"pluralRule-count-other": " @integer 4, 6, 9, 14, 16, 19, 24, 26, 104, 1004, … @decimal 0.4, 0.6, 0.9, 1.4, 1.6, 1.9, 2.4, 2.6, 10.4, 100.4, 1000.4, …"
|
||||
},
|
||||
"cgg": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"chr": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ckb": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"cs": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-few": "i = 2..4 and v = 0 @integer 2~4",
|
||||
"pluralRule-count-many": "v != 0 @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …",
|
||||
"pluralRule-count-other": " @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …"
|
||||
},
|
||||
"cy": {
|
||||
"pluralRule-count-zero": "n = 0 @integer 0 @decimal 0.0, 0.00, 0.000, 0.0000",
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-few": "n = 3 @integer 3 @decimal 3.0, 3.00, 3.000, 3.0000",
|
||||
"pluralRule-count-many": "n = 6 @integer 6 @decimal 6.0, 6.00, 6.000, 6.0000",
|
||||
"pluralRule-count-other": " @integer 4, 5, 7~20, 100, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"da": {
|
||||
"pluralRule-count-one": "n = 1 or t != 0 and i = 0,1 @integer 1 @decimal 0.1~1.6",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 2.0~3.4, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"de": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"dsb": {
|
||||
"pluralRule-count-one": "v = 0 and i % 100 = 1 or f % 100 = 1 @integer 1, 101, 201, 301, 401, 501, 601, 701, 1001, … @decimal 0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 10.1, 100.1, 1000.1, …",
|
||||
"pluralRule-count-two": "v = 0 and i % 100 = 2 or f % 100 = 2 @integer 2, 102, 202, 302, 402, 502, 602, 702, 1002, … @decimal 0.2, 1.2, 2.2, 3.2, 4.2, 5.2, 6.2, 7.2, 10.2, 100.2, 1000.2, …",
|
||||
"pluralRule-count-few": "v = 0 and i % 100 = 3..4 or f % 100 = 3..4 @integer 3, 4, 103, 104, 203, 204, 303, 304, 403, 404, 503, 504, 603, 604, 703, 704, 1003, … @decimal 0.3, 0.4, 1.3, 1.4, 2.3, 2.4, 3.3, 3.4, 4.3, 4.4, 5.3, 5.4, 6.3, 6.4, 7.3, 7.4, 10.3, 100.3, 1000.3, …",
|
||||
"pluralRule-count-other": " @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 0.5~1.0, 1.5~2.0, 2.5~2.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"dv": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"dz": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ee": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"el": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"en": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"eo": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"es": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"et": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"eu": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"fa": {
|
||||
"pluralRule-count-one": "i = 0 or n = 1 @integer 0, 1 @decimal 0.0~1.0, 0.00~0.04",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 1.1~2.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ff": {
|
||||
"pluralRule-count-one": "i = 0,1 @integer 0, 1 @decimal 0.0~1.5",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"fi": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"fil": {
|
||||
"pluralRule-count-one": "v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9 @integer 0~3, 5, 7, 8, 10~13, 15, 17, 18, 20, 21, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.3, 0.5, 0.7, 0.8, 1.0~1.3, 1.5, 1.7, 1.8, 2.0, 2.1, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …",
|
||||
"pluralRule-count-other": " @integer 4, 6, 9, 14, 16, 19, 24, 26, 104, 1004, … @decimal 0.4, 0.6, 0.9, 1.4, 1.6, 1.9, 2.4, 2.6, 10.4, 100.4, 1000.4, …"
|
||||
},
|
||||
"fo": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"fr": {
|
||||
"pluralRule-count-one": "i = 0,1 @integer 0, 1 @decimal 0.0~1.5",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"fur": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"fy": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ga": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-few": "n = 3..6 @integer 3~6 @decimal 3.0, 4.0, 5.0, 6.0, 3.00, 4.00, 5.00, 6.00, 3.000, 4.000, 5.000, 6.000, 3.0000, 4.0000, 5.0000, 6.0000",
|
||||
"pluralRule-count-many": "n = 7..10 @integer 7~10 @decimal 7.0, 8.0, 9.0, 10.0, 7.00, 8.00, 9.00, 10.00, 7.000, 8.000, 9.000, 10.000, 7.0000, 8.0000, 9.0000, 10.0000",
|
||||
"pluralRule-count-other": " @integer 0, 11~25, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.1, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"gd": {
|
||||
"pluralRule-count-one": "n = 1,11 @integer 1, 11 @decimal 1.0, 11.0, 1.00, 11.00, 1.000, 11.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2,12 @integer 2, 12 @decimal 2.0, 12.0, 2.00, 12.00, 2.000, 12.000, 2.0000",
|
||||
"pluralRule-count-few": "n = 3..10,13..19 @integer 3~10, 13~19 @decimal 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 3.00",
|
||||
"pluralRule-count-other": " @integer 0, 20~34, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.1, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"gl": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"gsw": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"gu": {
|
||||
"pluralRule-count-one": "i = 0 or n = 1 @integer 0, 1 @decimal 0.0~1.0, 0.00~0.04",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 1.1~2.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"guw": {
|
||||
"pluralRule-count-one": "n = 0..1 @integer 0, 1 @decimal 0.0, 1.0, 0.00, 1.00, 0.000, 1.000, 0.0000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"gv": {
|
||||
"pluralRule-count-one": "v = 0 and i % 10 = 1 @integer 1, 11, 21, 31, 41, 51, 61, 71, 101, 1001, …",
|
||||
"pluralRule-count-two": "v = 0 and i % 10 = 2 @integer 2, 12, 22, 32, 42, 52, 62, 72, 102, 1002, …",
|
||||
"pluralRule-count-few": "v = 0 and i % 100 = 0,20,40,60,80 @integer 0, 20, 40, 60, 80, 100, 120, 140, 1000, 10000, 100000, 1000000, …",
|
||||
"pluralRule-count-many": "v != 0 @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …",
|
||||
"pluralRule-count-other": " @integer 3~10, 13~19, 23, 103, 1003, …"
|
||||
},
|
||||
"ha": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"haw": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"he": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-two": "i = 2 and v = 0 @integer 2",
|
||||
"pluralRule-count-many": "v = 0 and n != 0..10 and n % 10 = 0 @integer 20, 30, 40, 50, 60, 70, 80, 90, 100, 1000, 10000, 100000, 1000000, …",
|
||||
"pluralRule-count-other": " @integer 0, 3~17, 101, 1001, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"hi": {
|
||||
"pluralRule-count-one": "i = 0 or n = 1 @integer 0, 1 @decimal 0.0~1.0, 0.00~0.04",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 1.1~2.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"hr": {
|
||||
"pluralRule-count-one": "v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, … @decimal 0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 10.1, 100.1, 1000.1, …",
|
||||
"pluralRule-count-few": "v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14 @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, … @decimal 0.2~0.4, 1.2~1.4, 2.2~2.4, 3.2~3.4, 4.2~4.4, 5.2, 10.2, 100.2, 1000.2, …",
|
||||
"pluralRule-count-other": " @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 0.5~1.0, 1.5~2.0, 2.5~2.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"hsb": {
|
||||
"pluralRule-count-one": "v = 0 and i % 100 = 1 or f % 100 = 1 @integer 1, 101, 201, 301, 401, 501, 601, 701, 1001, … @decimal 0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 10.1, 100.1, 1000.1, …",
|
||||
"pluralRule-count-two": "v = 0 and i % 100 = 2 or f % 100 = 2 @integer 2, 102, 202, 302, 402, 502, 602, 702, 1002, … @decimal 0.2, 1.2, 2.2, 3.2, 4.2, 5.2, 6.2, 7.2, 10.2, 100.2, 1000.2, …",
|
||||
"pluralRule-count-few": "v = 0 and i % 100 = 3..4 or f % 100 = 3..4 @integer 3, 4, 103, 104, 203, 204, 303, 304, 403, 404, 503, 504, 603, 604, 703, 704, 1003, … @decimal 0.3, 0.4, 1.3, 1.4, 2.3, 2.4, 3.3, 3.4, 4.3, 4.4, 5.3, 5.4, 6.3, 6.4, 7.3, 7.4, 10.3, 100.3, 1000.3, …",
|
||||
"pluralRule-count-other": " @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 0.5~1.0, 1.5~2.0, 2.5~2.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"hu": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"hy": {
|
||||
"pluralRule-count-one": "i = 0,1 @integer 0, 1 @decimal 0.0~1.5",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ia": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"id": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ig": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ii": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"in": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"io": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"is": {
|
||||
"pluralRule-count-one": "t = 0 and i % 10 = 1 and i % 100 != 11 or t != 0 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, … @decimal 0.1~1.6, 10.1, 100.1, 1000.1, …",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"it": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"iu": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-other": " @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"iw": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-two": "i = 2 and v = 0 @integer 2",
|
||||
"pluralRule-count-many": "v = 0 and n != 0..10 and n % 10 = 0 @integer 20, 30, 40, 50, 60, 70, 80, 90, 100, 1000, 10000, 100000, 1000000, …",
|
||||
"pluralRule-count-other": " @integer 0, 3~17, 101, 1001, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ja": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"jbo": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"jgo": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ji": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"jmc": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"jv": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"jw": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ka": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"kab": {
|
||||
"pluralRule-count-one": "i = 0,1 @integer 0, 1 @decimal 0.0~1.5",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"kaj": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"kcg": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"kde": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"kea": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"kk": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"kkj": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"kl": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"km": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"kn": {
|
||||
"pluralRule-count-one": "i = 0 or n = 1 @integer 0, 1 @decimal 0.0~1.0, 0.00~0.04",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 1.1~2.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ko": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ks": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ksb": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ksh": {
|
||||
"pluralRule-count-zero": "n = 0 @integer 0 @decimal 0.0, 0.00, 0.000, 0.0000",
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ku": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"kw": {
|
||||
"pluralRule-count-zero": "n = 0 @integer 0 @decimal 0.0, 0.00, 0.000, 0.0000",
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n % 100 = 2,22,42,62,82 or n % 1000 = 0 and n % 100000 = 1000..20000,40000,60000,80000 or n != 0 and n % 1000000 = 100000 @integer 2, 22, 42, 62, 82, 102, 122, 142, 1000, 10000, 100000, … @decimal 2.0, 22.0, 42.0, 62.0, 82.0, 102.0, 122.0, 142.0, 1000.0, 10000.0, 100000.0, …",
|
||||
"pluralRule-count-few": "n % 100 = 3,23,43,63,83 @integer 3, 23, 43, 63, 83, 103, 123, 143, 1003, … @decimal 3.0, 23.0, 43.0, 63.0, 83.0, 103.0, 123.0, 143.0, 1003.0, …",
|
||||
"pluralRule-count-many": "n != 1 and n % 100 = 1,21,41,61,81 @integer 21, 41, 61, 81, 101, 121, 141, 161, 1001, … @decimal 21.0, 41.0, 61.0, 81.0, 101.0, 121.0, 141.0, 161.0, 1001.0, …",
|
||||
"pluralRule-count-other": " @integer 4~19, 100, 1004, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.1, 1000000.0, …"
|
||||
},
|
||||
"ky": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"lag": {
|
||||
"pluralRule-count-zero": "n = 0 @integer 0 @decimal 0.0, 0.00, 0.000, 0.0000",
|
||||
"pluralRule-count-one": "i = 0,1 and n != 0 @integer 1 @decimal 0.1~1.6",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"lb": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"lg": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"lkt": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ln": {
|
||||
"pluralRule-count-one": "n = 0..1 @integer 0, 1 @decimal 0.0, 1.0, 0.00, 1.00, 0.000, 1.000, 0.0000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"lo": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"lt": {
|
||||
"pluralRule-count-one": "n % 10 = 1 and n % 100 != 11..19 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, … @decimal 1.0, 21.0, 31.0, 41.0, 51.0, 61.0, 71.0, 81.0, 101.0, 1001.0, …",
|
||||
"pluralRule-count-few": "n % 10 = 2..9 and n % 100 != 11..19 @integer 2~9, 22~29, 102, 1002, … @decimal 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 22.0, 102.0, 1002.0, …",
|
||||
"pluralRule-count-many": "f != 0 @decimal 0.1~0.9, 1.1~1.7, 10.1, 100.1, 1000.1, …",
|
||||
"pluralRule-count-other": " @integer 0, 10~20, 30, 40, 50, 60, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"lv": {
|
||||
"pluralRule-count-zero": "n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19 @integer 0, 10~20, 30, 40, 50, 60, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …",
|
||||
"pluralRule-count-one": "n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, … @decimal 0.1, 1.0, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 10.1, 100.1, 1000.1, …",
|
||||
"pluralRule-count-other": " @integer 2~9, 22~29, 102, 1002, … @decimal 0.2~0.9, 1.2~1.9, 10.2, 100.2, 1000.2, …"
|
||||
},
|
||||
"mas": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"mg": {
|
||||
"pluralRule-count-one": "n = 0..1 @integer 0, 1 @decimal 0.0, 1.0, 0.00, 1.00, 0.000, 1.000, 0.0000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"mgo": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"mk": {
|
||||
"pluralRule-count-one": "v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, … @decimal 0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 10.1, 100.1, 1000.1, …",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 0.2~1.0, 1.2~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ml": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"mn": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"mo": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-few": "v != 0 or n = 0 or n % 100 = 2..19 @integer 0, 2~16, 102, 1002, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …",
|
||||
"pluralRule-count-other": " @integer 20~35, 100, 1000, 10000, 100000, 1000000, …"
|
||||
},
|
||||
"mr": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ms": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"mt": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-few": "n = 0 or n % 100 = 2..10 @integer 0, 2~10, 102~107, 1002, … @decimal 0.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 10.0, 102.0, 1002.0, …",
|
||||
"pluralRule-count-many": "n % 100 = 11..19 @integer 11~19, 111~117, 1011, … @decimal 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 111.0, 1011.0, …",
|
||||
"pluralRule-count-other": " @integer 20~35, 100, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.1, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"my": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"nah": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"naq": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-other": " @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"nb": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"nd": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ne": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"nl": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"nn": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"nnh": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"no": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"nqo": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"nr": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"nso": {
|
||||
"pluralRule-count-one": "n = 0..1 @integer 0, 1 @decimal 0.0, 1.0, 0.00, 1.00, 0.000, 1.000, 0.0000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ny": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"nyn": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"om": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"or": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"os": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"osa": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"pa": {
|
||||
"pluralRule-count-one": "n = 0..1 @integer 0, 1 @decimal 0.0, 1.0, 0.00, 1.00, 0.000, 1.000, 0.0000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"pap": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"pcm": {
|
||||
"pluralRule-count-one": "i = 0 or n = 1 @integer 0, 1 @decimal 0.0~1.0, 0.00~0.04",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 1.1~2.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"pl": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-few": "v = 0 and i % 10 = 2..4 and i % 100 != 12..14 @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, …",
|
||||
"pluralRule-count-many": "v = 0 and i != 1 and i % 10 = 0..1 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 12..14 @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …",
|
||||
"pluralRule-count-other": " @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"prg": {
|
||||
"pluralRule-count-zero": "n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19 @integer 0, 10~20, 30, 40, 50, 60, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …",
|
||||
"pluralRule-count-one": "n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, … @decimal 0.1, 1.0, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 10.1, 100.1, 1000.1, …",
|
||||
"pluralRule-count-other": " @integer 2~9, 22~29, 102, 1002, … @decimal 0.2~0.9, 1.2~1.9, 10.2, 100.2, 1000.2, …"
|
||||
},
|
||||
"ps": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"pt": {
|
||||
"pluralRule-count-one": "i = 0..1 @integer 0, 1 @decimal 0.0~1.5",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"pt-PT": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"rm": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ro": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-few": "v != 0 or n = 0 or n % 100 = 2..19 @integer 0, 2~16, 102, 1002, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …",
|
||||
"pluralRule-count-other": " @integer 20~35, 100, 1000, 10000, 100000, 1000000, …"
|
||||
},
|
||||
"rof": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"root": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ru": {
|
||||
"pluralRule-count-one": "v = 0 and i % 10 = 1 and i % 100 != 11 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, …",
|
||||
"pluralRule-count-few": "v = 0 and i % 10 = 2..4 and i % 100 != 12..14 @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, …",
|
||||
"pluralRule-count-many": "v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14 @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …",
|
||||
"pluralRule-count-other": " @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"rwk": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sah": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"saq": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sat": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-other": " @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sc": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"scn": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sd": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sdh": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"se": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-other": " @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"seh": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ses": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sg": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sh": {
|
||||
"pluralRule-count-one": "v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, … @decimal 0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 10.1, 100.1, 1000.1, …",
|
||||
"pluralRule-count-few": "v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14 @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, … @decimal 0.2~0.4, 1.2~1.4, 2.2~2.4, 3.2~3.4, 4.2~4.4, 5.2, 10.2, 100.2, 1000.2, …",
|
||||
"pluralRule-count-other": " @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 0.5~1.0, 1.5~2.0, 2.5~2.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"shi": {
|
||||
"pluralRule-count-one": "i = 0 or n = 1 @integer 0, 1 @decimal 0.0~1.0, 0.00~0.04",
|
||||
"pluralRule-count-few": "n = 2..10 @integer 2~10 @decimal 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 2.00, 3.00, 4.00, 5.00, 6.00, 7.00, 8.00",
|
||||
"pluralRule-count-other": " @integer 11~26, 100, 1000, 10000, 100000, 1000000, … @decimal 1.1~1.9, 2.1~2.7, 10.1, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"si": {
|
||||
"pluralRule-count-one": "n = 0,1 or i = 0 and f = 1 @integer 0, 1 @decimal 0.0, 0.1, 1.0, 0.00, 0.01, 1.00, 0.000, 0.001, 1.000, 0.0000, 0.0001, 1.0000",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.2~0.9, 1.1~1.8, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sk": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-few": "i = 2..4 and v = 0 @integer 2~4",
|
||||
"pluralRule-count-many": "v != 0 @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …",
|
||||
"pluralRule-count-other": " @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …"
|
||||
},
|
||||
"sl": {
|
||||
"pluralRule-count-one": "v = 0 and i % 100 = 1 @integer 1, 101, 201, 301, 401, 501, 601, 701, 1001, …",
|
||||
"pluralRule-count-two": "v = 0 and i % 100 = 2 @integer 2, 102, 202, 302, 402, 502, 602, 702, 1002, …",
|
||||
"pluralRule-count-few": "v = 0 and i % 100 = 3..4 or v != 0 @integer 3, 4, 103, 104, 203, 204, 303, 304, 403, 404, 503, 504, 603, 604, 703, 704, 1003, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …",
|
||||
"pluralRule-count-other": " @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …"
|
||||
},
|
||||
"sma": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-other": " @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"smi": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-other": " @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"smj": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-other": " @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"smn": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-other": " @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sms": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-two": "n = 2 @integer 2 @decimal 2.0, 2.00, 2.000, 2.0000",
|
||||
"pluralRule-count-other": " @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sn": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"so": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sq": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sr": {
|
||||
"pluralRule-count-one": "v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, … @decimal 0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 10.1, 100.1, 1000.1, …",
|
||||
"pluralRule-count-few": "v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14 @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, … @decimal 0.2~0.4, 1.2~1.4, 2.2~2.4, 3.2~3.4, 4.2~4.4, 5.2, 10.2, 100.2, 1000.2, …",
|
||||
"pluralRule-count-other": " @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0, 0.5~1.0, 1.5~2.0, 2.5~2.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ss": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ssy": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"st": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"su": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sv": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"sw": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"syr": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ta": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"te": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"teo": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"th": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ti": {
|
||||
"pluralRule-count-one": "n = 0..1 @integer 0, 1 @decimal 0.0, 1.0, 0.00, 1.00, 0.000, 1.000, 0.0000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"tig": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"tk": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"tl": {
|
||||
"pluralRule-count-one": "v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9 @integer 0~3, 5, 7, 8, 10~13, 15, 17, 18, 20, 21, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.3, 0.5, 0.7, 0.8, 1.0~1.3, 1.5, 1.7, 1.8, 2.0, 2.1, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …",
|
||||
"pluralRule-count-other": " @integer 4, 6, 9, 14, 16, 19, 24, 26, 104, 1004, … @decimal 0.4, 0.6, 0.9, 1.4, 1.6, 1.9, 2.4, 2.6, 10.4, 100.4, 1000.4, …"
|
||||
},
|
||||
"tn": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"to": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"tr": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ts": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"tzm": {
|
||||
"pluralRule-count-one": "n = 0..1 or n = 11..99 @integer 0, 1, 11~24 @decimal 0.0, 1.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0",
|
||||
"pluralRule-count-other": " @integer 2~10, 100~106, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ug": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"uk": {
|
||||
"pluralRule-count-one": "v = 0 and i % 10 = 1 and i % 100 != 11 @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, …",
|
||||
"pluralRule-count-few": "v = 0 and i % 10 = 2..4 and i % 100 != 12..14 @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, …",
|
||||
"pluralRule-count-many": "v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14 @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …",
|
||||
"pluralRule-count-other": " @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ur": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"uz": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"ve": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"vi": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"vo": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"vun": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"wa": {
|
||||
"pluralRule-count-one": "n = 0..1 @integer 0, 1 @decimal 0.0, 1.0, 0.00, 1.00, 0.000, 1.000, 0.0000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 0.1~0.9, 1.1~1.7, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"wae": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"wo": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"xh": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"xog": {
|
||||
"pluralRule-count-one": "n = 1 @integer 1 @decimal 1.0, 1.00, 1.000, 1.0000",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~0.9, 1.1~1.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"yi": {
|
||||
"pluralRule-count-one": "i = 1 and v = 0 @integer 1",
|
||||
"pluralRule-count-other": " @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"yo": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"yue": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"zh": {
|
||||
"pluralRule-count-other": " @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
},
|
||||
"zu": {
|
||||
"pluralRule-count-one": "i = 0 or n = 1 @integer 0, 1 @decimal 0.0~1.0, 0.00~0.04",
|
||||
"pluralRule-count-other": " @integer 2~17, 100, 1000, 10000, 100000, 1000000, … @decimal 1.1~2.6, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in a new issue